Skip to content

Commit

Permalink
Search in administration (#3679)
Browse files Browse the repository at this point in the history
  • Loading branch information
JanMolcik authored Jan 29, 2025
2 parents de8eae1 + f53beec commit 8e8f7cc
Show file tree
Hide file tree
Showing 11 changed files with 515 additions and 78 deletions.
1 change: 1 addition & 0 deletions assets/js/admin/registerAdmin.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import '../common/components';
import '../common/validation';

import './components';
import './search/search';

import './validation/customization';
import './validation/form';
Expand Down
129 changes: 129 additions & 0 deletions assets/js/admin/search/search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import Ajax from '../../common/utils/Ajax';
import Register from '../../common/utils/Register';

export default class Search {
static init ($container) {
if ($container.is('body') === false) {
return;
}
let timeout;
const $searchInput = $container.filterAllNodes('.js-search-input');
const $searchResults = $container.filterAllNodes('.js-search-results');
const $searchResultsCloseButton = $container.filterAllNodes('.js-search-results__close');
const $searchIcon = $container.filterAllNodes('.js-search-icon');
const $searchElement = $container.filterAllNodes('.js-header-search');

$container.on('keydown', function (event) {
if (
(event.key === 'Tab' || event.key === 'ArrowDown' || event.key === 'ArrowUp')
&& $searchResults.is(':visible')
) {
event.preventDefault();
const focusableElements = $searchResults.filterAllNodes(
'div.web__header__search--results--container a'
);
$searchResults
.filterAllNodes('div.web__header__search--results--container div.result--item')
.removeClass('focused');
const focusable = Array.from(focusableElements);
const currentIndex = focusable.indexOf(document.activeElement);

let nextIndex;

const isUpward = event.key === 'ArrowUp' || (event.shiftKey && event.key === 'Tab');

if (isUpward) {
nextIndex = (currentIndex - 1 + focusable.length) % focusable.length;
} else {
nextIndex = (currentIndex + 1) % focusable.length;
}

if (nextIndex > -1) {
focusable[nextIndex].focus();
$(focusable[nextIndex]).closest('div.result--item').addClass('focused');
}

return;
}

if (event.key === 'Escape' && $searchResults.is(':visible')) {
event.preventDefault();
$searchResults.hide();
}
});

$searchIcon.on('click', function () {
if ($searchElement.hasClass('active')) {
$searchElement.removeClass('active');
} else {
$searchElement.addClass('active');
$searchInput.focus();
}
});

$searchResultsCloseButton.on('click', function (event) {
event.preventDefault();
Search.closeResults($searchResults, $searchInput);
$searchResultsCloseButton.hide();
});

$(document).on('click', function (event) {
if (!$(event.target).closest('.js-search-results').length) {
Search.closeResults($searchResults, $searchInput);
$searchResultsCloseButton.hide();
}
});

$searchInput.on('input', function () {
const $input = $(this);
clearTimeout(timeout);
if ($input.val().length > 0) {
$searchResultsCloseButton.show();
} else {
$searchResultsCloseButton.hide();
}
timeout = setTimeout(function () {
if ($input.val().length >= 3) {
Search.findResultsByInput($input, $searchResults);
}
if ($input.val().length < 3) {
Search.clearResults($searchResults);
}
}, 500);
});
}

static closeResults ($searchResults, $searchInput) {
Search.clearResults($searchResults);
$searchInput.val('');
}

static clearResults ($searchResults) {
$searchResults.find('.js-search-results__window').text('');
$searchResults.find('.js-search-results__search').text('');
$searchResults.hide();
}

static findResultsByInput ($searchInput, $searchResults) {
const value = $searchInput.val();
Ajax.ajax({
url: $searchInput.data('search-callback-url'),
loaderElement: 'none',
type: 'GET',
data: {
search: value
},
success: function (results) {
Search.showResults(value, results, $searchResults);
}
});
}

static showResults (search, results, $searchResults) {
const $htmlResult = $($.parseHTML(results));
$searchResults.find('.js-search-results__window').html($htmlResult);
$searchResults.find('.js-search-results__search').text(search);
$searchResults.show();
}
}
new Register().registerCallback(Search.init, 'Search.init');
1 change: 1 addition & 0 deletions assets/public/admin/svg/filter.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 34 additions & 8 deletions assets/styles/admin/layout/header/navig.less
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,45 @@
@header-navig-icon-size-small: 20px;
@header-navig-icon-background: @bg-page;

ul.navig {
padding-inline-start: unset;
}
.navig {
.reset-ul();
display: block;
margin-left: @width-panel;

display: flex;
font-size: 0;
padding-inline-start: unset;

&--side {
position: absolute;
right: 10px;
display: flex;
width: 100%;
margin: 0;

text-align: right;
&--left.navig__item {
display: flex;

@media @query-tablet {
margin-left: auto;
height: 100%;
}

@media @query-lg {
flex-grow: 1;
}
}

&--right {
display: flex;
margin-left: auto;
padding-right: 10px;

.svg-locale-flag {
min-width: 16px;
}

@media @query-tablet {
margin-left: unset;
}
}
}

&--main {
Expand All @@ -27,7 +53,7 @@
position: relative;
margin-right: 5px;

@media @query-lg {
@media @query-xl {
margin-right: 10px;
}

Expand Down
3 changes: 2 additions & 1 deletion assets/styles/admin/layout/layout.less
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,11 @@ body {

&__logo {
padding-left: @admin-header-padding;
width: 130px;
width: fit-content;

@media @query-lg {
width: @width-panel;
flex-shrink: 0;
}

&__svg {
Expand Down
127 changes: 127 additions & 0 deletions assets/styles/admin/todo.less
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,130 @@
.table-col-200px {
width: 200px;
}

.web__header__search {
display: none;
min-width: 235px;

@media @query-tablet {
position: absolute;
top: 50px;
width: 100%;
padding: 10px;
background-color: @color-f;
box-shadow: 0 2px 8px 0 rgba(77, 77, 77, 0.1);

&.active {
display: block !important;
}

.input {
width: 100%;
}
}

@media @query-lg {
display: flex;
position: relative;
flex-grow: 1;
min-width: 80px;
}

&__icon {
display: block;
margin-left: 10px;

.box-dropdown__select--menu {
display: flex;
align-items: center;

@media @query-tablet-only {
height: 39.5px;
}
}

@media @query-tablet-only {
height: 39.5px;
}

@media @query-lg {
display: none;
}
}

&--input.input {
display: inline-block;
height: 39.5px;
width: 100%;

@media @query-lg {
flex-grow: 1;
min-width: 80px;
}
}

&--results {
position: absolute;
top: 38.5px;
display: none;
padding: 5px;
width: fit-content;

color: #3b3b1f;
border: @input-border-size solid @color-border;
border-radius: @radius;
background-color: white;

@media @query-tablet {
top: 47.5px;
margin-right: 5px;
width: calc(~'100% - 20px');
}

@media @query-lg {
min-width: 300px;
}

&__close {
display: none;
position: absolute;
top: 50%;
right: 20px;
transform: translateY(-50%);

@media @query-lg {
right: 12px;
}
}

&__search-term {
display: flex;
margin-bottom: 8px;
}

&__hint {
margin-left: auto;
margin-bottom: 3px;
font-size: 10px;
text-align: right;
color: #8a8a8a;
display: inline-block;
}

.focused {
background-color: #b9e5ff;
}

&--container {
display: flex;
flex-direction: column;
text-align: left;
gap: 4px;
}
}

.result--path {
font-size: 10px;
color: #8a8a8a;
}
}
Loading

0 comments on commit 8e8f7cc

Please sign in to comment.