Commit c98e96f2 authored by Samir Sadyhov's avatar Samir Sadyhov 🤔

новый компонент меню с кнопкой создать

parent 08f3df70
this.MenuSearch = class {
constructor(menuItems, options = {}) {
this.locale = options.locale || AS?.OPTIONS?.locale || 'ru';
this.mode = options.mode || 'OR';
this.delay = options.delay || 250;
this.indexedMenu = this.buildIndex(menuItems);
this.searchDebounced = this.debounce(
this.search.bind(this),
this.delay
);
}
set filterCondition(mode) {
if (mode === 'AND' || mode === 'OR') this.mode = mode;
}
get filterCondition() {
return this.mode;
}
normalize(str = '') {
return str
.toLowerCase()
.replace(/[^\p{L}\p{N}\s]/gu, ' ')
.replace(/\s+/g, ' ')
.trim();
}
getLocalizedTitle(item) {
const t = item.translations?.find(t => t.locale === this.locale);
return t?.value || item.title || '';
}
buildIndex(items) {
return items.map(item => {
const indexed = {
...item,
_searchIndex: this.normalize(
`${this.getLocalizedTitle(item)} ${item.code || ''}`
)
};
if (item.is_group && item.items) {
indexed.items = this.buildIndex(item.items);
}
return indexed;
});
}
calcScore(index, words, mode) {
let score = 0;
for (const w of words) {
if (index.includes(` ${w} `)) score += 2;
if (index.startsWith(w) || index.includes(` ${w}`)) score += 3;
}
if (mode === 'AND' && words.every(w => index.includes(w))) {
score += 5;
}
if (index.length < 40) score += 1;
return score;
}
search(query, modeOverride) {
if (!query) return [];
const mode = modeOverride || this.mode;
const words = this.normalize(query).split(' ');
const result = [];
const match =
mode === 'AND'
? index => words.every(w => index.includes(w))
: index => words.some(w => index.includes(w));
const walk = (list) => {
for (const item of list) {
if (!item.is_group && match(item._searchIndex)) {
result.push({
...item,
_score: this.calcScore(item._searchIndex, words, mode)
});
}
if (item.is_group && item.items) {
walk(item.items);
}
}
};
walk(this.indexedMenu);
return result.sort((a, b) => b._score - a._score);
}
debounce(fn, delay) {
let t;
return (query, mode) => {
clearTimeout(t);
t = setTimeout(() => fn(query, mode), delay);
};
}
}
/*
const search = new MenuSearch(menuItems, { mode: 'OR' });
search.setMode('AND');
const result = search.search('заявление кжс');
search.search('заявление кжс', 'OR');
search.search('заявление кжс', 'AND');
modeToggle.addEventListener('change', e => {
search.setMode(e.target.value);
});
const result = search.search('отпуск учебный');
console.log(result);
search.searchDebounced = search.debounce((value) => {
const result = search.search(value);
console.log(result);
}, 250);
searchInput.addEventListener('input', e => {
search.searchDebounced(e.target.value);
});
*/
\ No newline at end of file
.qam_buttons_group {
display: flex;
}
.qam_buttons_group button {
border: 1px solid #1890FF;
background: #1890FF;
color: #fff;
cursor: pointer;
font-weight: bold;
transition: .3s;
}
.qam_buttons_group button:first-child {
border-radius: 6px 0 0 6px;
padding: 5px 20px;
}
.qam_buttons_group button:last-child {
border-radius: 0 6px 6px 0;
border-left: 1px solid #64abf3;
padding: 0 10px;
}
.qam_buttons_group button:hover {
background-color: #49a7ff;
border-color: #49a7ff;
}
.qam_menu_container {
position: fixed;
display: none;
background: rgba(255,255,255, 0.8);
width: 100vw;
height: 100vh;
z-index: 1;
left: 0;
top: 0;
overflow: hidden;
}
.qam_menu_container.active {
display: block;
}
.qam_menu_container_header {
border-bottom: 1px solid #c4c4c4;
background: #fff;
display: flex;
position: absolute;
width: 100%;
height: 50px;
left: 0;
top: 0;
justify-content: space-between;
align-items: center;
padding: 0 20px;
gap: 20px;
}
.qam_menu_container_header_left {
display: flex;
width: 100%;
height: 100%;
justify-content: flex-start;
align-items: center;
}
.qam_menu_container_header_right {
display: flex;
width: 100%;
height: 100%;
justify-content: flex-end;
align-items: center;
gap: 20px;
}
.qam_menu_container_content {
display: flex;
position: absolute;
width: 100%;
height: calc(100% - 50px);
left: 0;
top: 50px;
overflow: auto;
}
.qam_favorites_modal_container {
display: flex;
flex-direction: column;
gap: 10px;
margin: 15px 20px;
overflow: hidden;
}
.qam_favorites_items_container {
width: 100%;
min-height: 100px;
max-height: 400px;
border: 1px solid #cfcfcf;
overflow: auto;
}
.qam_favorites_buttons {
display: flex;
justify-content: center;
border-top: 1px solid #cfcfcf;
padding-top: 10px;
}
.qam_favorites_button {
display: flex;
justify-content: center;
border: 1px solid #cfcfcf;
padding: 10px 15px;
background: #fff;
border-radius: 6px;
cursor: pointer;
transition: .2s;
color: #222;
}
.qam_favorites_button:hover {
opacity: .7;
}
.qam_favorites_items_container>div {
width: 100%;
display: flex;
gap: 10px;
padding: 5px 10px;
user-select: none;
transition: 0.3s;
color: #333;
font-size: 14px;
}
.qam_favorites_items_container>div:nth-child(2n) {
background: #fbfbfb;
}
.qam_favorites_items_container>div:hover {
background: #E6F7FF;
}
.qam_favorites_items_container .favorites_group {
font-weight: bold;
padding-left: 40px;
}
.qam_favorites_items_container .favorites_item_container.selected {
background: #E6F7FF;
}
.favorites_icon {
cursor: pointer;
transition: .3s;
}
.favorites_icon[is_bookmark = "true"] {
color: #d8cb0f;
}
.favorites_icon[is_bookmark = "true"] polygon {
fill: #ffef00;
}
.favorites_icon[is_bookmark = "true"]:hover {
color: #333;
}
.favorites_icon[is_bookmark = "true"]:hover polygon {
fill: #fff;
}
.favorites_icon[is_bookmark = "false"]:hover {
color: #d8cb0f;
}
.favorites_icon[is_bookmark = "false"]:hover polygon {
fill: #d8cb0f;
}
.qam_menu_close_button {
width: 25px;
height: 25px;
cursor: pointer;
user-select: none;
transition: 0.3s ease-out 0s;
}
.qam_menu_close_button:hover {
transform: rotate(90deg);
}
.qam_menu_close_button:hover svg > line {
stroke: #f0506e;
}
#qam_input_search {
min-width: 450px;
border-radius: 3px;
}
.qam_filter_select_search {
border-radius: 3px;
}
.qam_item_list_container {
width: 100%;
background: #fff;
}
.qam_item_list_container .qam_item_list_item {
padding: 15px;
cursor: pointer;
transition: .2s;
}
.qam_item_list_container .qam_item_list_item:hover {
background: #E6F7FF;
}
.qam_menu_list {
min-width: 200px;
max-width: 350px;
border-right: 1px solid #eee;
background: #fff;
overflow-x: auto;
height: 100%;
}
.qam_menu_item {
padding: 8px 12px;
cursor: pointer;
user-select: none;
transition: .2s;
}
.qam_menu_item:hover {
background: #E6F7FF;
}
.qam_menu_item_group::after {
content: "›";
float: right;
opacity: .6;
}
.qam_menu_item_group.active {
background: #E6F7FF;
}
.uk-list-striped>li.qam_item_list_item:nth-child(even) {
background: #fff;
}
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment