Skip to content

Search #145

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: version2.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,247 changes: 3 additions & 1,244 deletions public/build/bundle.css

Large diffs are not rendered by default.

2,763 changes: 1 addition & 2,762 deletions public/build/bundle.js

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions public/javascripts/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const Editor = require('./editor').default;
*/
const Aside = require('./aside').default;
const Note = require('./note').default;
const Searcher = require('./searcher').default;

import User from './user';
import StatusBar from './status-bar';
Expand Down Expand Up @@ -46,6 +47,7 @@ let documentReady = () => {
codex.notes.user = new User();
codex.notes.statusBar = new StatusBar();
codex.notes.connectionObserver = new ConnectionObserver();
codex.notes.searcher = new Searcher();

/**
* New note saving handler
Expand Down
55 changes: 42 additions & 13 deletions public/javascripts/aside.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,13 +238,36 @@ export default class Aside {
* @param {number} noteData.folderId
*
* @param {Boolean} isRootFolder - true if Note is included to the Root Folder
* @param {Object} searchData - object with search data
*/
addMenuItem(noteData, isRootFolder) {
addMenuItem(noteData, isRootFolder, searchData) {
/**
* Creating note DOM
* @param {String} title - name of the note
* @param {Object} dataset - dataset of the root DOM note element
* @param {Object} highlight - object with coords of highlight for search
*/
let createNoteDOM = (title, dataset, highlight) => {
let item = this.makeMenuItem(title, dataset, highlight);

notesMenu.insertAdjacentElement('afterbegin', item);

item.addEventListener('click', event => this.menuItemClicked(event) );
};

if (!noteData.title) {
console.warn('Can not add Note to the Aside because it has no title', noteData);
return;
}

if (searchData) {
notesMenu = document.querySelector('[name="js-found-notes-menu"]');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

перенести в else if

createNoteDOM(noteData.title, {id: noteData._id}, searchData.highlight);
return;
} else {
codex.notes.searcher.pushData({title: noteData.title, _id: noteData._id});
}

let notesMenu;

if (isRootFolder) {
Expand All @@ -266,11 +289,7 @@ export default class Aside {
return;
}

let item = this.makeMenuItem(noteData.title, {id: noteData._id});

notesMenu.insertAdjacentElement('afterbegin', item);

item.addEventListener('click', event => this.menuItemClicked(event) );
createNoteDOM(noteData.title, {id: noteData._id});
}

/**
Expand All @@ -295,16 +314,23 @@ export default class Aside {

/**
* Makes aside menu item
* @param {String} title - item title
* @param {object} dataset - data to store in dataset
* @param {String} title - item title
* @param {Object} dataset - data to store in dataset
* @param {Object} highlight - pointers to part of title text to highlight
* @return {Element}
*/
makeMenuItem(title, dataset) {
makeMenuItem(title, dataset, highlight) {
title = this.createMenuItemTitle(title);

let item = $.make('li', null, {
textContent: title
});
let item = $.make('li');

if (highlight) {
item.innerHTML = title.substring(0, highlight.start) +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replace

'<span>' + title.substring(highlight.start, highlight.end) + '</span>'
+ title.substring(highlight.end);
} else {
item.textContent = title;
}

for (let key in dataset) {
item.dataset[key] = dataset[key];
Expand Down Expand Up @@ -337,7 +363,10 @@ export default class Aside {
notesMenu.forEach( menu => {
let existingNote = menu.querySelector('[data-id="' + itemId + '"]');

if (existingNote) existingNote.remove();
if (existingNote) {
existingNote.remove();
codex.notes.searcher.removeData(itemId);
}
});
}

Expand Down
146 changes: 146 additions & 0 deletions public/javascripts/searcher.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/**
* Class for searching through notes
*/
export default class Searcher {

/**
* @constructor
*/
constructor() {
/**
* DOM tree of class
* @type {Object}
*/
this.DOM = {
input: document.getElementsByClassName('searcher__input')[0],
foldersContainer: document.getElementsByName('js-folders-container')[0],
notes: {
created: document.getElementsByName('js-notes-menu')[0],
found: document.getElementsByName('js-found-notes-menu')[0]
}
};

/**
* CSS classes for DOM
* @type {Object}
*/
this.CSS = {
hidden: 'searcher__hidden'
};

/**
* Default value in the search input form
* @type {String}
*/
this.defaultInputValue = 'Search';

/**
* Where to search
* @type {Array}
*/
this.dataset = [];

/**
* Keyword from search field saved after search mode was disabled
* @type {Strng}
*/
this.lastSearch = '';

this.DOM.input.addEventListener('focus', () => {
this.DOM.notes.created.classList.add(this.CSS.hidden);
this.DOM.notes.found.classList.remove(this.CSS.hidden);
this.DOM.foldersContainer.classList.add(this.CSS.hidden);

this.DOM.input.value = this.lastSearch;
});

this.DOM.input.addEventListener('blur', (event) => {
if (event.relatedTarget != this.DOM.notes.found) {
this.DOM.notes.found.classList.add(this.CSS.hidden);
this.DOM.notes.found.classList.add(this.CSS.hidden);
this.DOM.notes.created.classList.remove(this.CSS.hidden);
this.DOM.foldersContainer.classList.remove(this.CSS.hidden);

this.lastSearch = this.DOM.input.value;
this.DOM.input.value = this.defaultInputValue;
}
});

this.DOM.input.addEventListener('keyup', () => {
this.search(this.DOM.input.value);
});
}

/**
* Cleans search results
* @param {Object} data - data to push to the dataset
*/
reset() {
let found = this.DOM.notes.found,
parent = found.parentNode;

this.DOM.notes.found = parent.removeChild(found).cloneNode(false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

innerHTML= '';

parent.appendChild(this.DOM.notes.found);
}

/**
* Push note data to array where search will be done
* @param {Object} data - data to push to the dataset
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

описать объект

*/
pushData( data ) {
let existingDataIndex = this.dataset.length;

this.dataset.forEach((item, index) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

написать комментарий

if (item._id == data._id) {
existingDataIndex = index;
return;
}
});

this.dataset.splice(existingDataIndex, 1, data);
}

/**
* Remove note data from array where search will be done
* @param {Object} dataId - the id of data to remove from the dataset
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

это не объект

*/
removeData( dataId ) {
let existingDataIndex = this.dataset.length;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

вынести код в метод


this.dataset.forEach((item, index) => {
if (item._id == dataId) {
existingDataIndex = index;
return;
}
});

this.dataset.splice(existingDataIndex, 1);
}

/**
* Find data in the dataset array
* @param {String} title - key to find data
*/
search( title ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

query

this.reset();

if (title == '') {
return;
}

let highlight = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

выделять на выводе через replace

start: 0,
end: 0
};

this.dataset.forEach((element) => {
highlight.start = element.title.indexOf(title);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inlcudes

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • учитывать регистр


if (highlight.start > -1) {
highlight.end = highlight.start + title.length;
codex.notes.aside.addMenuItem(element, true, {highlight: highlight});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

передавать подстроку, которую нужно выделить

}
});
}

}
1 change: 1 addition & 0 deletions public/stylesheets/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
@import "components/folder-header.css";
@import "components/folder-settings.css";
@import "components/status-bar.css";
@import "components/searcher.css";

body {
height: 100vh;
Expand Down
7 changes: 7 additions & 0 deletions public/stylesheets/components/aside.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@
color: var(--aside-color);
font-size: 13.7px;
letter-spacing: 0.3px;

&__content-wrap {
display: flex;
flex-direction: column;
position: relative;
margin-top: 15px;
}

&__header {
position: relative;
Expand Down
32 changes: 32 additions & 0 deletions public/stylesheets/components/searcher.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
.searcher {

&__hidden {
display: none;
}

&__container {
display: flex;
font-size: 15px;
padding: 5px 0px;
border-bottom: 2px solid rgba(130,156,176,.42);
margin-bottom: 15px;
}

&__input {
display: flex;
width: 100%;
border: none;
color: #63758c;
background: none;
}

&__input:focus {
color: white;
outline: none;
}

}

[name='js-found-notes-menu'] span {
color: white;
}
13 changes: 13 additions & 0 deletions public/svg/search.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
47 changes: 31 additions & 16 deletions src/views/aside.pug
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@

.aside-swiper__left

//-
//- Search
//-
.searcher__container
input.searcher__input(value="Search")
include ../../public/svg/search.svg


//-
//- Header
//-
Expand All @@ -19,28 +27,35 @@
.aside__scrollable
.aside__scrollable-content(name="js-scrollable")

.aside__section-title Folders
.aside__content-wrap(name="js-folders-container")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

проверить скролл

.aside__section-title Folders

section#folders-section
section#folders-section

.notes-list
ul.notes-list__content(name="js-folders-menu")
.notes-list
ul.notes-list__content(name="js-folders-menu")

.aside__add-button(name="js-new-folder-button")
include ../../public/svg/plus.svg
| Add folder
.aside__add-button(name="js-new-folder-button")
include ../../public/svg/plus.svg
| Add folder

fieldset.aside__input.hide(name="js-new-folder-field")
input(placeholder="Enter title", type="text")
include ../../public/svg/arrow-right.svg
fieldset.aside__input.hide(name="js-new-folder-field")
input(placeholder="Enter title", type="text")
include ../../public/svg/arrow-right.svg

.aside__section-title Notes
.aside__content-wrap(name="js-notes-container")
.aside__section-title Notes

.notes-list
ul.notes-list__content(name="js-notes-menu")
//-
//- div.notes-list__scroll
//-
.notes-list
ul.notes-list__content(name="js-notes-menu")
//-
//- div.notes-list__scroll
//-
ul.notes-list__content(name="js-found-notes-menu", tabindex="0")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

скрывать поиск после очистки инпута

//-
//- div.notes-list__scroll
//-



.aside-swiper__right
Expand Down