mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-11-17 22:42:22 +08:00
Merge pull request #3126 from biosistemika/features/new-experiments-page
Features/new experiments page
This commit is contained in:
commit
8be9d3b14c
34 changed files with 1500 additions and 1281 deletions
|
|
@ -7,7 +7,7 @@
|
|||
// - refresh project users tab after manage user modal is closed
|
||||
// - refactor view handling using library, ex. backbone.js
|
||||
|
||||
/* global animateSpinner HelperModule dropdownSelector Sidebar Turbolinks */
|
||||
/* global animateSpinner HelperModule dropdownSelector Sidebar Turbolinks filterDropdown */
|
||||
|
||||
(function() {
|
||||
const PERMISSIONS = ['editable', 'archivable', 'restorable', 'moveable'];
|
||||
|
|
@ -507,9 +507,9 @@
|
|||
let projectsPageSelector = '.projects-index';
|
||||
|
||||
// list/cards switch
|
||||
$(projectsPageSelector).on('click', '.projects-view-mode', function() {
|
||||
$(projectsPageSelector).on('click', '.cards-switch', function() {
|
||||
let $btn = $(this);
|
||||
$('.projects-view-mode').removeClass('active');
|
||||
$('.cards-switch').removeClass('active');
|
||||
if ($btn.hasClass('view-switch-cards')) {
|
||||
$(cardsWrapper).removeClass('list');
|
||||
} else if ($btn.hasClass('view-switch-list')) {
|
||||
|
|
@ -539,63 +539,28 @@
|
|||
});
|
||||
}
|
||||
|
||||
function appliedFiltersMark() {
|
||||
let filtersEnabled = projectsViewSearch
|
||||
|| createdOnFromFilter
|
||||
|| createdOnToFilter
|
||||
|| (membersFilter && membersFilter.length !== 0)
|
||||
|| lookInsideFolders
|
||||
|| archivedOnFromFilter
|
||||
|| archivedOnToFilter;
|
||||
if (filtersEnabled) {
|
||||
$('.filter-container').addClass('filters-applied');
|
||||
} else {
|
||||
$('.filter-container').removeClass('filters-applied');
|
||||
}
|
||||
}
|
||||
|
||||
function initProjectsFilters() {
|
||||
function applyFilters() {
|
||||
let teamId = $('.projects-filters').data('team-id');
|
||||
projectsViewSearch = $('#textSearchFilterInput').closest('.select-block').find('input[type=text]').val();
|
||||
try {
|
||||
let storagePath = `project_filters_per_team/${teamId}/recent_search_keywords`;
|
||||
let recentSearchKeywords = JSON.parse(localStorage.getItem(storagePath));
|
||||
if (!Array.isArray(recentSearchKeywords)) recentSearchKeywords = [];
|
||||
if (recentSearchKeywords.indexOf(projectsViewSearch) !== -1) {
|
||||
recentSearchKeywords.splice(recentSearchKeywords.indexOf(projectsViewSearch), 1);
|
||||
}
|
||||
if (recentSearchKeywords.length > 4) {
|
||||
recentSearchKeywords = recentSearchKeywords.slice(0, 4);
|
||||
}
|
||||
recentSearchKeywords.unshift(projectsViewSearch);
|
||||
localStorage.setItem(storagePath, JSON.stringify(recentSearchKeywords));
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
$('#applyProjectFiltersButton').closest('.dropdown').removeClass('open');
|
||||
|
||||
createdOnFromFilter = $createdOnFromFilter.val();
|
||||
createdOnToFilter = $createdOnToFilter.val();
|
||||
membersFilter = dropdownSelector.getValues($('.members-filter'));
|
||||
lookInsideFolders = $foldersCB.prop('checked') ? 'true' : '';
|
||||
archivedOnFromFilter = $archivedOnFromFilter.val();
|
||||
archivedOnToFilter = $archivedOnToFilter.val();
|
||||
|
||||
appliedFiltersMark();
|
||||
refreshCurrentView();
|
||||
}
|
||||
|
||||
var $filterDropdown = filterDropdown.init();
|
||||
let $projectsFilter = $('.projects-index .projects-filters');
|
||||
let $membersFilter = $('.members-filter', $projectsFilter);
|
||||
let $foldersCB = $('#folder_search', $projectsFilter);
|
||||
let $createdOnFromFilter = $('#createdOnFromDate', $projectsFilter);
|
||||
let $createdOnToFilter = $('#createdOnToDate', $projectsFilter);
|
||||
let $archivedOnFromFilter = $('#archivedOnFromDate', $projectsFilter);
|
||||
let $archivedOnToFilter = $('#archivedOnToDate', $projectsFilter);
|
||||
let $createdOnFromFilter = $('.created-on-filter .from-date', $projectsFilter);
|
||||
let $createdOnToFilter = $('.created-on-filter .to-date', $projectsFilter);
|
||||
let $archivedOnFromFilter = $('.archived-on-filter .from-date', $projectsFilter);
|
||||
let $archivedOnToFilter = $('.archived-on-filter .to-date', $projectsFilter);
|
||||
let $textFilter = $('#textSearchFilterInput', $projectsFilter);
|
||||
|
||||
function appliedFiltersMark() {
|
||||
let filtersEnabled = projectsViewSearch
|
||||
|| createdOnFromFilter
|
||||
|| createdOnToFilter
|
||||
|| (membersFilter && membersFilter.length !== 0)
|
||||
|| lookInsideFolders
|
||||
|| archivedOnFromFilter
|
||||
|| archivedOnToFilter;
|
||||
filterDropdown.toggleFilterMark($filterDropdown, filtersEnabled);
|
||||
}
|
||||
|
||||
dropdownSelector.init($membersFilter, {
|
||||
optionClass: 'checkbox-icon users-dropdown-list',
|
||||
optionLabel: (data) => {
|
||||
|
|
@ -608,66 +573,26 @@
|
|||
tagClass: 'users-dropdown-list'
|
||||
});
|
||||
|
||||
$textFilter.click((e) => {
|
||||
e.stopPropagation();
|
||||
$('#textSearchFilterHistory').toggle();
|
||||
$textFilter.closest('.dropdown').toggleClass('open');
|
||||
}).on('input', () => {
|
||||
$('#textSearchFilterHistory').hide();
|
||||
$textFilter.closest('.dropdown').removeClass('open');
|
||||
});
|
||||
|
||||
$projectsFilter.on('click', '.projects-search-keyword', function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
$textFilter.val($(this).data('keyword'));
|
||||
$('#textSearchFilterHistory').hide();
|
||||
$textFilter.closest('.dropdown').removeClass('open');
|
||||
});
|
||||
|
||||
$projectsFilter.on('click', '#folderSearchInfoBtn', function(e) {
|
||||
e.stopPropagation();
|
||||
$('#folderSearchInfo').toggle();
|
||||
});
|
||||
|
||||
$('.project-filters-dropdown').on('show.bs.dropdown', function() {
|
||||
let teamId = $projectsFilter.data('team-id');
|
||||
$('#textSearchFilterHistory').find('li').remove();
|
||||
$filterDropdown.on('filter:apply', function() {
|
||||
createdOnFromFilter = $createdOnFromFilter.val();
|
||||
createdOnToFilter = $createdOnToFilter.val();
|
||||
membersFilter = dropdownSelector.getValues($('.members-filter'));
|
||||
lookInsideFolders = $foldersCB.prop('checked') ? 'true' : '';
|
||||
archivedOnFromFilter = $archivedOnFromFilter.val();
|
||||
archivedOnToFilter = $archivedOnToFilter.val();
|
||||
projectsViewSearch = $textFilter.val();
|
||||
|
||||
try {
|
||||
let storagePath = `project_filters_per_team/${teamId}/recent_search_keywords`;
|
||||
let recentSearchKeywords = JSON.parse(localStorage.getItem(storagePath));
|
||||
$.each(recentSearchKeywords, function(i, keyword) {
|
||||
$('#textSearchFilterHistory').append($(
|
||||
`<li class="dropdown-item">
|
||||
<a class="projects-search-keyword" href="#" data-keyword="${keyword}">
|
||||
<i class="fas fa-history"></i>
|
||||
<span class="keyword-text">${keyword}</span>
|
||||
</a>
|
||||
</li>`
|
||||
));
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}).on('hide.bs.dropdown', function() {
|
||||
$('#textSearchFilterHistory').hide();
|
||||
$textFilter.closest('.dropdown').removeClass('open');
|
||||
$('#folderSearchInfo').hide();
|
||||
applyFilters();
|
||||
});
|
||||
|
||||
$('#applyProjectFiltersButton').click((e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
applyFilters();
|
||||
appliedFiltersMark();
|
||||
refreshCurrentView();
|
||||
});
|
||||
|
||||
// Clear filters
|
||||
$('.clear-button', $projectsFilter).click((e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
$filterDropdown.on('filter:clear', function() {
|
||||
dropdownSelector.clearData($membersFilter);
|
||||
if ($createdOnFromFilter.data('DateTimePicker')) $createdOnFromFilter.data('DateTimePicker').clear();
|
||||
if ($createdOnToFilter.data('DateTimePicker')) $createdOnToFilter.data('DateTimePicker').clear();
|
||||
|
|
@ -678,15 +603,11 @@
|
|||
});
|
||||
|
||||
// Prevent filter window close
|
||||
$($projectsFilter).click((e) => {
|
||||
if (!$(e.target).is('input,a')) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
$('#textSearchFilterHistory').hide();
|
||||
$textFilter.closest('.dropdown').removeClass('open');
|
||||
dropdownSelector.closeDropdown($membersFilter);
|
||||
$('#folderSearchInfo').hide();
|
||||
}
|
||||
$filterDropdown.on('filter:clickBody', function() {
|
||||
$('#textSearchFilterHistory').hide();
|
||||
$textFilter.closest('.dropdown').removeClass('open');
|
||||
dropdownSelector.closeDropdown($membersFilter);
|
||||
$('#folderSearchInfo').hide();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,61 @@
|
|||
/* global filterDropdown */
|
||||
(function() {
|
||||
let experimentsCurrentSort;
|
||||
let experimentsViewSearch;
|
||||
let startedOnFromFilter;
|
||||
let startedOnToFilter;
|
||||
let modifiedOnFromFilter;
|
||||
let modifiedOnToFilter;
|
||||
let archivedOnFromFilter;
|
||||
let archivedOnToFilter;
|
||||
|
||||
function initExperimentsFilters() {
|
||||
var $filterDropdown = filterDropdown.init();
|
||||
|
||||
let $experimentsFilter = $('.experiments-filters');
|
||||
let $startedOnFromFilter = $('.started-on-filter .from-date', $experimentsFilter);
|
||||
let $startedOnToFilter = $('.started-on-filter .to-date', $experimentsFilter);
|
||||
let $modifiedOnFromFilter = $('.modified-on-filter .from-date', $experimentsFilter);
|
||||
let $modifiedOnToFilter = $('.modified-on-filter .to-date', $experimentsFilter);
|
||||
let $archivedOnFromFilter = $('.archived-on-filter .from-date', $experimentsFilter);
|
||||
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() {
|
||||
startedOnFromFilter = $startedOnFromFilter.val();
|
||||
startedOnToFilter = $startedOnToFilter.val();
|
||||
modifiedOnFromFilter = $modifiedOnFromFilter.val();
|
||||
modifiedOnToFilter = $modifiedOnToFilter.val();
|
||||
archivedOnFromFilter = $archivedOnFromFilter.val();
|
||||
archivedOnToFilter = $archivedOnToFilter.val();
|
||||
experimentsViewSearch = $textFilter.val();
|
||||
appliedFiltersMark();
|
||||
//refreshCurrentView();
|
||||
});
|
||||
|
||||
// Clear filters
|
||||
$filterDropdown.on('filter:clear', function() {
|
||||
if ($startedOnFromFilter.data('DateTimePicker')) $startedOnFromFilter.data('DateTimePicker').clear();
|
||||
if ($startedOnToFilter.data('DateTimePicker')) $startedOnToFilter.data('DateTimePicker').clear();
|
||||
if ($modifiedOnFromFilter.data('DateTimePicker')) $modifiedOnFromFilter.data('DateTimePicker').clear();
|
||||
if ($modifiedOnToFilter.data('DateTimePicker')) $modifiedOnToFilter.data('DateTimePicker').clear();
|
||||
if ($archivedOnFromFilter.data('DateTimePicker')) $archivedOnFromFilter.data('DateTimePicker').clear();
|
||||
if ($archivedOnToFilter.data('DateTimePicker')) $archivedOnToFilter.data('DateTimePicker').clear();
|
||||
$textFilter.val('');
|
||||
});
|
||||
}
|
||||
|
||||
function init() {
|
||||
$('.workflowimg-container').each(function() {
|
||||
let container = $(this);
|
||||
|
|
@ -18,6 +75,8 @@
|
|||
});
|
||||
}
|
||||
});
|
||||
|
||||
initExperimentsFilters();
|
||||
}
|
||||
|
||||
init();
|
||||
|
|
|
|||
116
app/assets/javascripts/sitewide/filter_dropdown.js
Normal file
116
app/assets/javascripts/sitewide/filter_dropdown.js
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
var filterDropdown = (function() {
|
||||
var $filterContainer = '';
|
||||
|
||||
function initClearButton() {
|
||||
$('.clear-button', $filterContainer).click(function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
$filterContainer.trigger('filter:clear');
|
||||
});
|
||||
}
|
||||
|
||||
function preventDropdownClose() {
|
||||
$('.dropdown-menu', $filterContainer).click((e) => {
|
||||
if (!$(e.target).is('input,a')) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
$('#textSearchFilterHistory').hide();
|
||||
$('#textSearchFilterInput', $filterContainer).closest('.dropdown').removeClass('open');
|
||||
$filterContainer.trigger('filter:clickBody');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function initSearchField() {
|
||||
var $textFilter = $('#textSearchFilterInput', $filterContainer);
|
||||
|
||||
$filterContainer.on('show.bs.dropdown', function() {
|
||||
let $filterDropdown = $filterContainer.find('.dropdown-menu');
|
||||
let teamId = $filterDropdown.data('team-id');
|
||||
$('#textSearchFilterHistory').find('li').remove();
|
||||
try {
|
||||
let storagePath = `${$filterDropdown.data('search-field-history-key')}/${teamId}/recent_search_keywords`;
|
||||
let recentSearchKeywords = JSON.parse(localStorage.getItem(storagePath));
|
||||
$.each(recentSearchKeywords, function(i, keyword) {
|
||||
$('#textSearchFilterHistory').append(
|
||||
$(`<li class="dropdown-item">
|
||||
<a class="projects-search-keyword" href="#" data-keyword="${keyword}">
|
||||
<i class="fas fa-history"></i>
|
||||
<span class="keyword-text">${keyword}</span>
|
||||
</a>
|
||||
</li>`)
|
||||
);
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}).on('hide.bs.dropdown', function() {
|
||||
$('#textSearchFilterHistory').hide();
|
||||
$('.apply-filters', $filterContainer).click();
|
||||
});
|
||||
|
||||
$textFilter.click(function(e) {
|
||||
e.stopPropagation();
|
||||
$('#textSearchFilterHistory').toggle();
|
||||
$(this).closest('.dropdown').toggleClass('open');
|
||||
}).on('input', () => {
|
||||
$('#textSearchFilterHistory').hide();
|
||||
$(this).closest('.dropdown').removeClass('open');
|
||||
});
|
||||
|
||||
$filterContainer.on('click', '.projects-search-keyword', function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
$textFilter.val($(this).data('keyword'));
|
||||
$('#textSearchFilterHistory').hide();
|
||||
$textFilter.closest('.dropdown').removeClass('open');
|
||||
});
|
||||
}
|
||||
|
||||
function initApplyButton() {
|
||||
$('.apply-filters', $filterContainer).click(function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
let $filterDropdown = $filterContainer.find('.dropdown-menu');
|
||||
let teamId = $filterDropdown.data('team-id');
|
||||
let projectsViewSearch = $('#textSearchFilterInput').val();
|
||||
try {
|
||||
let storagePath = `${$filterDropdown.data('search-field-history-key')}/${teamId}/recent_search_keywords`;
|
||||
let recentSearchKeywords = JSON.parse(localStorage.getItem(storagePath));
|
||||
if (!Array.isArray(recentSearchKeywords)) recentSearchKeywords = [];
|
||||
if (recentSearchKeywords.indexOf(projectsViewSearch) !== -1) {
|
||||
recentSearchKeywords.splice(recentSearchKeywords.indexOf(projectsViewSearch), 1);
|
||||
}
|
||||
if (recentSearchKeywords.length > 4) {
|
||||
recentSearchKeywords = recentSearchKeywords.slice(0, 4);
|
||||
}
|
||||
recentSearchKeywords.unshift(projectsViewSearch);
|
||||
localStorage.setItem(storagePath, JSON.stringify(recentSearchKeywords));
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
$filterContainer.trigger('filter:apply');
|
||||
$(this).closest('.dropdown').removeClass('open');
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
init: function() {
|
||||
$filterContainer = $('.filter-container');
|
||||
initClearButton();
|
||||
preventDropdownClose();
|
||||
initApplyButton();
|
||||
initSearchField();
|
||||
return $filterContainer;
|
||||
},
|
||||
toggleFilterMark: function(filterContainer, filtersEnabled) {
|
||||
if (filtersEnabled) {
|
||||
filterContainer.addClass('filters-applied');
|
||||
} else {
|
||||
filterContainer.removeClass('filters-applied');
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}());
|
||||
|
|
@ -3,207 +3,67 @@
|
|||
// scss-lint:disable SelectorFormat
|
||||
// scss-lint:disable IdSelector
|
||||
|
||||
// EXPERIMENT PANEL
|
||||
.experiment-panel {
|
||||
@include box-shadow(0 4px 8px 0 $color-dove-gray);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 400px;
|
||||
margin: 0 auto;
|
||||
margin-bottom: 35px;
|
||||
margin-top: 15px;
|
||||
max-width: 700px;
|
||||
|
||||
.panel-title {
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
// New experiments page
|
||||
|
||||
.panel-heading .clone-experiment,
|
||||
.panel-heading .dropdown {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:hover .clone-experiment,
|
||||
&:hover .dropdown {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.panel-date {
|
||||
color: $color-silver-chalice;
|
||||
|
||||
.fas {
|
||||
display: inline-block;
|
||||
width: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.panel-heading > .clone-experiment {
|
||||
color: $color-silver-chalice;
|
||||
padding-left: 4px;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
color: $color-silver-chalice;
|
||||
|
||||
button {
|
||||
padding-left: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.panel-body {
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
|
||||
a {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.experiment-description {
|
||||
margin-top: 10px;
|
||||
max-height: 86px;
|
||||
overflow-x: hidden;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.experiment-no-description {
|
||||
@include font-h3;
|
||||
color: $color-alto;
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
margin-top: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.no-workflowimg {
|
||||
color: $color-alto;
|
||||
display: block;
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
margin: 15px 0;
|
||||
max-height: 200px;
|
||||
padding-bottom: 70px;
|
||||
padding-top: 50px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.workflowimg-container {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
|
||||
img {
|
||||
max-height: 190px;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
// SHOW
|
||||
.center-btn {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
.big-plus {
|
||||
color: $color-gainsboro;
|
||||
display: block;
|
||||
font-size: 180px;
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
|
||||
&:hover {
|
||||
color: $color-alto;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
color: $color-alto;
|
||||
}
|
||||
}
|
||||
|
||||
#project-show-archive {
|
||||
.experiment-panel {
|
||||
background: $color-concrete;
|
||||
|
||||
.panel-heading {
|
||||
background: unset;
|
||||
}
|
||||
|
||||
.panel-date {
|
||||
color: $color-black;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#project-show,
|
||||
#project-show-archive {
|
||||
.projects-show {
|
||||
.content-header {
|
||||
.project-name {
|
||||
max-width: calc(100% - 2em);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
max-width: calc(100% - 7em);
|
||||
|
||||
.fas {
|
||||
margin-right: .5em;
|
||||
}
|
||||
}
|
||||
}
|
||||
.header-actions {
|
||||
margin-left: auto;
|
||||
|
||||
.experiment-sort-menu {
|
||||
display: inline-block;
|
||||
.project-show-container {
|
||||
margin: 1.5em 0;
|
||||
|
||||
#sortMenu {
|
||||
background: $color-white;
|
||||
.cards-wrapper {
|
||||
--card-min-width: 350px;
|
||||
--list-columns-number: 7;
|
||||
|
||||
&:focus,
|
||||
&:active {
|
||||
box-shadow: none;
|
||||
}
|
||||
.card {
|
||||
grid-row: span 6;
|
||||
|
||||
&:hover {
|
||||
background: $color-concrete;
|
||||
&.experiment-card {
|
||||
border-radius: 4px;
|
||||
box-shadow: $flyout-shadow;
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
@include font-button;
|
||||
min-width: 200px;
|
||||
padding: .5em 0;
|
||||
&.list {
|
||||
grid-template-columns: max-content repeat(calc(var(--list-columns-number) - 2), minmax(100px, auto)) max-content;
|
||||
|
||||
a {
|
||||
border-radius: unset;
|
||||
cursor: pointer;
|
||||
padding: .5em 1em;
|
||||
text-align: left;
|
||||
.card {
|
||||
&.experiment-card {
|
||||
.experiment-name-cell {
|
||||
grid-column: 2;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $color-concrete;
|
||||
}
|
||||
.start-date-cell {
|
||||
grid-column: 3;
|
||||
}
|
||||
|
||||
&.selected::after {
|
||||
@include font-awesome;
|
||||
content: $font-fas-check;
|
||||
margin-left: auto;
|
||||
position: absolute;
|
||||
right: 1em;
|
||||
.modified-date-cell {
|
||||
grid-column: 4;
|
||||
}
|
||||
|
||||
.completed-task-cell {
|
||||
grid-column: 5;
|
||||
}
|
||||
|
||||
.description-cell {
|
||||
grid-column: 6;
|
||||
}
|
||||
|
||||
.actions-cell {
|
||||
grid-column: 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.project-show-toolbar {
|
||||
margin-top: 1em;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,20 +8,6 @@
|
|||
$color-group-hover: $color-alabaster;
|
||||
$color-module-hover: $brand-primary;
|
||||
|
||||
// Breadcrumbs
|
||||
.projects-breadcrumbs {
|
||||
padding: .5em 1em;
|
||||
}
|
||||
|
||||
/* Secondary navigation */
|
||||
|
||||
.navbar-nav {
|
||||
.projects-view-mode-switch {
|
||||
margin: 8px 10px 12px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Canvas index page */
|
||||
|
||||
#canvas-container:not(.canvas-container-edit-mode) {
|
||||
|
|
@ -396,7 +382,6 @@ li.module-hover {
|
|||
|
||||
/* Edit module tags modal window */
|
||||
#manage-module-tags-modal {
|
||||
|
||||
.add-tag-form {
|
||||
display: inline-block;
|
||||
margin-left: 15px;
|
||||
|
|
@ -468,176 +453,17 @@ li.module-hover {
|
|||
}
|
||||
|
||||
|
||||
|
||||
/// icon override
|
||||
|
||||
.panel-project {
|
||||
|
||||
.nav-tabs[data-hook="project-footer-icons"] {
|
||||
|
||||
.btn-link {
|
||||
display: inline-block;
|
||||
min-width: 30px;
|
||||
}
|
||||
|
||||
.badge-indicator {
|
||||
background: transparent;
|
||||
color: $color-silver-chalice;
|
||||
font-size: 12px;
|
||||
margin-left: 0;
|
||||
padding: 0;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.tab-content[data-hook="project-dropdown-panel"] {
|
||||
|
||||
.over-due {
|
||||
|
||||
.title {
|
||||
border-top: 1px solid $color-concrete;
|
||||
font-size: 14px;
|
||||
line-height: 15px;
|
||||
padding: 10px 15px 0;
|
||||
}
|
||||
|
||||
.notification {
|
||||
padding-left: 35px;
|
||||
|
||||
.date-time {
|
||||
position: relative;
|
||||
|
||||
.fas {
|
||||
font-size: 14px;
|
||||
left: -20px;
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// New projects page
|
||||
|
||||
.projects-breadcrumbs {
|
||||
padding: .5em 1em;
|
||||
}
|
||||
|
||||
.projects-index {
|
||||
.cards-wrapper {
|
||||
align-items: center;
|
||||
display: grid;
|
||||
grid-auto-rows: 2em;
|
||||
grid-column-gap: 1em;
|
||||
grid-row-gap: 1em;
|
||||
grid-template-columns: repeat(auto-fill, minmax(291px, 1fr));
|
||||
width: 100%;
|
||||
|
||||
.table-header {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.projects-view-mode {
|
||||
&.active::after {
|
||||
@include font-awesome;
|
||||
content: "\f00c";
|
||||
position: absolute;
|
||||
right: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.archive-projects-form {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.restore-projects-form {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.header-actions {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
margin-left: auto;
|
||||
|
||||
.projects-sort-menu {
|
||||
display: inline-block;
|
||||
|
||||
#sortMenu {
|
||||
background: $color-white;
|
||||
|
||||
&:focus,
|
||||
&:active {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $color-concrete;
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
@include font-button;
|
||||
min-width: 150px;
|
||||
padding: .5em 0;
|
||||
|
||||
a {
|
||||
border-radius: unset;
|
||||
cursor: pointer;
|
||||
padding: .5em 1em;
|
||||
text-align: left;
|
||||
|
||||
&:hover {
|
||||
background: $color-concrete;
|
||||
}
|
||||
|
||||
&.selected::after {
|
||||
@include font-awesome;
|
||||
content: $font-fas-check;
|
||||
margin-left: auto;
|
||||
position: absolute;
|
||||
right: 1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.filter-container {
|
||||
position: initial;
|
||||
|
||||
.projects-filters {
|
||||
padding: 0;
|
||||
width: 230px;
|
||||
|
||||
.header {
|
||||
align-items: center;
|
||||
border-bottom: $border-default;
|
||||
display: flex;
|
||||
height: 2.75em;
|
||||
margin-bottom: 1em;
|
||||
padding: 0 .3em 0 1em;
|
||||
|
||||
.title {
|
||||
@include font-h2;
|
||||
flex-grow: 1;
|
||||
user-select: none;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.select-block {
|
||||
display: inline-block;
|
||||
padding: 0 1em 1em;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
label {
|
||||
@include font-small;
|
||||
font-weight: bold;
|
||||
margin-bottom: .3em;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
&.folders {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
|
|
@ -661,96 +487,7 @@ li.module-hover {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.text-search-filter {
|
||||
&.open {
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.recent-searches {
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
left: auto;
|
||||
margin-top: -1px;
|
||||
top: auto;
|
||||
width: calc(100% - 2em);
|
||||
|
||||
label {
|
||||
@include font-small;
|
||||
color: $color-silver-chalice;
|
||||
font-weight: bold;
|
||||
margin-bottom: .3em;
|
||||
padding: 0 1.5em;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.projects-search-keyword {
|
||||
@include font-button;
|
||||
padding: .5em 1.25em;
|
||||
|
||||
.keyword-text {
|
||||
margin-left: .25em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
align-items: center;
|
||||
border-top: $border-default;
|
||||
display: flex;
|
||||
height: 4.25em;
|
||||
justify-content: center;
|
||||
padding: 0 1em;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&.filters-applied .filter-button::after {
|
||||
@include red-dot;
|
||||
right: .35em;
|
||||
top: .3em;
|
||||
}
|
||||
|
||||
.connect-line {
|
||||
background: $input-border;
|
||||
height: 10px;
|
||||
margin: 5px auto;
|
||||
width: 2px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
|
||||
.projects-filters {
|
||||
width: 460px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
.btn:last-child {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.datetime-picker-container {
|
||||
display: inline-block;
|
||||
width: 46%;
|
||||
}
|
||||
|
||||
.connect-line {
|
||||
display: inline-block;
|
||||
margin: 0 11px;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.created-on-label {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.users-dropdown-list {
|
||||
.item-avatar {
|
||||
border-radius: 50%;
|
||||
|
|
@ -762,56 +499,25 @@ li.module-hover {
|
|||
}
|
||||
|
||||
.projects-toolbar {
|
||||
margin-bottom: 1em;
|
||||
|
||||
.form-group {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.archive-projects-form {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.restore-projects-form {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.projects-container {
|
||||
margin: 1.5em 20px;
|
||||
margin: 1.5em 0;
|
||||
|
||||
.cards-wrapper {
|
||||
align-items: center;
|
||||
display: grid;
|
||||
grid-auto-rows: 2em;
|
||||
grid-column-gap: 1em;
|
||||
grid-row-gap: 1em;
|
||||
grid-template-columns: repeat(auto-fill, minmax(291px, 1fr));
|
||||
width: 100%;
|
||||
|
||||
&.no-results {
|
||||
|
||||
.no-results-container {
|
||||
grid-row: 8;
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.no-results-img {
|
||||
display: block;
|
||||
margin: auto;
|
||||
max-height: 230px;
|
||||
}
|
||||
|
||||
.no-results-title {
|
||||
@include font-h1;
|
||||
margin-bottom: .25em;
|
||||
margin-top: 1.25em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.no-results-description {
|
||||
@include font-main;
|
||||
color: $color-silver-chalice;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.table-header {
|
||||
display: none;
|
||||
}
|
||||
--card-min-width: 291px;
|
||||
--list-columns-number: 6;
|
||||
|
||||
.projects-group {
|
||||
grid-column: 1/-1;
|
||||
|
|
@ -819,49 +525,6 @@ li.module-hover {
|
|||
}
|
||||
|
||||
.card {
|
||||
background-color: $color-white;
|
||||
color: $color-volcano;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
grid-row: span 4;
|
||||
height: 100%;
|
||||
padding: .5em 1em;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
.checkbox-cell {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
height: 2em;
|
||||
justify-content: center;
|
||||
left: .5em;
|
||||
position: absolute;
|
||||
top: .5em;
|
||||
width: 2em;
|
||||
}
|
||||
|
||||
.user-cell {
|
||||
.global-avatar-container {
|
||||
height: 28px;
|
||||
margin-right: .25em;
|
||||
width: 28px;
|
||||
}
|
||||
|
||||
.value {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.manage-users-link {
|
||||
color: $color-silver-chalice;
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.folder-card {
|
||||
text-align: center;
|
||||
|
||||
|
|
@ -971,48 +634,53 @@ li.module-hover {
|
|||
display: none;
|
||||
}
|
||||
|
||||
.more-users {
|
||||
align-items: center;
|
||||
background: $color-volcano;
|
||||
border-radius: 50%;
|
||||
color: $color-white;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
height: 2em;
|
||||
justify-content: center;
|
||||
margin-right: .25em;
|
||||
width: 2em;
|
||||
|
||||
&:hover {
|
||||
&.user-cell {
|
||||
a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.new-user {
|
||||
align-items: center;
|
||||
background: $color-concrete;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
height: 2em;
|
||||
justify-content: center;
|
||||
width: 2em;
|
||||
.value {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.global-avatar-container {
|
||||
height: 28px;
|
||||
margin-right: .25em;
|
||||
width: 28px;
|
||||
}
|
||||
|
||||
.more-users {
|
||||
align-items: center;
|
||||
background: $color-volcano;
|
||||
border-radius: 50%;
|
||||
color: $color-white;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
height: 2em;
|
||||
justify-content: center;
|
||||
margin-right: .25em;
|
||||
width: 2em;
|
||||
}
|
||||
|
||||
.new-user {
|
||||
align-items: center;
|
||||
background: $color-concrete;
|
||||
border-radius: 50%;
|
||||
color: $color-silver-chalice;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
height: 2em;
|
||||
justify-content: center;
|
||||
width: 2em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.list {
|
||||
grid-auto-flow: dense;
|
||||
grid-auto-rows: 2em 1px;
|
||||
grid-row-gap: .5em;
|
||||
grid-template-columns: max-content repeat(3, minmax(100px, auto)) max-content max-content;
|
||||
margin: 40px 0 0 6px;
|
||||
|
||||
.no-results-container {
|
||||
grid-row: 12;
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
grid-template-columns: max-content repeat(calc(var(--list-columns-number) - 3), minmax(100px, auto)) max-content max-content;
|
||||
|
||||
.projects-group {
|
||||
display: contents;
|
||||
|
|
@ -1031,17 +699,6 @@ li.module-hover {
|
|||
}
|
||||
|
||||
.card {
|
||||
display: contents;
|
||||
|
||||
// Border element
|
||||
&:after {
|
||||
background: $color-concrete;
|
||||
content: "";
|
||||
display: inline-block;
|
||||
grid-column: 1/-1;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
.data-row {
|
||||
font-weight: normal;
|
||||
line-height: 1.25em;
|
||||
|
|
@ -1061,10 +718,6 @@ li.module-hover {
|
|||
font-weight: normal;
|
||||
}
|
||||
|
||||
.checkbox-cell {
|
||||
position: initial;
|
||||
}
|
||||
|
||||
&.folder-card {
|
||||
text-align: left;
|
||||
|
||||
|
|
@ -1076,6 +729,7 @@ li.module-hover {
|
|||
|
||||
.name {
|
||||
grid-column: 5 span;
|
||||
line-height: 3em;
|
||||
|
||||
&:before {
|
||||
@include font-awesome;
|
||||
|
|
@ -1094,12 +748,9 @@ li.module-hover {
|
|||
display: none;
|
||||
}
|
||||
|
||||
.checkbox-cell {
|
||||
grid-column: 1;
|
||||
}
|
||||
|
||||
.project-name-cell {
|
||||
grid-column: 2;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
|
||||
a:hover {
|
||||
|
|
@ -1120,39 +771,13 @@ li.module-hover {
|
|||
}
|
||||
|
||||
.actions-cell {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
grid-column: 6;
|
||||
position: initial;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.table-header {
|
||||
display: contents;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
grid-column: 1/-1;
|
||||
}
|
||||
|
||||
.table-header-cell {
|
||||
align-items: center;
|
||||
border: 1px solid $color-white;
|
||||
display: flex;
|
||||
height: 3em;
|
||||
margin-left: -.5em;
|
||||
padding: 0 .5em;
|
||||
width: calc(100% + 1em);
|
||||
|
||||
&.select-all-checkboxes {
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
& > * {
|
||||
background-color: $color-concrete;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1200,36 +825,32 @@ li.module-hover {
|
|||
}
|
||||
|
||||
&.list {
|
||||
grid-auto-rows: 2em 1px;
|
||||
grid-template-columns: max-content repeat(5, minmax(100px, auto)) max-content;
|
||||
--list-columns-number: 7;
|
||||
grid-auto-rows: 3em 1px;
|
||||
grid-template-columns: max-content repeat(calc(var(--list-columns-number) - 2), minmax(100px, auto)) max-content;
|
||||
|
||||
.card::after {
|
||||
background: $color-white;
|
||||
}
|
||||
|
||||
.card.folder-card {
|
||||
.name {
|
||||
grid-column: 6 span;
|
||||
}
|
||||
}
|
||||
|
||||
.card.project-card {
|
||||
.checkbox-cell,
|
||||
.project-name-cell,
|
||||
.actions-cell,
|
||||
.data-row {
|
||||
align-items: center;
|
||||
background: $color-concrete;
|
||||
color: $color-volcano;
|
||||
display: flex;
|
||||
height: 3em;
|
||||
margin-left: -.5em;
|
||||
padding-left: .5em;
|
||||
width: calc(100% + 1em);
|
||||
.card {
|
||||
&::after {
|
||||
background: $color-white;
|
||||
}
|
||||
|
||||
.checkbox-cell {
|
||||
padding-left: 0;
|
||||
&.project-card {
|
||||
.table-cell {
|
||||
background: $color-concrete;
|
||||
color: $color-volcano;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.table-cell {
|
||||
background: $color-alto;
|
||||
}
|
||||
}
|
||||
|
||||
&.folder-card {
|
||||
.name {
|
||||
grid-column: 6 span;
|
||||
}
|
||||
}
|
||||
|
||||
.archived-date-cell {
|
||||
|
|
|
|||
|
|
@ -31,66 +31,70 @@
|
|||
|
||||
|
||||
#repository-toolbar {
|
||||
align-items: center;
|
||||
background-color: $color-white;
|
||||
border: 0;
|
||||
display: flex;
|
||||
left: var(--repository-sidebar-margin);
|
||||
padding: 0 2em;
|
||||
position: fixed;
|
||||
transition: .4s $timing-function-sharp;
|
||||
width: calc(100% - var(--repository-sidebar-margin));
|
||||
z-index: 100;
|
||||
|
||||
.toolbar-delimiter {
|
||||
border-bottom: $border-tertiary;
|
||||
bottom: 0;
|
||||
position: absolute;
|
||||
width: calc(100% - 4em);
|
||||
}
|
||||
|
||||
.repository-share-icon {
|
||||
flex-shrink: 0;
|
||||
margin-top: -2px;
|
||||
|
||||
.fas-custom {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
@include font-button;
|
||||
}
|
||||
|
||||
.repository-title-name {
|
||||
@include font-h2;
|
||||
.title-row {
|
||||
align-items: center;
|
||||
background-color: $color-white;
|
||||
border: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
line-height: 32px;
|
||||
margin-right: 20px;
|
||||
overflow: hidden;
|
||||
padding-left: 5px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
left: var(--repository-sidebar-margin);
|
||||
margin-left: 0em;
|
||||
padding: 0 2em;
|
||||
position: fixed;
|
||||
transition: .4s $timing-function-sharp;
|
||||
width: calc(100% - var(--repository-sidebar-margin));
|
||||
z-index: 100;
|
||||
|
||||
.name-container {
|
||||
align-items: center;
|
||||
display: inline-flex;
|
||||
height: 32px;
|
||||
margin: 0;
|
||||
.toolbar-delimiter {
|
||||
border-bottom: $border-tertiary;
|
||||
bottom: 0;
|
||||
margin-left: -2em;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.read-only-name {
|
||||
display: inline-block;
|
||||
line-height: 32px;
|
||||
max-width: calc(100% - 30px);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
.repository-share-icon {
|
||||
flex-shrink: 0;
|
||||
margin-top: -2px;
|
||||
|
||||
.fas-custom {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.inline-editing-container {
|
||||
width: 100%;
|
||||
.dropdown-menu {
|
||||
@include font-button;
|
||||
}
|
||||
|
||||
.repository-title-name {
|
||||
@include font-h2;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
line-height: 32px;
|
||||
margin-right: 20px;
|
||||
overflow: hidden;
|
||||
padding-left: 5px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
.name-container {
|
||||
align-items: center;
|
||||
display: inline-flex;
|
||||
height: 32px;
|
||||
margin: 0;
|
||||
|
||||
.read-only-name {
|
||||
display: inline-block;
|
||||
line-height: 32px;
|
||||
max-width: calc(100% - 30px);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.inline-editing-container {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
138
app/assets/stylesheets/shared/cards.scss
Normal file
138
app/assets/stylesheets/shared/cards.scss
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
.cards-wrapper {
|
||||
--card-min-width: 200px;
|
||||
--list-columns-number: 5;
|
||||
align-items: center;
|
||||
display: grid;
|
||||
grid-auto-rows: 2em;
|
||||
grid-column-gap: 1em;
|
||||
grid-row-gap: 1em;
|
||||
grid-template-columns: repeat(auto-fill, minmax(var(--card-min-width), 1fr));
|
||||
width: 100%;
|
||||
|
||||
.table-header {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.no-results {
|
||||
.no-results-container {
|
||||
grid-row: 8;
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.no-results-img {
|
||||
display: block;
|
||||
margin: auto;
|
||||
max-height: 230px;
|
||||
}
|
||||
|
||||
.no-results-title {
|
||||
@include font-h1;
|
||||
margin-bottom: .25em;
|
||||
margin-top: 1.25em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.no-results-description {
|
||||
@include font-main;
|
||||
color: $color-silver-chalice;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.card {
|
||||
background-color: $color-white;
|
||||
color: $color-volcano;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
grid-row: span 4;
|
||||
height: 100%;
|
||||
padding: .5em 1em;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
.checkbox-cell {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
height: 2em;
|
||||
justify-content: center;
|
||||
left: .5em;
|
||||
position: absolute;
|
||||
top: .5em;
|
||||
width: 2em;
|
||||
}
|
||||
}
|
||||
|
||||
&.list {
|
||||
grid-auto-flow: dense;
|
||||
grid-auto-rows: 3em 1px;
|
||||
grid-column-gap: 0;
|
||||
grid-row-gap: 0;
|
||||
grid-template-columns: repeat(var(--list-columns-number), minmax(100px, auto));
|
||||
margin: 40px 0 0 6px;
|
||||
|
||||
.no-results-container {
|
||||
grid-row: 12;
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.card {
|
||||
display: contents;
|
||||
|
||||
// Border element
|
||||
&:after {
|
||||
background: $color-concrete;
|
||||
content: "";
|
||||
display: inline-block;
|
||||
grid-column: 1/-1;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.table-cell {
|
||||
background: $color-concrete;
|
||||
}
|
||||
}
|
||||
|
||||
.table-cell {
|
||||
height: 100%;
|
||||
padding: 0 .5em;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.checkbox-cell {
|
||||
grid-column: 1;
|
||||
position: initial;
|
||||
}
|
||||
}
|
||||
|
||||
.table-header {
|
||||
display: contents;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
grid-column: 1/-1;
|
||||
}
|
||||
|
||||
.table-header-cell {
|
||||
align-items: center;
|
||||
border: 1px solid $color-white;
|
||||
display: flex;
|
||||
height: 3em;
|
||||
padding: 0 .5em;
|
||||
position: sticky;
|
||||
position: -webkit-sticky;
|
||||
top: 13em;
|
||||
width: calc(100% + 1em);
|
||||
z-index: 2;
|
||||
|
||||
&.select-all-checkboxes {
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
& > * {
|
||||
background-color: $color-concrete;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,6 @@
|
|||
// scss-lint:disable SelectorDepth SelectorFormat
|
||||
// scss-lint:disable NestingDepth QualifyingElement
|
||||
|
||||
.content-pane {
|
||||
background-color: $color-white;
|
||||
margin: 20px 0;
|
||||
|
|
@ -9,50 +12,133 @@
|
|||
}
|
||||
|
||||
.content-header {
|
||||
align-items: center;
|
||||
border-bottom: $border-tertiary;
|
||||
display: flex;
|
||||
height: 5em;
|
||||
|
||||
h1 {
|
||||
flex-grow: 1;
|
||||
margin: 0;
|
||||
&.sticky-header {
|
||||
background: $color-white;
|
||||
position: sticky;
|
||||
position: -webkit-sticky;
|
||||
top: var(--navbar-height);
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.view-switch {
|
||||
margin-left: auto;
|
||||
.title-row {
|
||||
align-items: center;
|
||||
background: $color-white;
|
||||
border-bottom: $border-tertiary;
|
||||
display: flex;
|
||||
height: 5em;
|
||||
margin-left: -2em;
|
||||
padding: 0 2em;
|
||||
width: calc(100% + 4em);
|
||||
|
||||
.caret {
|
||||
margin: 8px 0 8px 8px;
|
||||
h1 {
|
||||
flex-grow: 1;
|
||||
margin: 0;
|
||||
}
|
||||
&.open {
|
||||
|
||||
.header-actions {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.view-switch {
|
||||
margin-left: auto;
|
||||
|
||||
.caret {
|
||||
transform: rotateX(180deg)
|
||||
margin: 8px 0 8px 8px;
|
||||
}
|
||||
|
||||
&.open {
|
||||
.caret {
|
||||
transform: rotateX(180deg);
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
@include font-button;
|
||||
min-width: auto;
|
||||
|
||||
.divider-label {
|
||||
@include font-small;
|
||||
color: $color-silver-chalice;
|
||||
padding: .25em 1em;
|
||||
}
|
||||
|
||||
li {
|
||||
cursor: pointer;
|
||||
padding: 1em;
|
||||
white-space: nowrap;
|
||||
|
||||
.button-icon {
|
||||
margin-right: .5em;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $color-concrete;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cards-switch {
|
||||
&.active::after {
|
||||
@include font-awesome;
|
||||
content: "\f00c";
|
||||
position: absolute;
|
||||
right: 1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
@include font-button;
|
||||
min-width: auto;
|
||||
.sort-menu {
|
||||
display: inline-block;
|
||||
|
||||
li {
|
||||
cursor: pointer;
|
||||
padding: 1em;
|
||||
white-space: nowrap;
|
||||
#sortMenu {
|
||||
background: $color-white;
|
||||
|
||||
.button-icon {
|
||||
margin-right: .5em;
|
||||
&:focus,
|
||||
&:active {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $color-concrete;
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
@include font-button;
|
||||
min-width: 150px;
|
||||
padding: .5em 0;
|
||||
|
||||
a {
|
||||
border-radius: unset;
|
||||
cursor: pointer;
|
||||
padding: .5em 1em;
|
||||
text-align: left;
|
||||
|
||||
&:hover {
|
||||
background: $color-concrete;
|
||||
}
|
||||
|
||||
&.selected::after {
|
||||
@include font-awesome;
|
||||
content: $font-fas-check;
|
||||
margin-left: auto;
|
||||
position: absolute;
|
||||
right: 1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content-body {
|
||||
|
||||
.toolbar-row {
|
||||
background: $color-white;
|
||||
border-bottom: $border-tertiary;
|
||||
margin-left: -2em;
|
||||
padding: 1em 0;
|
||||
padding-left: 2em;
|
||||
width: calc(100% + 4em);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
124
app/assets/stylesheets/shared/filter_dropdown.scss
Normal file
124
app/assets/stylesheets/shared/filter_dropdown.scss
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
// scss-lint:disable NestingDepth SelectorDepth
|
||||
|
||||
.filter-container {
|
||||
position: initial;
|
||||
|
||||
.filter-dropdown {
|
||||
padding: 0;
|
||||
width: 230px;
|
||||
|
||||
.header {
|
||||
align-items: center;
|
||||
border-bottom: $border-default;
|
||||
display: flex;
|
||||
height: 2.75em;
|
||||
margin-bottom: 1em;
|
||||
padding: 0 .3em 0 1em;
|
||||
|
||||
.title {
|
||||
@include font-h2;
|
||||
flex-grow: 1;
|
||||
user-select: none;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.select-block {
|
||||
display: inline-block;
|
||||
padding: 0 1em 1em;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
label {
|
||||
@include font-small;
|
||||
font-weight: bold;
|
||||
margin-bottom: .3em;
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
|
||||
.text-search-filter {
|
||||
&.open {
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.recent-searches {
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
left: auto;
|
||||
margin-top: -1px;
|
||||
top: auto;
|
||||
width: calc(100% - 2em);
|
||||
|
||||
label {
|
||||
@include font-small;
|
||||
color: $color-silver-chalice;
|
||||
font-weight: bold;
|
||||
margin-bottom: .3em;
|
||||
padding: 0 1.5em;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.projects-search-keyword {
|
||||
@include font-button;
|
||||
padding: .5em 1.25em;
|
||||
|
||||
.keyword-text {
|
||||
margin-left: .25em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
align-items: center;
|
||||
border-top: $border-default;
|
||||
display: flex;
|
||||
height: 4.25em;
|
||||
justify-content: center;
|
||||
padding: 0 1em;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&.filters-applied .filter-button::after {
|
||||
@include red-dot;
|
||||
right: .35em;
|
||||
top: .3em;
|
||||
}
|
||||
|
||||
.connect-line {
|
||||
background: $input-border;
|
||||
height: 10px;
|
||||
margin: 5px auto;
|
||||
width: 2px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
|
||||
.filter-dropdown {
|
||||
width: 460px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
.btn:last-child {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.datetime-picker-container {
|
||||
display: inline-block;
|
||||
width: 46%;
|
||||
}
|
||||
|
||||
.connect-line {
|
||||
display: inline-block;
|
||||
margin: 0 11px;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -657,84 +657,6 @@ ul.double-line > li {
|
|||
}
|
||||
}
|
||||
|
||||
.panel-project {
|
||||
box-shadow: 0 3px 6px $color-alto;
|
||||
color: $color-silver-chalice;
|
||||
|
||||
&:not(.selected) .panel-heading .project-card-selector,
|
||||
&:not(.selected) .panel-heading .dropdown {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:not(.selected):hover .project-card-selector,
|
||||
&:not(.selected):hover .dropdown {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.nav .btn-link {
|
||||
padding: 10px 5px;
|
||||
}
|
||||
|
||||
&.selected {
|
||||
border-color: $brand-primary;
|
||||
box-shadow: 0 3px 10px $brand-primary;
|
||||
}
|
||||
|
||||
&.archived {
|
||||
&,
|
||||
.panel-heading,
|
||||
.panel-body,
|
||||
.panel-footer-scinote {
|
||||
background-color: $color-concrete;
|
||||
background-image: none;
|
||||
}
|
||||
}
|
||||
|
||||
.panel-heading {
|
||||
background-color: $color-white;
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
color: $color-silver-chalice;
|
||||
|
||||
.fas {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.panel-title {
|
||||
color: $brand-primary;
|
||||
|
||||
.fas {
|
||||
color: $color-silver-chalice;
|
||||
}
|
||||
}
|
||||
|
||||
.panel-body {
|
||||
padding: 10px 15px;
|
||||
|
||||
.row {
|
||||
padding: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.panel-footer {
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
|
||||
.nav {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.nav-tabs {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.tab-pane {
|
||||
color: $color-emperor;
|
||||
}
|
||||
}
|
||||
|
||||
.panel-archive {
|
||||
.panel-heading {
|
||||
background-color: darken($color-gainsboro, 5%);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ class ProjectsController < ApplicationController
|
|||
|
||||
before_action :switch_team_with_param, only: :index
|
||||
before_action :load_vars, only: %i(show edit update notifications experiment_archive sidebar)
|
||||
before_action :load_current_folder, only: %i(index cards new)
|
||||
before_action :load_current_folder, only: %i(index cards new show experiment_archive)
|
||||
before_action :check_view_permissions, only: %i(show notifications experiment_archive sidebar)
|
||||
before_action :check_create_permissions, only: %i(new create)
|
||||
before_action :check_manage_permissions, only: :edit
|
||||
|
|
@ -301,6 +301,8 @@ class ProjectsController < ApplicationController
|
|||
def load_current_folder
|
||||
if current_team && params[:project_folder_id].present?
|
||||
@current_folder = current_team.project_folders.find_by(id: params[:project_folder_id])
|
||||
elsif @project&.project_folder
|
||||
@current_folder = @project&.project_folder
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ class Project < ApplicationRecord
|
|||
include ArchivableModel
|
||||
include SearchableModel
|
||||
include SearchableByNameModel
|
||||
include ViewableModel
|
||||
|
||||
enum visibility: { hidden: 0, visible: 1 }
|
||||
|
||||
|
|
@ -150,6 +151,22 @@ class Project < ApplicationRecord
|
|||
.distinct
|
||||
end
|
||||
|
||||
def default_view_state
|
||||
{
|
||||
experiments: {
|
||||
active: { sort: 'new' },
|
||||
archived: { sort: 'new' }
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def validate_view_state(view_state)
|
||||
if %w(new old atoz ztoa).exclude?(view_state.state.dig('experiments', 'active', 'sort')) ||
|
||||
%w(new old atoz ztoa archived_new archived_old).exclude?(view_state.state.dig('experiments', 'archived', 'sort'))
|
||||
view_state.errors.add(:state, :wrong_state)
|
||||
end
|
||||
end
|
||||
|
||||
def last_activities(count = Constants::ACTIVITY_AND_NOTIF_SEARCH_LIMIT)
|
||||
activities.order(created_at: :desc).first(count)
|
||||
end
|
||||
|
|
|
|||
76
app/services/experiments_overview_service.rb
Normal file
76
app/services/experiments_overview_service.rb
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ExperimentsOverviewService
|
||||
def initialize(project, user, params)
|
||||
@project = project
|
||||
@user = user
|
||||
@params = params
|
||||
@view_state = @project.current_view_state(@user)
|
||||
@view_mode = if @project.archived?
|
||||
'archived'
|
||||
else
|
||||
params[:view_mode] || 'active'
|
||||
end
|
||||
|
||||
# Update sort if changed
|
||||
@sort = @view_state.state.dig('experiments', @view_mode, 'sort') || 'atoz'
|
||||
if @params[:sort] && @sort != @params[:sort] &&
|
||||
%w(new old atoz ztoa archived_old archived_new).include?(@params[:sort])
|
||||
@view_state.state['experiments'].merge!(Hash[@view_mode, { 'sort': @params[:sort] }.stringify_keys])
|
||||
@view_state.save!
|
||||
@sort = @view_state.state.dig('experiments', @view_mode, 'sort')
|
||||
end
|
||||
end
|
||||
|
||||
def experiments
|
||||
sort_records(
|
||||
filter_records(
|
||||
fetch_records
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def fetch_records
|
||||
@project.experiments.joins(:project)
|
||||
end
|
||||
|
||||
def filter_records(records)
|
||||
records = records.archived if @view_mode == 'archived' && @project.active?
|
||||
records = records.active if @view_mode == 'active'
|
||||
if @params[:search].present?
|
||||
records = records.where_attributes_like(%w(experiments.name experiments.description), @params[:search])
|
||||
end
|
||||
if @params[:created_on_from].present?
|
||||
records = records.where('experiments.created_at > ?', @params[:created_on_from])
|
||||
end
|
||||
records = records.where('experiments.created_at < ?', @params[:created_on_to]) if @params[:created_on_to].present?
|
||||
if @params[:archived_on_from].present?
|
||||
records = records.where('COALESCE(experiments.archived_on, projects.archived_on) > ?', @params[:archived_on_from])
|
||||
end
|
||||
if @params[:archived_on_to].present?
|
||||
records = records.where('COALESCE(experiments.archived_on, projects.archived_on) < ?', @params[:archived_on_to])
|
||||
end
|
||||
records
|
||||
end
|
||||
|
||||
def sort_records(records)
|
||||
case @sort
|
||||
when 'new'
|
||||
records.order(created_at: :desc)
|
||||
when 'old'
|
||||
records.order(:created_at)
|
||||
when 'atoz'
|
||||
records.order(:name)
|
||||
when 'ztoa'
|
||||
records.order(name: :desc)
|
||||
when 'archived_old'
|
||||
records.order(Arel.sql('COALESCE(experiments.archived_on, projects.archived_on) ASC'))
|
||||
when 'archived_new'
|
||||
records.order(Arel.sql('COALESCE(experiments.archived_on, projects.archived_on) DESC'))
|
||||
else
|
||||
records
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -110,8 +110,9 @@ class ProjectsOverviewService
|
|||
records = records.archived if @view_mode == 'archived'
|
||||
records = records.active if @view_mode == 'active'
|
||||
records = records.where_attributes_like('projects.name', @params[:search]) if @params[:search].present?
|
||||
records = records.where_attributes_like('projects.name', @params[:search]) if @params[:search].present?
|
||||
records = records.joins(:user_projects).where('user_projects.user_id IN (?)', @params[:members]) if @params[:members]&.any?
|
||||
if @params[:members].present?
|
||||
records = records.joins(:user_projects).where('user_projects.user_id IN (?)', @params[:members])
|
||||
end
|
||||
records = records.where('projects.created_at > ?', @params[:created_on_from]) if @params[:created_on_from].present?
|
||||
records = records.where('projects.created_at < ?', @params[:created_on_to]) if @params[:created_on_to].present?
|
||||
records = records.where('projects.archived_on < ?', @params[:archived_on_to]) if @params[:archived_on_to].present?
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@
|
|||
<%= render partial: 'shared/sidebar/experiments.html.erb', locals: { project: @project, archived: true } %>
|
||||
<% end %>
|
||||
|
||||
<% content_for :breadcrumbs do %>
|
||||
<%= render partial: 'projects/index/breadcrumbs', locals: { target_folder: @project.project_folder } %>
|
||||
<% end %>
|
||||
|
||||
<div class="content-pane flexible" id="project-show-archive">
|
||||
<%= render partial: 'projects/show/header' %>
|
||||
|
|
|
|||
|
|
@ -21,9 +21,7 @@
|
|||
<%= render partial: 'projects/index/modals/export_projects' %>
|
||||
|
||||
<div class="projects-container">
|
||||
<div id="toolbarWrapper">
|
||||
</div>
|
||||
<div class="cards-wrapper" id="cardsWrapper" data-projects-cards-url="<%= current_folder ? project_folder_cards_url(current_folder) : cards_projects_url %>">
|
||||
<div class="cards-wrapper" id="cardsWrapper" data-projects-cards-url="<%= @current_folder ? project_folder_cards_url(@current_folder) : cards_projects_url %>">
|
||||
<div class="table-header">
|
||||
<div class="table-header-cell select-all-checkboxes">
|
||||
<div class="sci-checkbox-container">
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<% target_folder ||= current_folder %>
|
||||
<div class="projects-breadcrumbs">
|
||||
<%= link_to(t('projects.index.breadcrumbs_root'),
|
||||
projects_path,
|
||||
projects_path(view_mode: projects_view_mode),
|
||||
class: 'project-folder-link',
|
||||
data: { projects_cards_url: cards_projects_url,
|
||||
sidebar_url: sidebar_team_path(current_team) }) %>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
data-moveable="<%= can_update_team?(current_team) %>"
|
||||
data-archivable="false"
|
||||
data-restorable="false">
|
||||
<div class="checkbox-cell">
|
||||
<div class="checkbox-cell table-cell">
|
||||
<div class="sci-checkbox-container">
|
||||
<input value="1" type="checkbox" class="sci-checkbox folder-card-selector">
|
||||
<span class="sci-checkbox-label"></span>
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
<div class="icon-folder">
|
||||
<i class="fas fa-folder"></i>
|
||||
</div>
|
||||
<div class="name" title="<%= folder.name %>">
|
||||
<div class="name table-cell" title="<%= folder.name %>">
|
||||
<%= folder.name %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -1,168 +1,75 @@
|
|||
<div class="content-header">
|
||||
<h1 data-view-mode="active"><%= t('projects.index.head_title') %></h1>
|
||||
<h1 data-view-mode="archived"><i class="fas fa-archive"></i> <%= t('projects.index.head_title_archived') %></h1>
|
||||
<div class="content-header sticky-header">
|
||||
<div class="title-row">
|
||||
<h1 data-view-mode="active"><%= t('projects.index.head_title') %></h1>
|
||||
<h1 data-view-mode="archived"><i class="fas fa-archive"></i> <%= t('projects.index.head_title_archived') %></h1>
|
||||
|
||||
<div class="sci-btn-group header-actions">
|
||||
<%= render layout: 'shared/view_switch', locals: { disabled: false } do %>
|
||||
<li class="view-switch-cards projects-view-mode active">
|
||||
<i class="fas fa-th-large button-icon"></i> <%= t('projects.index.header.cards') %>
|
||||
</li>
|
||||
<div class="sci-btn-group header-actions">
|
||||
<%= render layout: 'shared/view_switch', locals: { disabled: false } do %>
|
||||
<li class="view-switch-cards cards-switch active">
|
||||
<i class="fas fa-th-large button-icon"></i> <%= t('projects.index.header.cards') %>
|
||||
</li>
|
||||
|
||||
<li class="view-switch-list projects-view-mode ">
|
||||
<i class="fas fa-list button-icon"></i> <%= t('projects.index.header.table') %>
|
||||
</li>
|
||||
<li class="view-switch-list cards-switch ">
|
||||
<i class="fas fa-list button-icon"></i> <%= t('projects.index.header.table') %>
|
||||
</li>
|
||||
<div role="separator" class="divider"></div>
|
||||
<li class="view-switch-active archive-switch" data-view-mode="archived" data-url="<%= projects_path %>">
|
||||
<i class="fas fa-rocket button-icon"></i> <%= t('projects.index.header.active_projects') %>
|
||||
</li>
|
||||
|
||||
<li class="view-switch-active archive-switch" data-view-mode="archived" data-url="<%= projects_path %>">
|
||||
<i class="fas fa-rocket button-icon"></i> <%= t('projects.index.header.active_projects') %>
|
||||
</li>
|
||||
|
||||
<li class="view-switch-archived archive-switch" data-view-mode="active" data-url="<%= projects_path(view_mode: 'archived') %>">
|
||||
<i class="fas fa-archive button-icon"></i> <%= t('projects.index.header.archived_projects') %>
|
||||
</li>
|
||||
<% end %>
|
||||
<div class="filter-container dropdown project-filters-dropdown">
|
||||
<button class="btn btn-light icon-btn filter-button" data-toggle="dropdown"><i class="fas fa-filter"></i></button>
|
||||
<div class="dropdown-menu dropdown-menu-right projects-filters" role="menu" data-team-id="<%= current_team.id %>">
|
||||
<div class="header">
|
||||
<div class="title"><%= t("projects.index.filters_modal.title") %></div>
|
||||
<div class="btn btn-light clear-button">
|
||||
<i class="fas fa-times-circle"></i><%= t("projects.index.filters_modal.clear_btn") %></div>
|
||||
</div>
|
||||
<div class="select-block dropdown-selector-container">
|
||||
<label><%= t('projects.index.filters_modal.text.label') %></label>
|
||||
<div class="input-field dropdown text-search-filter">
|
||||
<input id="textSearchFilterInput"
|
||||
class="dropdown-toggle search-field"
|
||||
type="text"
|
||||
name="search"
|
||||
autocomplete="off"
|
||||
data-toggle="dropdown"
|
||||
placeholder="<%= t('projects.index.filters_modal.text.placeholder') %>">
|
||||
</div>
|
||||
<div id="textSearchFilterHistory" class="dropdown-menu recent-searches" aria-labelledby="textSearchFilterInput">
|
||||
<label><%= t("projects.index.filters_modal.recent_searches_label") %></label>
|
||||
<li class="view-switch-archived archive-switch" data-view-mode="active" data-url="<%= projects_path(view_mode: 'archived') %>">
|
||||
<i class="fas fa-archive button-icon"></i> <%= t('projects.index.header.archived_projects') %>
|
||||
</li>
|
||||
<% end %>
|
||||
<%= render layout: 'shared/filter_dropdown', locals: {
|
||||
container_class: 'projects-filters',
|
||||
dropdown_title: t("filters_modal.title"),
|
||||
search_field_history_key: 'project_filters_per_team'
|
||||
} do %>
|
||||
<%= render partial: 'shared/filter_dropdown/text_search', locals: {container_class: ''} %>
|
||||
<%= render partial: 'shared/filter_dropdown/datetime_search', locals: {container_class: 'created-on-filter', label: t("filters_modal.created_on.label"), view_mode: nil } %>
|
||||
<div class="select-block">
|
||||
<label><%= t("projects.index.filters_modal.members.label") %></label>
|
||||
<select class="members-filter"
|
||||
data-ajax-url="<%= users_filter_projects_path %>"
|
||||
data-placeholder="<%= t('projects.index.filters_modal.members.placeholder') %>">
|
||||
</select>
|
||||
</div>
|
||||
<%= render partial: 'shared/filter_dropdown/datetime_search', locals: {container_class: 'archived-on-filter', label: t("filters_modal.archived_on.label"), view_mode: 'archived' } %>
|
||||
<div class="select-block folders">
|
||||
<span class="sci-checkbox-container">
|
||||
<%= check_box_tag :folder_search, 'accepted', false, {class: "sci-checkbox"} %>
|
||||
<span class="sci-checkbox-label"></span>
|
||||
</span>
|
||||
<span class="folder-search-label"><%= t("projects.index.filters_modal.folders.label") %></span>
|
||||
<div class="dropdown folder-search-info">
|
||||
<a class="fas fa-info-circle" id="folderSearchInfoBtn" data-toggle="dropdown"></a>
|
||||
<div id="folderSearchInfo" class="dropdown-menu folder-search-popover" aria-labelledby="folderSearchInfo">
|
||||
<%= t("projects.index.filters_modal.folders.popover_html") %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="select-block">
|
||||
<div class="created-on-label">
|
||||
<label><%= t("projects.index.filters_modal.created_on.label") %></label>
|
||||
</div>
|
||||
<div class="datetime-picker-container" id="from-date">
|
||||
<span class="fas fa-calendar-alt"></span>
|
||||
<input id="createdOnFromDate"
|
||||
type="datetime"
|
||||
data-toggle='date-time-picker'
|
||||
class="form-control calendar-input"
|
||||
readonly
|
||||
placeholder="<%= t('projects.index.filters_modal.created_on.from_placeholder') %>"
|
||||
data-date-format="<%= datetime_picker_format_full %>"
|
||||
data-date-locale="<%= I18n.locale %>"
|
||||
data-date-use-current="false"
|
||||
value=""/>
|
||||
</div>
|
||||
|
||||
<div class="connect-line"></div>
|
||||
|
||||
<div class="datetime-picker-container" id="to-date">
|
||||
<span class="fas fa-calendar-alt"></span>
|
||||
<input id="createdOnToDate"
|
||||
type="datetime"
|
||||
data-toggle='date-time-picker'
|
||||
class="form-control calendar-input"
|
||||
readonly
|
||||
placeholder="<%= t('projects.index.filters_modal.created_on.to_placeholder') %>"
|
||||
data-date-format="<%= datetime_picker_format_full %>"
|
||||
data-date-locale="<%= I18n.locale %>"
|
||||
data-date-use-current="false"
|
||||
data-date-orientation="left"
|
||||
value=""/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="select-block">
|
||||
<label><%= t("projects.index.filters_modal.members.label") %></label>
|
||||
<select class="members-filter"
|
||||
data-ajax-url="<%= users_filter_projects_path %>"
|
||||
data-placeholder="<%= t('projects.index.filters_modal.members.placeholder') %>">
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="select-block" data-view-mode="archived">
|
||||
<div class="created-on-label">
|
||||
<label><%= t("projects.index.filters_modal.archived_on.label") %></label>
|
||||
</div>
|
||||
<div class="datetime-picker-container" id="from-date">
|
||||
<span class="fas fa-calendar-alt"></span>
|
||||
<input id="archivedOnFromDate"
|
||||
type="datetime"
|
||||
data-toggle='date-time-picker'
|
||||
class="form-control calendar-input"
|
||||
readonly
|
||||
placeholder="<%= t('projects.index.filters_modal.created_on.from_placeholder') %>"
|
||||
data-date-format="<%= datetime_picker_format_full %>"
|
||||
data-date-locale="<%= I18n.locale %>"
|
||||
data-date-use-current="false"
|
||||
value=""/>
|
||||
</div>
|
||||
|
||||
<div class="connect-line"></div>
|
||||
|
||||
<div class="datetime-picker-container" id="to-date">
|
||||
<span class="fas fa-calendar-alt"></span>
|
||||
<input id="archivedOnToDate"
|
||||
type="datetime"
|
||||
data-toggle='date-time-picker'
|
||||
class="form-control calendar-input"
|
||||
readonly
|
||||
placeholder="<%= t('projects.index.filters_modal.created_on.to_placeholder') %>"
|
||||
data-date-format="<%= datetime_picker_format_full %>"
|
||||
data-date-locale="<%= I18n.locale %>"
|
||||
data-date-use-current="false"
|
||||
data-date-orientation="left"
|
||||
value=""/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="select-block folders">
|
||||
<span class="sci-checkbox-container">
|
||||
<%= check_box_tag :folder_search, 'accepted', false, {class: "sci-checkbox"} %>
|
||||
<span class="sci-checkbox-label"></span>
|
||||
</span>
|
||||
<span class="folder-search-label"><%= t("projects.index.filters_modal.folders.label") %></span>
|
||||
<div class="dropdown folder-search-info">
|
||||
<a class="fas fa-info-circle" id="folderSearchInfoBtn" data-toggle="dropdown"></a>
|
||||
<div id="folderSearchInfo" class="dropdown-menu folder-search-popover" aria-labelledby="folderSearchInfo">
|
||||
<%= t("projects.index.filters_modal.folders.popover_html") %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<div id="applyProjectFiltersButton" class="btn btn-primary"><%= t("projects.index.filters_modal.show_btn.one") %></div>
|
||||
</div>
|
||||
<div class="dropdown sort-menu">
|
||||
<button class="btn btn-light dropdown-toggle" type="button" id="sortMenu" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||
<span><i class="fas fa-sort-amount-down"></i></span>
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul id="sortMenuDropdown" class="dropdown-menu sort-projects-menu dropdown-menu-right" aria-labelledby="sortMenu">
|
||||
<% %w(new old atoz ztoa archived_new archived_old).each_with_index do |sort, i| %>
|
||||
<% if i.even? && i.positive? %>
|
||||
<li class="divider" <%= i > 3 ? 'data-view-mode=archived' : '' %>></li>
|
||||
<% end %>
|
||||
<li <%= %w(archived_new archived_old).include?(sort) ? 'data-view-mode=archived' : '' %>>
|
||||
<a class="<%= 'selected' if @current_sort == sort %>"
|
||||
data-sort="<%= sort %>" >
|
||||
<%= t("general.sort.#{sort}_html") %>
|
||||
</a>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dropdown projects-sort-menu">
|
||||
<button class="btn btn-light dropdown-toggle" type="button" id="sortMenu" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||
<span><i class="fas fa-sort-amount-down"></i></span>
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul id="sortMenuDropdown" class="dropdown-menu sort-projects-menu dropdown-menu-right" aria-labelledby="sortMenu">
|
||||
<% %w(new old atoz ztoa archived_new archived_old).each_with_index do |sort, i| %>
|
||||
<% if i.even? && i.positive? %>
|
||||
<li class="divider" <%= i > 3 ? 'data-view-mode=archived' : '' %>></li>
|
||||
<% end %>
|
||||
<li <%= %w(archived_new archived_old).include?(sort) ? 'data-view-mode=archived' : '' %>>
|
||||
<a class="<%= 'selected' if @current_sort == sort %>"
|
||||
data-sort="<%= sort %>" >
|
||||
<%= t("general.sort.#{sort}_html") %>
|
||||
</a>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="toolbarWrapper" class="toolbar-row">
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -5,13 +5,13 @@
|
|||
data-moveable="<%= can_update_team?(current_team) %>"
|
||||
data-archivable="<%= project.active? && can_archive_project?(project) %>"
|
||||
data-restorable="<%= project.archived? && can_restore_project?(project) %>">
|
||||
<div class="checkbox-cell">
|
||||
<div class="checkbox-cell table-cell">
|
||||
<div class="sci-checkbox-container">
|
||||
<input value="1" type="checkbox" class="sci-checkbox project-card-selector">
|
||||
<span class="sci-checkbox-label"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="project-name-cell">
|
||||
<div class="project-name-cell table-cell">
|
||||
<% if project.archived? %>
|
||||
<%= link_to experiment_archive_project_url(project) do %>
|
||||
<h3 class="name" title="<%= project.name %>">
|
||||
|
|
@ -26,17 +26,17 @@
|
|||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="actions actions-cell">
|
||||
<div class="actions actions-cell table-cell">
|
||||
<%= render partial: 'projects/index/project_actions_dropdown.html.erb', locals: { project: project, view: 'cards' } %>
|
||||
</div>
|
||||
|
||||
<div class="data-row start-date-cell">
|
||||
<div class="data-row start-date-cell table-cell">
|
||||
<span class="card-label"><%= t('projects.index.card.start_date') %></span>
|
||||
<span class="value card-value"> <%= l(project.created_at, format: :full_date) %></span>
|
||||
<span class="value cell-value"> <%= l(project.created_at, format: :full_with_comma) %></span>
|
||||
</div>
|
||||
|
||||
<div class="data-row visibility-cell">
|
||||
<div class="data-row visibility-cell table-cell">
|
||||
<span class="card-label"><%= t('projects.index.card.visibility') %></span>
|
||||
<span class="value">
|
||||
<% if project.hidden? %>
|
||||
|
|
@ -47,7 +47,7 @@
|
|||
</span>
|
||||
</div>
|
||||
|
||||
<div class="data-row user-cell">
|
||||
<div class="data-row user-cell table-cell">
|
||||
<span class="card-label"><%= t('projects.index.card.users') %></span>
|
||||
<div class="value">
|
||||
|
||||
|
|
@ -78,7 +78,7 @@
|
|||
</div>
|
||||
|
||||
<% if project.archived? %>
|
||||
<div class="data-row archived-date-cell">
|
||||
<div class="data-row archived-date-cell table-cell">
|
||||
<span class="card-label"><%= t('projects.index.card.archived_date') %></span>
|
||||
<span class="value card-value"> <%= l(project.archived_on, format: :full_date) %></span>
|
||||
<span class="value cell-value"> <%= l(project.archived_on, format: :full_with_comma) %></span>
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
<% end %>
|
||||
<% end %>
|
||||
<a href="#" class="btn btn-light edit-btn single-object-action hidden" data-for="editable">
|
||||
<span class="fas fa-folder" aria-hidden="true"></span>
|
||||
<span class="fas fa-pencil-alt" aria-hidden="true"></span>
|
||||
<span class="hidden-xs"><%= t('projects.index.edit_button') %></span>
|
||||
</a>
|
||||
<a href="#" class="btn btn-light move-projects-btn multiple-object-action hidden" data-for="moveable" data-url="<%= move_to_modal_project_folders_url %>">
|
||||
|
|
|
|||
|
|
@ -7,28 +7,36 @@
|
|||
<%= render partial: 'shared/sidebar/experiments.html.erb', locals: { project: @project, archived: false } %>
|
||||
<% end %>
|
||||
|
||||
<div class="content-pane flexible" id="project-show">
|
||||
<% content_for :breadcrumbs do %>
|
||||
<%= render partial: 'projects/index/breadcrumbs', locals: { target_folder: @project.project_folder } %>
|
||||
<% end %>
|
||||
|
||||
<div id="projectShowWrapper" class="content-pane flexible projects-show">
|
||||
<%= render partial: 'projects/show/header' %>
|
||||
<div class="project-show-toolbar">
|
||||
<% if can_create_experiments?(@project) %>
|
||||
<%= link_to new_project_experiment_url(@project),
|
||||
remote: true,
|
||||
type: "button",
|
||||
id: 'new-experiment',
|
||||
class: 'btn btn-primary' do %>
|
||||
<span class="fas fa-plus"></span>
|
||||
<span class="hidden-xs"><%=t 'experiments.new.create' %></span>
|
||||
|
||||
<div class="project-show-container">
|
||||
<div class="cards-wrapper" id="cardsWrapper">
|
||||
<!-- list -->
|
||||
<div class="table-header">
|
||||
<div class="table-header-cell select-all-checkboxes">
|
||||
<div class="sci-checkbox-container">
|
||||
<input value="1" type="checkbox" class="sci-checkbox select-all">
|
||||
<span class="sci-checkbox-label"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-header-cell"><%= t('experiments.card.name') %></div>
|
||||
<div class="table-header-cell"><%= t('experiments.card.start_date') %></div>
|
||||
<div class="table-header-cell"><%= t('experiments.card.modified_date') %></div>
|
||||
<div class="table-header-cell"><%= t('experiments.card.completed_task') %></div>
|
||||
<div class="table-header-cell"><%= t('experiments.card.description') %></div>
|
||||
<div class="table-header-cell"></div>
|
||||
</div>
|
||||
<!-- cards -->
|
||||
<% @project.sorted_experiments(@current_sort).each do |experiment| %>
|
||||
<%= render partial: 'projects/show/experiment_card',
|
||||
locals: { experiment: experiment } %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="row">
|
||||
<% @project.sorted_experiments(@current_sort).each_with_index do |experiment, index| %>
|
||||
<%= render partial: 'projects/show/experiment',
|
||||
locals: { experiment: experiment } %>
|
||||
<% end %>
|
||||
<% if can_create_experiments?(@project) %>
|
||||
<%= render 'projects/show/new_experiment' %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
28
app/views/projects/show/_experiment_card.html.erb
Normal file
28
app/views/projects/show/_experiment_card.html.erb
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<div class="card experiment-card">
|
||||
<div class="checkbox-cell table-cell">
|
||||
<div class="sci-checkbox-container">
|
||||
<input value="1" type="checkbox" class="sci-checkbox experiment-card-selector">
|
||||
<span class="sci-checkbox-label"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="experiment-name-cell table-cell">
|
||||
<%= experiment.name %>
|
||||
</div>
|
||||
<div class="actions actions-cell table-cell">
|
||||
<i class="fas fa-ellipsis-h"></i>
|
||||
</div>
|
||||
<div class="data-row start-date-cell table-cell">
|
||||
<span class="card-label"><%= t('experiments.card.start_date') %></span>
|
||||
<span class="value card-value"><%= l(experiment.created_at, format: :full_date) %></span>
|
||||
</div>
|
||||
<div class="data-row modified-date-cell table-cell">
|
||||
<span class="card-label"><%= t('experiments.card.modified_date') %></span>
|
||||
<span class="value card-value"><%= l(experiment.updated_at, format: :full_date) %></span>
|
||||
</div>
|
||||
<div class="data-row completed-task-cell table-cell">
|
||||
<span class="card-label"><%= t('experiments.card.completed_task') %></span>
|
||||
</div>
|
||||
<div class="data-row description-cell table-cell">
|
||||
<span class="card-label"><%= t('experiments.card.description') %></span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,35 +1,71 @@
|
|||
<div class="content-header">
|
||||
<h1 class="project-name">
|
||||
<% if @inline_editable_title_config.present? %>
|
||||
<%= render partial: "shared/inline_editing",
|
||||
locals: {
|
||||
initial_value: @project.name,
|
||||
config: @inline_editable_title_config
|
||||
} %>
|
||||
<% else %>
|
||||
<% if action_name == 'experiment_archive' %>
|
||||
<i class="fas fa-archive"></i>
|
||||
<% end %>
|
||||
<%= @project.name %>
|
||||
<% end %>
|
||||
</h1>
|
||||
<div class="header-actions">
|
||||
<div class="dropdown experiment-sort-menu">
|
||||
<button class="btn btn-light icon-btn dropdown-toggle" type="button" id="sortMenu" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||
<i class="fas fa-sort-amount-up"></i>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-right" aria-labelledby="sortMenu">
|
||||
<% ["new", "old", "atoz", "ztoa", "archived_new", "archived_old"].each_with_index do |sort, i| %>
|
||||
<% unless action_name != 'experiment_archive' && sort.include?('arch') %>
|
||||
<% if i.even? && i.positive? %>
|
||||
<li class="divider"></li>
|
||||
<% end %>
|
||||
<li>
|
||||
<a class="<%= 'selected' if @current_sort == sort %>" href="?<%= {sort: sort}.reject{|v| v.to_s == "0"}.to_query %>"><%= t("general.sort.#{sort}_html") %></a>
|
||||
</li>
|
||||
<% end %>
|
||||
<div class="content-header sticky-header">
|
||||
<div class="title-row">
|
||||
<h1 class="project-name">
|
||||
<% if @inline_editable_title_config.present? %>
|
||||
<%= render partial: "shared/inline_editing",
|
||||
locals: {
|
||||
initial_value: @project.name,
|
||||
config: @inline_editable_title_config
|
||||
} %>
|
||||
<% else %>
|
||||
<% if action_name == 'experiment_archive' %>
|
||||
<i class="fas fa-archive"></i>
|
||||
<% end %>
|
||||
</ul>
|
||||
<%= @project.name %>
|
||||
<% end %>
|
||||
</h1>
|
||||
<div class="sci-btn-group header-actions">
|
||||
<!-- View switch dropdown -->
|
||||
<%= render layout: 'shared/view_switch', locals: { disabled: false } do %>
|
||||
<li class="view-switch-cards cards-switch active">
|
||||
<i class="fas fa-th-large button-icon"></i> <%= t('experiments.header.cards') %>
|
||||
</li>
|
||||
|
||||
<li class="view-switch-list cards-switch ">
|
||||
<i class="fas fa-list button-icon"></i> <%= t('experiments.header.table') %>
|
||||
</li>
|
||||
|
||||
<div role="separator" class="divider"></div>
|
||||
<li class="view-switch-active archive-switch" data-view-mode="archived" data-url="<%= project_path(@project) %>">
|
||||
<i class="fas fa-rocket button-icon"></i> <%= t('experiments.header.active_experiments') %>
|
||||
</li>
|
||||
|
||||
<li class="view-switch-archived archive-switch" data-view-mode="active" data-url="<%= project_path(@project, view_mode: 'archived') %>">
|
||||
<i class="fas fa-archive button-icon"></i> <%= t('experiments.header.archived_experiments') %>
|
||||
</li>
|
||||
<% end %>
|
||||
<%= render layout: 'shared/filter_dropdown', locals: {
|
||||
container_class: 'experiments-filters',
|
||||
dropdown_title: t("filters_modal.title"),
|
||||
search_field_history_key: 'experiment_filters_per_team'
|
||||
} do %>
|
||||
<%= render partial: 'shared/filter_dropdown/text_search', locals: {container_class: ''} %>
|
||||
<%= render partial: 'shared/filter_dropdown/datetime_search', locals: {container_class: 'started-on-filter', label: t("filters_modal.created_on.label"), view_mode: nil } %>
|
||||
<%= render partial: 'shared/filter_dropdown/datetime_search', locals: {container_class: 'modified-on-filter', label: t("filters_modal.updated_on.label"), view_mode: nil } %>
|
||||
<%= render partial: 'shared/filter_dropdown/datetime_search', locals: {container_class: 'archived-on-filter', label: t("filters_modal.archived_on.label"), view_mode: 'archived' } %>
|
||||
|
||||
<% end %>
|
||||
<!-- Sort menu dropdown -->
|
||||
<div class="dropdown sort-menu">
|
||||
<button class="btn btn-light icon-btn dropdown-toggle" type="button" id="sortMenu" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||
<i class="fas fa-sort-amount-up"></i>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-right" aria-labelledby="sortMenu">
|
||||
<% ["new", "old", "atoz", "ztoa", "archived_new", "archived_old"].each_with_index do |sort, i| %>
|
||||
<% unless action_name != 'experiment_archive' && sort.include?('arch') %>
|
||||
<% if i.even? && i.positive? %>
|
||||
<li class="divider"></li>
|
||||
<% end %>
|
||||
<li>
|
||||
<a class="<%= 'selected' if @current_sort == sort %>" href="?<%= {sort: sort}.reject{|v| v.to_s == "0"}.to_query %>"><%= t("general.sort.#{sort}_html") %></a>
|
||||
</li>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="toolbarWrapper" class="toolbar-row">
|
||||
<%= render partial: 'projects/show/toolbar' %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
33
app/views/projects/show/_toolbar.html.erb
Normal file
33
app/views/projects/show/_toolbar.html.erb
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<div id="projectShowToolbar" class="project-show-toolbar">
|
||||
<!-- new experiment button -->
|
||||
<% if can_create_experiments?(@project) %>
|
||||
<%= link_to new_project_experiment_url(@project),
|
||||
remote: true,
|
||||
type: "button",
|
||||
id: 'new-experiment',
|
||||
class: 'btn btn-primary' do %>
|
||||
<span class="fas fa-plus" aria-hidden="true"></span>
|
||||
<span class="hidden-xs"><%= t('experiments.toolbar.new_button') %></span>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<a href="#" class="btn btn-light edit-experiment-btn single-object-action" data-for="editable" data-url="">
|
||||
<span class="fas fa-pencil-alt" aria-hidden="true"></span>
|
||||
<span class="hidden-xs"><%= t('experiments.toolbar.edit_button') %></span>
|
||||
</a>
|
||||
|
||||
<a href="#" class="btn btn-light duplicate-experiment-btn multiple-object-action" data-for="duplicable" data-url="">
|
||||
<span class="fas fa-copy" aria-hidden="true"></span>
|
||||
<span class="hidden-xs"><%= t('experiments.toolbar.duplicate_button') %></span>
|
||||
</a>
|
||||
|
||||
<a href="#" class="btn btn-light move-experiments-btn multiple-object-action" data-for="moveable" data-url="">
|
||||
<span class="fas fa-arrow-right" aria-hidden="true"></span>
|
||||
<span class="hidden-xs"><%= t('experiments.toolbar.move_button') %></span>
|
||||
</a>
|
||||
|
||||
<a href="#" class="btn btn-light archive-experiments-btn multiple-object-action" data-for="archivable" data-url="">
|
||||
<span class="fas fa-archive" aria-hidden="true"></span>
|
||||
<span class="hidden-xs"><%= t('experiments.toolbar.archive_button') %></span>
|
||||
</a>
|
||||
</div>
|
||||
|
|
@ -10,18 +10,20 @@
|
|||
<div class="content-pane flexible <%= params[:archived] ? :archived : :active %> repositories-index"
|
||||
data-readonly="<%= !current_user.is_admin_of_team?(current_team) %>">
|
||||
<div class="content-header">
|
||||
<h1 data-view-mode="active"><%= t('libraries.index.head_title') %></h1>
|
||||
<h1 data-view-mode="archived"><i class="fas fa-archive"></i> <%= t('libraries.index.head_title_archived') %></h1>
|
||||
<%= render layout: "shared/view_switch", locals: { disabled: false } do %>
|
||||
<li class="view-switch-archived" data-view-mode="active">
|
||||
<i class="fas fa-archive button-icon"></i>
|
||||
<%= t('libraries.index.switch_view.archived') %>
|
||||
</li>
|
||||
<li class="view-switch-active" data-view-mode="archived">
|
||||
<i class="fas fa-rocket button-icon"></i>
|
||||
<%= t('libraries.index.switch_view.active') %>
|
||||
</li>
|
||||
<% end %>
|
||||
<div class="title-row">
|
||||
<h1 data-view-mode="active"><%= t('libraries.index.head_title') %></h1>
|
||||
<h1 data-view-mode="archived"><i class="fas fa-archive"></i> <%= t('libraries.index.head_title_archived') %></h1>
|
||||
<%= render layout: "shared/view_switch", locals: { disabled: false } do %>
|
||||
<li class="view-switch-archived" data-view-mode="active">
|
||||
<i class="fas fa-archive button-icon"></i>
|
||||
<%= t('libraries.index.switch_view.archived') %>
|
||||
</li>
|
||||
<li class="view-switch-active" data-view-mode="archived">
|
||||
<i class="fas fa-rocket button-icon"></i>
|
||||
<%= t('libraries.index.switch_view.active') %>
|
||||
</li>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-body">
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -14,133 +14,134 @@
|
|||
|
||||
<div class="content-pane repository-show <%= @repository.active? ? "active" : "archived" %>" data-table-url="<%= load_table_repository_path(@repository) %>">
|
||||
<div id="repository-toolbar" class="content-header">
|
||||
<% if @repository.active? %>
|
||||
<div class="repository-title-name" data-view-mode="active">
|
||||
<h1 class="name-container">
|
||||
<% if @inline_editable_title_config.present? %>
|
||||
<%= render partial: "shared/inline_editing",
|
||||
locals: {
|
||||
initial_value: @repository.name,
|
||||
config: @inline_editable_title_config
|
||||
} %>
|
||||
<% else %>
|
||||
<div class="read-only-name">
|
||||
<%= @repository.name %>
|
||||
</div>
|
||||
<span class="repository-share-icon">
|
||||
<%= inventory_shared_status_icon(@repository, current_team) %>
|
||||
</span>
|
||||
<div class="title-row">
|
||||
<% if @repository.active? %>
|
||||
<div class="repository-title-name" data-view-mode="active">
|
||||
<h1 class="name-container">
|
||||
<% if @inline_editable_title_config.present? %>
|
||||
<%= render partial: "shared/inline_editing",
|
||||
locals: {
|
||||
initial_value: @repository.name,
|
||||
config: @inline_editable_title_config
|
||||
} %>
|
||||
<% else %>
|
||||
<div class="read-only-name">
|
||||
<%= @repository.name %>
|
||||
</div>
|
||||
<span class="repository-share-icon">
|
||||
<%= inventory_shared_status_icon(@repository, current_team) %>
|
||||
</span>
|
||||
<% end %>
|
||||
</h1>
|
||||
<% if @repository.shared_with_anybody? %>
|
||||
<% team_name = @repository.team == current_team ? t('repositories.show.your_team') : @repository.team.name %>
|
||||
<div class="repository-subtitle"><%= t('repositories.show.subtitle', team_name: team_name) %></div>
|
||||
<% end %>
|
||||
</h1>
|
||||
<% if @repository.shared_with_anybody? %>
|
||||
<% team_name = @repository.team == current_team ? t('repositories.show.your_team') : @repository.team.name %>
|
||||
<div class="repository-subtitle"><%= t('repositories.show.subtitle', team_name: team_name) %></div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="repository-archived-title-name" data-view-mode="archived">
|
||||
<% if @repository.archived? %>
|
||||
<i class="fas fa-archive"></i>
|
||||
<%= t('repositories.show.archived_inventory', repository_name: @repository.name) %>
|
||||
<% else %>
|
||||
<%= t('repositories.show.archived_inventory_items', repository_name: @repository.name) %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="repo-datatables-buttons">
|
||||
<div class="share-repository-button" data-view-mode="active">
|
||||
<% if can_share_repository?(@repository) && current_user.teams.count > 1 %>
|
||||
<%= link_to team_repository_share_modal_path(current_team, repository_id: @repository),
|
||||
class: 'btn btn-secondary share-repo-option', remote: true, id: 'shareRepoBtn' do %>
|
||||
<span class="fas fa-user-plus"></span>
|
||||
<span class="hidden-xs"><%= t('repositories.index.share_inventory') %></span>
|
||||
<% end %>
|
||||
<div class="repository-archived-title-name" data-view-mode="archived">
|
||||
<% if @repository.archived? %>
|
||||
<i class="fas fa-archive"></i>
|
||||
<%= t('repositories.show.archived_inventory', repository_name: @repository.name) %>
|
||||
<% else %>
|
||||
<%= t('repositories.show.archived_inventory_items', repository_name: @repository.name) %>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="repo-datatables-buttons">
|
||||
<div class="share-repository-button" data-view-mode="active">
|
||||
<% if can_share_repository?(@repository) && current_user.teams.count > 1 %>
|
||||
<%= link_to team_repository_share_modal_path(current_team, repository_id: @repository),
|
||||
class: 'btn btn-secondary share-repo-option', remote: true, id: 'shareRepoBtn' do %>
|
||||
<span class="fas fa-user-plus"></span>
|
||||
<span class="hidden-xs"><%= t('repositories.index.share_inventory') %></span>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-secondary manage-repo-column-index"
|
||||
data-modal-url="<%= repository_repository_columns_path(@repository) %>"
|
||||
data-action="new">
|
||||
<span class="fas fa-wrench"></span> <%= t('repositories.index.columns') %>
|
||||
</button>
|
||||
|
||||
<div class="repository-cog dropdown">
|
||||
<button id="repository-acitons-dropdown"
|
||||
class="btn btn-secondary"
|
||||
type="button"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="true"
|
||||
<%= "disabled" unless can_perform_repository_actions(@repository) %>>
|
||||
<span class="fas fa-pencil-alt"></span>
|
||||
<span class="hidden-xs"><%= t('repositories.index.edit_inventory') %></span>
|
||||
<span class="caret"></span>
|
||||
<button class="btn btn-secondary manage-repo-column-index"
|
||||
data-modal-url="<%= repository_repository_columns_path(@repository) %>"
|
||||
data-action="new">
|
||||
<span class="fas fa-wrench"></span> <%= t('repositories.index.columns') %>
|
||||
</button>
|
||||
|
||||
<% if can_perform_repository_actions(@repository) %>
|
||||
<ul class="dropdown-menu pull-right">
|
||||
<% if can_create_repository_rows?(@repository) %>
|
||||
<li data-view-mode="active">
|
||||
<a href="#" id="importRecordsButton" data-turbolinks="false">
|
||||
<%= t('repositories.index.options_dropdown.import_items') %>
|
||||
</a>
|
||||
</li>
|
||||
<% end %>
|
||||
<% if can_read_repository?(@repository) %>
|
||||
<li >
|
||||
<a href="#" id="exportRepositoriesButton" data-turbolinks="false">
|
||||
<%= t("repositories.index.options_dropdown.export_items") %>
|
||||
</a>
|
||||
</li>
|
||||
<% end %>
|
||||
<% if can_create_repositories?(current_team) && !@repository.shared_with?(current_team) %>
|
||||
<li data-view-mode="active">
|
||||
<%= link_to t('repositories.index.options_dropdown.copy'),
|
||||
team_repository_copy_modal_path(current_team, repository_id: @repository),
|
||||
class: "copy-repo-option",
|
||||
remote: true %>
|
||||
</li>
|
||||
<% end %>
|
||||
<% if can_archive_repository?(@repository) %>
|
||||
<li data-view-mode="active" role="separator" class="divider"></li>
|
||||
<li data-view-mode="active">
|
||||
<%= link_to t('repositories.index.options_dropdown.archive'),
|
||||
archive_team_repositories_path(current_team),
|
||||
class: "archive-repository-option",
|
||||
data: { repository_id: @repository.id } %>
|
||||
</li>
|
||||
<% if @repository.archived? %>
|
||||
<li data-view-mode="archived">
|
||||
<%= link_to t('repositories.index.options_dropdown.restore'),
|
||||
restore_team_repositories_path(current_team),
|
||||
<div class="repository-cog dropdown">
|
||||
<button id="repository-acitons-dropdown"
|
||||
class="btn btn-secondary"
|
||||
type="button"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="true"
|
||||
<%= "disabled" unless can_perform_repository_actions(@repository) %>>
|
||||
<span class="fas fa-pencil-alt"></span>
|
||||
<span class="hidden-xs"><%= t('repositories.index.edit_inventory') %></span>
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
|
||||
<% if can_perform_repository_actions(@repository) %>
|
||||
<ul class="dropdown-menu pull-right">
|
||||
<% if can_create_repository_rows?(@repository) %>
|
||||
<li data-view-mode="active">
|
||||
<a href="#" id="importRecordsButton" data-turbolinks="false">
|
||||
<%= t('repositories.index.options_dropdown.import_items') %>
|
||||
</a>
|
||||
</li>
|
||||
<% end %>
|
||||
<% if can_read_repository?(@repository) %>
|
||||
<li >
|
||||
<a href="#" id="exportRepositoriesButton" data-turbolinks="false">
|
||||
<%= t("repositories.index.options_dropdown.export_items") %>
|
||||
</a>
|
||||
</li>
|
||||
<% end %>
|
||||
<% if can_create_repositories?(current_team) && !@repository.shared_with?(current_team) %>
|
||||
<li data-view-mode="active">
|
||||
<%= link_to t('repositories.index.options_dropdown.copy'),
|
||||
team_repository_copy_modal_path(current_team, repository_id: @repository),
|
||||
class: "copy-repo-option",
|
||||
remote: true %>
|
||||
</li>
|
||||
<% end %>
|
||||
<% if can_archive_repository?(@repository) %>
|
||||
<li data-view-mode="active" role="separator" class="divider"></li>
|
||||
<li data-view-mode="active">
|
||||
<%= link_to t('repositories.index.options_dropdown.archive'),
|
||||
archive_team_repositories_path(current_team),
|
||||
class: "archive-repository-option",
|
||||
data: { repository_id: @repository.id } %>
|
||||
</li>
|
||||
<% if @repository.archived? %>
|
||||
<li data-view-mode="archived">
|
||||
<%= link_to t('repositories.index.options_dropdown.restore'),
|
||||
restore_team_repositories_path(current_team),
|
||||
class: "archive-repository-option",
|
||||
data: { repository_id: @repository.id } %>
|
||||
</li>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% if can_manage_repository?(@repository) && @repository.archived? %>
|
||||
<li data-view-mode="archived" data-hook="destroy-repository-option">
|
||||
<%= link_to t('repositories.index.options_dropdown.delete'),
|
||||
team_repository_destroy_modal_path(current_team, repository_id: @repository),
|
||||
class: "delete-repo-option",
|
||||
remote: true %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
<% if can_manage_repository?(@repository) && @repository.archived? %>
|
||||
<li data-view-mode="archived" data-hook="destroy-repository-option">
|
||||
<%= link_to t('repositories.index.options_dropdown.delete'),
|
||||
team_repository_destroy_modal_path(current_team, repository_id: @repository),
|
||||
class: "delete-repo-option",
|
||||
remote: true %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
</div>
|
||||
<%= render layout: "shared/view_switch", locals: {disabled: @repository.archived?} do %>
|
||||
<li class="view-switch-archived" data-view-mode="active">
|
||||
<i class="fas fa-archive button-icon"></i>
|
||||
<%= t('repositories.show.show_archived_items') %>
|
||||
</li>
|
||||
<li class="view-switch-active" data-view-mode="archived">
|
||||
<i class="fas fa-rocket button-icon"></i>
|
||||
<%= t('repositories.show.show_active_items') %>
|
||||
</li>
|
||||
<% end %>
|
||||
</div>
|
||||
<%= render layout: "shared/view_switch", locals: {disabled: @repository.archived?} do %>
|
||||
<li class="view-switch-archived" data-view-mode="active">
|
||||
<i class="fas fa-archive button-icon"></i>
|
||||
<%= t('repositories.show.show_archived_items') %>
|
||||
</li>
|
||||
<li class="view-switch-active" data-view-mode="archived">
|
||||
<i class="fas fa-rocket button-icon"></i>
|
||||
<%= t('repositories.show.show_active_items') %>
|
||||
</li>
|
||||
<% end %>
|
||||
<div class="toolbar-delimiter"></div>
|
||||
</div>
|
||||
|
||||
<div class="toolbar-delimiter"></div>
|
||||
</div>
|
||||
|
||||
<!-- These buttons are appended to table in javascript, after table initialization -->
|
||||
|
|
|
|||
16
app/views/shared/_filter_dropdown.html.erb
Normal file
16
app/views/shared/_filter_dropdown.html.erb
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<div class="filter-container dropdown <%= container_class + '-dropdown' %>">
|
||||
<button class="btn btn-light icon-btn filter-button" data-toggle="dropdown"><i class="fas fa-filter"></i></button>
|
||||
<div class="dropdown-menu dropdown-menu-right filter-dropdown <%= container_class %>" role="menu" data-team-id="<%= current_team.id %>" data-search-field-history-key="<%= search_field_history_key %>">
|
||||
<div class="header">
|
||||
<div class="title"><%= dropdown_title %></div>
|
||||
<div class="btn btn-light clear-button">
|
||||
<i class="fas fa-times-circle"></i><%= t("filters_modal.clear_btn") %></div>
|
||||
</div>
|
||||
<div class="body">
|
||||
<%= yield %>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<div class="btn btn-primary apply-filters"><%= t("filters_modal.show_btn.one") %></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
<span class="caret pull-right"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-right" aria-labelledby="viewSwitchButton">
|
||||
<li class="divider-label"><%= t("general.set_view_type") %></li>
|
||||
<%= yield %>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
|||
33
app/views/shared/filter_dropdown/_datetime_search.html.erb
Normal file
33
app/views/shared/filter_dropdown/_datetime_search.html.erb
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<div class="select-block <%= container_class %>" <%= "data-view-mode=#{view_mode}" if view_mode %>>
|
||||
<div class="created-on-label">
|
||||
<label><%= label %></label>
|
||||
</div>
|
||||
<div class="datetime-picker-container">
|
||||
<span class="fas fa-calendar-alt"></span>
|
||||
<input type="datetime"
|
||||
data-toggle='date-time-picker'
|
||||
class="form-control calendar-input from-date"
|
||||
readonly
|
||||
placeholder="<%= t('filters_modal.from_placeholder') %>"
|
||||
data-date-format="<%= datetime_picker_format_full %>"
|
||||
data-date-locale="<%= I18n.locale %>"
|
||||
data-date-use-current="false"
|
||||
value=""/>
|
||||
</div>
|
||||
|
||||
<div class="connect-line"></div>
|
||||
|
||||
<div class="datetime-picker-container">
|
||||
<span class="fas fa-calendar-alt"></span>
|
||||
<input type="datetime"
|
||||
data-toggle='date-time-picker'
|
||||
class="form-control calendar-input to-date"
|
||||
readonly
|
||||
placeholder="<%= t('filters_modal.to_placeholder') %>"
|
||||
data-date-format="<%= datetime_picker_format_full %>"
|
||||
data-date-locale="<%= I18n.locale %>"
|
||||
data-date-use-current="false"
|
||||
data-date-orientation="left"
|
||||
value=""/>
|
||||
</div>
|
||||
</div>
|
||||
15
app/views/shared/filter_dropdown/_text_search.html.erb
Normal file
15
app/views/shared/filter_dropdown/_text_search.html.erb
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<div class="select-block dropdown-selector-container">
|
||||
<label><%= t('filters_modal.text.label') %></label>
|
||||
<div class="input-field dropdown text-search-filter">
|
||||
<input id="textSearchFilterInput"
|
||||
class="dropdown-toggle search-field"
|
||||
type="text"
|
||||
name="search"
|
||||
autocomplete="off"
|
||||
data-toggle="dropdown"
|
||||
placeholder="<%= t('filters_modal.text.placeholder') %>">
|
||||
</div>
|
||||
<div id="textSearchFilterHistory" class="dropdown-menu recent-searches" aria-labelledby="textSearchFilterInput">
|
||||
<label><%= t("filters_modal.recent_searches_label") %></label>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -5,7 +5,9 @@
|
|||
|
||||
<div class="content-pane active flexible user-settings">
|
||||
<div class="content-header">
|
||||
<h1><%=t "users.registrations.edit.title" %></h1>
|
||||
<div class="title-row">
|
||||
<h1><%=t "users.registrations.edit.title" %></h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row settings-row">
|
||||
<div class="col-md-12">
|
||||
|
|
|
|||
|
|
@ -425,30 +425,12 @@ en:
|
|||
invite_users_details: "to team %{team}."
|
||||
contact_admins: "To invite additional users to team %{team}, contact its administrator/s."
|
||||
filters_modal:
|
||||
title: "Filters"
|
||||
text:
|
||||
label: "Contains text"
|
||||
placeholder: "Enter search terms..."
|
||||
created_on:
|
||||
label: "Start date"
|
||||
from_placeholder: "From"
|
||||
to_placeholder: "To"
|
||||
archived_on:
|
||||
label: "Archived date"
|
||||
from_placeholder: "From"
|
||||
to_placeholder: "To"
|
||||
members:
|
||||
label: "Members"
|
||||
placeholder: "Select members of a project"
|
||||
folders:
|
||||
label: "Look inside folders"
|
||||
popover_html: "When <strong>“Look inside folders”</strong> is active, the filters will also take all folders and their content into account."
|
||||
recent_searches_label: "Recent searches"
|
||||
show_btn:
|
||||
many: "Show %{num} projects"
|
||||
none: "No projects"
|
||||
one: "Show project"
|
||||
clear_btn: "Clear"
|
||||
|
||||
export_projects:
|
||||
export_button: "Export"
|
||||
|
|
@ -961,6 +943,24 @@ en:
|
|||
body_html: This inventory has been ushared with your team by the inventory’s owner. To view the item/s that are assigned to your task/s contact the <b>%{team_name}</b> team administrator <b>%{admin_name}</b> (<b>%{admin_email}</b>).
|
||||
open_mobile_app: "Open mobile app"
|
||||
experiments:
|
||||
header:
|
||||
cards: "Cards"
|
||||
table: "Table"
|
||||
active_experiments: "Go to Active experiments"
|
||||
archived_experiments: "Go to Archived experiments"
|
||||
toolbar:
|
||||
new_button: "New experiment"
|
||||
edit_button: "Edit details"
|
||||
duplicate_button: "Duplicate"
|
||||
move_button: "Move"
|
||||
archive_button: "Archive"
|
||||
card:
|
||||
name: "Experiment"
|
||||
start_date: "Start date"
|
||||
modified_date: "Modified date"
|
||||
archived_date: "Archived date"
|
||||
completed_task: "Completed"
|
||||
description: "Description"
|
||||
new:
|
||||
create: 'New Experiment'
|
||||
modal_title: 'Create new experiment'
|
||||
|
|
@ -2337,6 +2337,7 @@ en:
|
|||
public: "public"
|
||||
private: "private"
|
||||
view: "View"
|
||||
set_view_type: "SET VIEW TYPE"
|
||||
search: "Search"
|
||||
file:
|
||||
choose: "Choose File"
|
||||
|
|
@ -2482,3 +2483,21 @@ en:
|
|||
previous: "Previous"
|
||||
next: "Next"
|
||||
truncate: "…"
|
||||
|
||||
filters_modal:
|
||||
title: "Filters"
|
||||
text:
|
||||
label: "Contains text"
|
||||
placeholder: "Enter search terms..."
|
||||
from_placeholder: "From"
|
||||
to_placeholder: "To"
|
||||
created_on:
|
||||
label: "Start date"
|
||||
updated_on:
|
||||
label: "Modified date"
|
||||
archived_on:
|
||||
label: "Archived date"
|
||||
recent_searches_label: "Recent searches"
|
||||
show_btn:
|
||||
one: "Show results"
|
||||
clear_btn: "Clear"
|
||||
|
|
|
|||
170
spec/services/experiments_overview_service_spec.rb
Normal file
170
spec/services/experiments_overview_service_spec.rb
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe ExperimentsOverviewService do
|
||||
EXPERIMENTS_CNT = 26
|
||||
time = Time.new(2019, 8, 1, 14, 35, 0)
|
||||
let!(:user) { create :user }
|
||||
let!(:project) { create :project }
|
||||
before do
|
||||
@experiments_overview = ExperimentsOverviewService.new(project, user, params)
|
||||
end
|
||||
|
||||
let!(:experiment_1) do
|
||||
create :experiment, name: 'test experiment D', project: project,
|
||||
archived: false, created_at: time.advance(hours: 2)
|
||||
end
|
||||
let!(:experiment_2) do
|
||||
create :experiment, name: 'test experiment B', project: project,
|
||||
archived: true, archived_on: time.advance(hours: 9), archived_by: user, created_at: time
|
||||
end
|
||||
let!(:experiment_3) do
|
||||
create :experiment, name: 'test experiment C', project: project,
|
||||
archived: false, created_at: time.advance(hours: 3)
|
||||
end
|
||||
let!(:experiment_4) do
|
||||
create :experiment, name: 'test experiment A', project: project,
|
||||
archived: true, archived_on: time.advance(hours: 8), archived_by: user,
|
||||
created_at: time.advance(hours: 1)
|
||||
end
|
||||
let!(:experiment_5) do
|
||||
create :experiment, name: 'test experiment E', project: project,
|
||||
archived: true, archived_on: time.advance(hours: 10), archived_by: user,
|
||||
created_at: time.advance(hours: 5)
|
||||
end
|
||||
let!(:experiment_6) do
|
||||
create :experiment, name: 'test experiment F', project: project,
|
||||
archived: false, created_at: time.advance(hours: 4)
|
||||
end
|
||||
(7..EXPERIMENTS_CNT).each do |i|
|
||||
let!("experiment_#{i}") do
|
||||
create :experiment, name: "test experiment #{(64 + i).chr}",
|
||||
project: project, created_at: time.advance(hours: 6, minutes: i)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#experiments' do
|
||||
let(:params) { {} }
|
||||
|
||||
context "with request parameters { filter: 'active' }" do
|
||||
let(:params) { { view_mode: 'active' } }
|
||||
|
||||
it 'returns all active experiments' do
|
||||
experiments = @experiments_overview.experiments
|
||||
expect(experiments.length).to eq EXPERIMENTS_CNT - 3
|
||||
expect(experiments.uniq.length).to eq experiments.length
|
||||
expect(experiments).to include(experiment_1, experiment_3)
|
||||
expect(experiments).not_to include(experiment_2, experiment_4, experiment_5)
|
||||
end
|
||||
|
||||
context "with request parameters { sort: 'old' }" do
|
||||
let(:params) { super().merge(sort: 'old') }
|
||||
|
||||
it 'returns all active experiments, sorted by ascending creation time attribute' do
|
||||
experiments = @experiments_overview.experiments
|
||||
expect(experiments.length).to eq EXPERIMENTS_CNT - 3
|
||||
expect(experiments.uniq.length).to eq experiments.length
|
||||
expect(experiments.first(2)).to eq [experiment_1, experiment_3]
|
||||
expect(experiments).not_to include(experiment_2, experiment_4, experiment_5)
|
||||
end
|
||||
end
|
||||
|
||||
context "with request parameters { sort: 'new' }" do
|
||||
let(:params) { super().merge(sort: 'new') }
|
||||
|
||||
it 'returns all active experiments, sorted by descending creation time attribute' do
|
||||
experiments = @experiments_overview.experiments
|
||||
expect(experiments.length).to eq EXPERIMENTS_CNT - 3
|
||||
expect(experiments.uniq.length).to eq experiments.length
|
||||
expect(experiments.last(2)).to eq [experiment_3, experiment_1]
|
||||
expect(experiments).not_to include(experiment_2, experiment_4, experiment_5)
|
||||
end
|
||||
end
|
||||
|
||||
context "with request parameters { sort: 'atoz' }" do
|
||||
let(:params) { super().merge(sort: 'atoz') }
|
||||
|
||||
it 'returns all active experiments, sorted by ascending name attribute' do
|
||||
experiments = @experiments_overview.experiments
|
||||
expect(experiments.length).to eq EXPERIMENTS_CNT - 3
|
||||
expect(experiments.uniq.length).to eq experiments.length
|
||||
expect(experiments.first(2)).to eq [experiment_3, experiment_1]
|
||||
expect(experiments).not_to include(experiment_2, experiment_4, experiment_5)
|
||||
end
|
||||
end
|
||||
|
||||
context "with request parameters { sort: 'ztoa' }" do
|
||||
let(:params) { super().merge(sort: 'ztoa') }
|
||||
|
||||
it 'returns all active experiments, sorted by descending name attribute' do
|
||||
experiments = @experiments_overview.experiments
|
||||
expect(experiments.length).to eq EXPERIMENTS_CNT - 3
|
||||
expect(experiments.uniq.length).to eq experiments.length
|
||||
expect(experiments.last(2)).to eq [experiment_1, experiment_3]
|
||||
expect(experiments).not_to include(experiment_2, experiment_4, experiment_5)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "with request parameters { filter: 'archived' }" do
|
||||
let(:params) { super().merge(view_mode: 'archived') }
|
||||
|
||||
it 'returns all archived experiments' do
|
||||
experiments = @experiments_overview.experiments
|
||||
expect(experiments.length).to eq 3
|
||||
expect(experiments.uniq.length).to eq experiments.length
|
||||
expect(experiments).to include(experiment_2, experiment_4, experiment_5)
|
||||
expect(experiments).not_to include(experiment_1, experiment_3)
|
||||
end
|
||||
|
||||
context "with request parameters { sort: 'old' }" do
|
||||
let(:params) { super().merge(sort: 'old') }
|
||||
|
||||
it 'returns all archived experiments, sorted by ascending creation time attribute' do
|
||||
experiments = @experiments_overview.experiments
|
||||
expect(experiments.length).to eq 3
|
||||
expect(experiments.uniq.length).to eq experiments.length
|
||||
expect(experiments.first(3)).to eq [experiment_2, experiment_4, experiment_5]
|
||||
expect(experiments).not_to include(experiment_1, experiment_3, experiment_6)
|
||||
end
|
||||
end
|
||||
|
||||
context "with request parameters { sort: 'new' }" do
|
||||
let(:params) { super().merge(sort: 'new') }
|
||||
|
||||
it 'returns all archived experiments, sorted by descending creation time attribute' do
|
||||
experiments = @experiments_overview.experiments
|
||||
expect(experiments.length).to eq 3
|
||||
expect(experiments.uniq.length).to eq experiments.length
|
||||
expect(experiments.last(3)).to eq [experiment_5, experiment_4, experiment_2]
|
||||
expect(experiments).not_to include(experiment_1, experiment_3, experiment_6)
|
||||
end
|
||||
end
|
||||
|
||||
context "with request parameters { sort: 'atoz' }" do
|
||||
let(:params) { super().merge(sort: 'atoz') }
|
||||
|
||||
it 'returns all archived experiments, sorted by ascending name attribute' do
|
||||
experiments = @experiments_overview.experiments
|
||||
expect(experiments.length).to eq 3
|
||||
expect(experiments.uniq.length).to eq experiments.length
|
||||
expect(experiments.first(3)).to eq [experiment_4, experiment_2, experiment_5]
|
||||
expect(experiments).not_to include(experiment_1, experiment_3, experiment_6)
|
||||
end
|
||||
end
|
||||
|
||||
context "with request parameters { sort: 'ztoa' }" do
|
||||
let(:params) { super().merge(sort: 'ztoa') }
|
||||
|
||||
it 'returns all archived experiments, sorted by descending name attribute' do
|
||||
experiments = @experiments_overview.experiments
|
||||
expect(experiments.length).to eq 3
|
||||
expect(experiments.uniq.length).to eq experiments.length
|
||||
expect(experiments.last(3)).to eq [experiment_5, experiment_2, experiment_4]
|
||||
expect(experiments).not_to include(experiment_1, experiment_3, experiment_6)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Reference in a new issue