Update filter

This commit is contained in:
2024-10-26 03:52:54 +03:00
parent 2c6d0ac34f
commit cca3c2256d
27 changed files with 699 additions and 195 deletions

62
docs/source/conf.py Normal file
View File

@@ -0,0 +1,62 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
# -- Project information -----------------------------------------------------
project = 'myapp'
copyright = 'RemiZOffAlex'
author = 'RemiZOffAlex'
# The full version, including alpha/beta/rc tags
release = '0.2'
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = 'ru'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = []
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'classic'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']

View File

@@ -0,0 +1,9 @@
__author__ = 'RemiZOffAlex'
__copyright__ = '(c) RemiZOffAlex'
__email__ = 'remizoffalex@mail.ru'
from . import ( # noqa F401
common,
favorite
)

View File

@@ -1,9 +1,9 @@
__author__ = 'RemiZOffAlex'
__email__ = 'remizoffalex@mail.ru'
from . import jsonrpc, login_required
from .. import app, lib, models
from ..mutations.page import page_as_dict
from .. import jsonrpc, login_required
from ... import app, lib, models
from ...mutations.page import page_as_dict
@jsonrpc.method('page')
@@ -68,7 +68,7 @@ def page_destroy(id: int) -> bool:
@jsonrpc.method('page.update')
@login_required
def page_update(id: int, title: str, text: str) -> dict:
def page_update(id: int, title: str, body: str) -> dict:
"""Обновить статью
"""
page = models.db_session.query(
@@ -80,13 +80,10 @@ def page_update(id: int, title: str, text: str) -> dict:
raise ValueError
page.title = title
page.text = text
page.body = body
models.db_session.commit()
result = page.as_dict()
result['user'] = page.user.as_dict()
result['tags'] = []
for tagLink in page.tags:
result['tags'].append(tagLink.tag.as_dict())
result = page_as_dict(page)
return result

View File

@@ -0,0 +1,55 @@
__author__ = 'RemiZOffAlex'
__email__ = 'remizoffalex@mail.ru'
from .. import jsonrpc, login_required
from ... import acl, app, lib, models
from ...mutations.page import page_as_dict
@jsonrpc.method('page.favorite.add')
@login_required
def page_favorite_add(id: int) -> bool:
"""Добавление статьи в избранное
"""
page = models.db_session.query(
models.Page
).filter(
models.Page.id == id
).first()
if page is None:
raise ValueError
exist = models.db_session.query(
models.PageFavorite
).filter(
models.PageFavorite.page_id == id,
models.PageFavorite.user_id == lib.get_user().id
).first()
if exist:
raise ValueError
new_favorite_page = models.PageFavorite(
lib.get_user(),
page
)
models.db_session.add(new_favorite_page)
models.db_session.commit()
return True
@jsonrpc.method('page.favorite.delete')
@login_required
def page_favorite_delete(id: int) -> bool:
"""Удаление статьи из избранного
"""
exist = models.db_session.query(
models.PageFavorite
).filter(
models.PageFavorite.page_id == id,
models.PageFavorite.user_id == lib.get_user().id
).first()
if exist is None:
raise ValueError
models.db_session.delete(exist)
models.db_session.commit()
return True

View File

@@ -1,7 +1,7 @@
function PanelFilter() {
let data = {
visible: false,
value: '',
visible: true,
isregex: false,
};
function filter_clear() {
@@ -20,12 +20,37 @@ function PanelFilter() {
}
};
return {
data: data,
oninit: function(vnode) {
console.log('PanelFilter.oninit');
for (let key in vnode.attrs){
data[key] = vnode.attrs[key];
console.log(key, vnode.attrs[key]);
// data[key] = vnode.attrs[key];
Object.defineProperty(data, key, {
get() {
return vnode.attrs[key]
},
set(value) {
vnode.attrs[key] = value
},
});
};
console.log(data);
},
onbeforeupdate: function (vnode) {
console.log('PanelFilter.onbeforeupdate');
for (let key in vnode.attrs){
console.log(key, vnode.attrs[key]);
// data[key] = vnode.attrs[key];
Object.defineProperty(data, key, {
get() {
return vnode.attrs[key]
},
set(value) {
vnode.attrs[key] = value
},
});
};
console.log(data);
},
view: function() {
console.log('PanelFilter.view');

View File

@@ -4,3 +4,4 @@
{% include '/components/info.js' %}
{% include '/components/order_by.js' %}
{% include '/components/pagination.js' %}
{% include '/components/tag_short.js' %}

View File

@@ -0,0 +1,67 @@
function TagShort() {
let data = {
tag: null,
};
return {
oninit: function(vnode) {
console.log('TagShort.oninit');
for (let key in vnode.attrs){
data[key] = vnode.attrs[key];
};
},
onbeforeupdate: function(vnode) {
console.log('TagShort.onbeforeupdate');
for (let key in vnode.attrs){
data[key] = vnode.attrs[key];
};
},
view: function(vnode) {
console.log('TagShort.view');
console.log(data);
if (data.tag!=null) {
return [
m('i', {class: 'fa fa-tag me-1'}),
m(m.route.Link, {class: "text-decoration-none me-2", href: `/tag/${data.tag.id}`}, data.tag.name),
]
}
}
}
};
function TagsShort() {
let data = {
tags: null,
};
function tag_render(tag, tagIdx) {
return [
m('i', {class: 'fa fa-tag me-1'}),
m(m.route.Link, {class: "text-decoration-none font-monospace me-2", href: `/tag/${tag.id}`}, tag.name),
]
};
function tags_render() {
return data.tags.map(tag_render);
};
return {
oninit: function(vnode) {
console.log('TagsShort.oninit');
for (let key in vnode.attrs){
data[key] = vnode.attrs[key];
};
},
onbeforeupdate: function(vnode) {
console.log('TagsShort.onbeforeupdate');
for (let key in vnode.attrs){
data[key] = vnode.attrs[key];
};
},
view: function(vnode) {
console.log('TagsShort.view');
if (data.tags!=null) {
return m('div', {class: 'row'},
m('div', {class: 'col text-muted py-2'},
m('small', tags_render())
)
);
}
}
}
};

View File

@@ -7,25 +7,11 @@ function ComponentPages() {
if (pageIdx % 2) {
odd = ' bg-light'
};
let tags = page.tags.map(
function(tag, tagIdx) {
return [
m('i', {class: "fa fa-tag"}),
{tag: '<', children: '&nbsp;'},
m(m.route.Link, {class: "font-monospace text-decoration-none", href: `/tag/${tag.id}`}, tag.name),
{tag: '<', children: '&nbsp;'},
]
}
);
return m('div', {class: 'row'},
m('div', {class: "col py-2" + odd}, [
m(m.route.Link, {class: "text-decoration-none", href: `/page/${page.id}`}, m.trust(page.title)),
m('div', {class: 'row'},
m('div', {class: 'col text-muted'},
m('small', [...tags])
)
)
m(TagsShort, { tags: page.tags }),
])
)
};
@@ -39,8 +25,8 @@ function ComponentPages() {
data[key] = vnode.attrs[key];
};
},
onupdate: function(vnode) {
console.log('ComponentPages.onupdate');
onbeforeupdate: function(vnode) {
console.log('ComponentPages.onbeforeupdate');
for (let key in vnode.attrs){
data[key] = vnode.attrs[key];
};

View File

@@ -1,6 +1,10 @@
function FavoriteNotes() {
let data = {
filter: PanelFilter(),
filter: {
value: '',
isregex: false,
visible: false
},
order_by: PanelOrderBy({
field: 'updated',
fields: [
@@ -92,7 +96,7 @@ function FavoriteNotes() {
m('div', {class: 'col h1 py-2'}, [
m('div', {class: "btn-group btn-group-lg me-2"}, [
m(m.route.Link, {class: "btn btn-outline-secondary", href: '/favorite', title: "Вернуться"}, m('i', {class: "fa fa-chevron-left"})),
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.filter.data) }},
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.filter) }},
m('i', {class: "fa fa-filter"})
),
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.order_by.data) }},
@@ -104,11 +108,11 @@ function FavoriteNotes() {
),
m('hr'),
m(MenuFavorite, {menuitem: 'notes'}),
m(PanelFilter, data.filter),
m(data.order_by),
m(Pagination, data.pagination),
);
result.push(m(data.filter));
result.push(m(data.order_by));
result.push(m(Pagination, data.pagination));
if (data.notes.length>0) {
result.push(m(ComponentNotes, {notes: data.notes}));
result.push(m(Pagination, data.pagination));

View File

@@ -1,6 +1,10 @@
function FavoritePages() {
let data = {
filter: PanelFilter(),
filter: {
value: '',
isregex: false,
visible: false
},
order_by: PanelOrderBy({
field: 'updated',
fields: [
@@ -92,7 +96,7 @@ function FavoritePages() {
m('div', {class: 'col h1 py-2'}, [
m('div', {class: "btn-group btn-group-lg me-2"}, [
m(m.route.Link, {class: "btn btn-outline-secondary", href: '/favorite', title: "Вернуться"}, m('i', {class: "fa fa-chevron-left"})),
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.filter.data) }},
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.filter) }},
m('i', {class: "fa fa-filter"})
),
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.order_by.data) }},
@@ -104,11 +108,11 @@ function FavoritePages() {
),
m('hr'),
m(MenuFavorite, {menuitem: 'pages'}),
m(PanelFilter, data.filter),
m(data.order_by),
m(Pagination, data.pagination),
);
result.push(m(data.filter));
result.push(m(data.order_by));
result.push(m(Pagination, data.pagination));
if (data.pages.length>0) {
result.push(m(ComponentPages, {pages: data.pages}));
result.push(m(Pagination, data.pagination));

View File

@@ -1,6 +1,10 @@
function Notes() {
let data = {
filter: PanelFilter(),
filter: {
value: '',
isregex: false,
visible: false
},
order_by: PanelOrderBy({
field: 'title',
fields: [
@@ -86,7 +90,7 @@ function Notes() {
m('div', {class: 'col py-2 h1'}, [
m(m.route.Link, {class: 'btn btn-outline-success btn-lg float-end', href: '/note/add'}, m('i', {class: 'fa fa-plus'})),
m('div', {class: "btn-group btn-group-lg me-2"}, [
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.filter.data) }},
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.filter) }},
m('i', {class: "fa fa-filter"})
),
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.order_by.data) }},
@@ -96,11 +100,11 @@ function Notes() {
'Мои заметки',
])
),
m('hr')
m('hr'),
m(PanelFilter, data.filter),
m(data.order_by),
m(Pagination, data.pagination),
]);
result.push(m(data.filter));
result.push(m(data.order_by));
result.push(m(Pagination, data.pagination));
if (data.notes.length>0) {
result.push(m(ComponentNotes, {notes: data.notes}));
result.push(m(Pagination, data.pagination));

View File

@@ -0,0 +1,193 @@
function PageEdit() {
let data = {
uuid: get_id(),
page: null,
panels: {
standart: {
visible: false
}
},
editor: null,
};
function breadcrumbs_render() {
let result = m('ul', {class: 'breadcrumb mt-2'}, [
m('li', {class: 'breadcrumb-item'}, m(m.route.Link, {href: '/'}, m('i', {class: 'fa fa-home'}))),
m('li', {class: 'breadcrumb-item'}, m(m.route.Link, {href: '/pages'}, 'Список статей')),
m('li', {class: 'breadcrumb-item'}, m(m.route.Link, {href: `/page/${data.page.id}`}, data.page.title)),
m('li', {class: 'breadcrumb-item active'}, 'Редактирование страницы'),
]);
return result;
};
function page_get(id) {
m.request({
url: '/api',
method: "POST",
body: {
"jsonrpc": "2.0",
"method": 'page',
"params": {
"id": id,
"fields": ["id", "title", "body"]
},
"id": get_id()
}
}).then(
function(response) {
if ('result' in response) {
data.page = response['result'];
} else if ('error' in response) {
bus.emit('notify', {
title: 'Редактирование статьи',
body: response['error'].message,
typeOf: 'danger'
})
}
}
)
};
function apply() {
/* Сохранить */
if (data.page.title.length<2) {
return;
};
m.request({
url: '/api',
method: "POST",
body: {
"jsonrpc": "2.0",
"method": "page.update",
"params": {
"id": data.page.id,
"title": data.page.title,
"body": data.page.body
},
"id": get_id()
}
}).then(
function(response) {
if ('result' in response) {
}
}
);
};
function apply_and_close() {
/* Сохранить */
if (data.page.title.length<2) {
return;
};
m.request({
url: '/api',
method: "POST",
body: {
"jsonrpc": "2.0",
"method": "page.update",
"params": {
"id": data.page.id,
"title": data.page.title,
"body": data.page.body
},
"id": get_id()
}
}).then(
function(response) {
if ('result' in response) {
m.route.set(`/page/${data.page.id}`);
}
}
);
};
function form_submit(e) {
e.preventDefault();
apply_and_close();
};
function editor_events(ed) {
ed.on('change', function (e) {
data.page.body = ed.getContent();
});
};
return {
oncreate(vnode) {
console.log('PageEdit.oncreate');
if (data.page!=null) {
console.log(data.page);
if (data.editor==null) {
tinymce_config = tinymce_config_init();
tinymce_config.selector = `#page_body_${data.uuid}`;
tinymce_config.setup = editor_events;
tinymce.init(tinymce_config).then(
function (editors) {
data.editor = editors[0];
}
);
}
}
},
oninit: function(vnode) {
console.log('PageEdit.oninit');
page_get(vnode.attrs.id);
},
onbeforeremove: function (vnode) {
console.log('PageAdd.onbeforeremove');
if (data.editor != null) {
data.editor.remove();
data.editor = null;
};
},
onbeforeupdate: function (vnode) {
console.log('PageEdit.onbeforeupdate');
if (data.page != null) {
if (data.page.id.toString() !== vnode.attrs.id) {
page_get(vnode.attrs.id);
};
};
},
onupdate: function(vnode) {
console.log('PageEdit.onupdate');
if (data.page!=null) {
if (data.editor == null) {
tinymce_config = tinymce_config_init();
tinymce_config.selector = `#page_body_${data.uuid}`;
tinymce_config.setup = editor_events;
tinymce.init(tinymce_config).then(
function (editors) {
data.editor = editors[0];
}
);
}
};
},
view: function(vnode) {
let result = [];
if (data.page!=null) {
result.push(
breadcrumbs_render(),
m('div', {class: 'row'},
m('div', {class: 'col h1 py-2'},
m(m.route.Link, {class: "btn btn-outline-secondary btn-lg me-2", href: `/page/${data.page.id}`, title: data.page.title}, m('i', {class: 'fa fa-chevron-left'})),
'Редактирование страницы',
)
),
m('hr'),
m('form', {onsubmit: form_submit}, [
m('div', {class: 'mb-2'}, [
m('label', {class: 'form-label'}, 'Заголовок'),
m('input', {class: 'form-control', type: 'text', oninput: function (e) {data.page.title = e.target.value}, value: data.page.title}, 'Заголовок'),
]),
m('div', {class: 'mb-2'}, [
m('label', {class: 'form-label'}, 'Текст'),
m('textarea', { class: 'form-control', cols: '40', rows: '8', id: `page_body_${data.uuid}`, oninput: function (e) {data.page.body = e.target.value}, value: data.page.body})
]),
m('div', {class: 'row'},
m('div', {class: 'col py-2 text-end'}, [
m('button', {class: 'btn btn-outline-success btn-lg me-2', type: 'button', onclick: apply}, [m('i', {class: 'fa fa-save me-2'}), 'Сохранить']),
m('button', {class: 'btn btn-outline-success btn-lg', type: 'submit'}, [m('i', {class: 'fa fa-save me-2'}), 'Сохранить и закрыть']),
])
),
])
);
result.push(breadcrumbs_render());
};
return result;
}
};
};

View File

@@ -1,11 +1,13 @@
{% include '/private/domains/page/add.js' %}
{% include '/private/domains/page/new.js' %}
{% include '/private/domains/page/edit.js' %}
{% include '/private/domains/page/page.js' %}
{% include '/private/domains/page/pages.js' %}
Object.assign(
routes,
{
"/page/add": layout_decorator(PageAdd),
"/page/add": layout_decorator(PageNew),
"/page/:id/edit": layout_decorator(PageEdit),
"/page/:id": layout_decorator(Page),
"/pages": layout_decorator(Pages),
"/pages/:page": layout_decorator(Pages),

View File

@@ -0,0 +1,64 @@
function PageMenu(arguments) {
let data = {
menuitem: null,
page: null,
};
for (let key in arguments){
data[key] = arguments[key];
};
function button_common() {
if (data.menuitem===null) {
return {tag: '<', children: '<div class="btn btn-primary me-2"><i class="fa fa-bars"></i></div>'};
} else {
return m(m.route.Link, {class: "btn btn-outline-secondary me-2 text-decoration-none", href: `/page/${data.page.id}`, title: data.page.title}, m('i', {class: 'fa fa-bars'}))
}
};
function button_briefcases() {
if (data.menuitem==='briefcases') {
return {tag: '<', children: '<div class="btn btn-primary me-2">Портфели</div>'};
} else {
return m(m.route.Link, {class: "btn btn-outline-secondary me-2 text-decoration-none", href: `/page/${data.page.id}/briefcases`}, 'Портфели')
}
};
function button_attachments() {
if (data.menuitem==='attachments') {
return {tag: '<', children: '<div class="btn btn-primary me-2">Связи</div>'};
} else {
return m(m.route.Link, {class: "btn btn-outline-secondary me-2 text-decoration-none", href: `/page/${data.page.id}/attachments`}, 'Связи')
}
};
function button_properties() {
if (data.menuitem==='properties') {
return {tag: '<', children: '<div class="btn btn-primary me-2">Свойства</div>'};
} else {
return m(m.route.Link, {class: "btn btn-outline-secondary me-2 text-decoration-none", href: `/page/${data.page.id}/properties`}, 'Свойства')
}
};
function button_details() {
if (data.menuitem==='details') {
return {tag: '<', children: '<div class="btn btn-primary me-2">Сведения</div>'};
} else {
return m(m.route.Link, {class: "btn btn-outline-secondary me-2 text-decoration-none", href: `/page/${data.page.id}/details`}, 'Сведения')
}
};
return {
oninit: function(vnode) {
console.log('PageMenu.oninit');
for (let key in vnode.attrs){
data[key] = vnode.attrs[key];
};
},
view: function(vnode) {
console.log('PageMenu.view');
return m('div', {class: 'row'},
m('div', {class: 'col py-2'}, [
button_common(),
button_briefcases(),
button_attachments(),
button_properties(),
button_details(),
])
)
}
}
};

View File

@@ -1,5 +1,6 @@
function PageAdd() {
function PageNew() {
let data = {
uuid: get_id(),
page: {
title: '',
body: '',
@@ -22,7 +23,6 @@ function PageAdd() {
if (data.page.title.length<2) {
return;
};
tinymce_get_value();
m.request({
url: '/api',
method: "POST",
@@ -40,38 +40,43 @@ function PageAdd() {
}
)
};
function editor_events(ed) {
ed.on('change', function (e) {
data.page.body = ed.getContent();
});
};
function tinymce_remove() {
tinymce.get('page_body').remove();
};
function tinymce_get_value() {
let value = tinymce.get('page_body').getContent();
if (value != data.page.body) {
data.page.body = value;
}
};
function tinymce_set_value() {
tinymce.get('page_body').setContent(data.page.body);
};
return {
oncreate(vnode) {
console.log('PageAdd.oncreate');
if (data.editor==null) {
data.editor = tinymce_init('#page_body');
tinymce_config = tinymce_config_init();
tinymce_config.selector = `#page_body_${data.uuid}`;
tinymce_config.setup = editor_events;
tinymce.init(tinymce_config).then(
function (editors) {
data.editor = editors[0];
}
);
}
},
onbeforeremove: function(vnode) {
console.log('PageAdd.onbeforeremove');
if (data.editor!=null) {
tinymce_remove();
data.editor.remove();
data.editor = null;
};
},
view: function(vnode) {
console.log('PageAdd.view');
result = [];
result.push([
breadcrumbs_render(),
m('div', {class: 'row'},
m('div', {class: 'col py-2 h1'}, [
m(m.route.Link, {class: "btn btn-outline-secondary", href: "/pages", title: "Список статей"}, m('i', {class: 'fa fa-chevron-left'})),
m(m.route.Link, {class: "btn btn-outline-secondary btn-lg me-2", href: "/pages", title: "Список статей"}, m('i', {class: 'fa fa-chevron-left'})),
'Новая страница'
])
),
@@ -85,11 +90,11 @@ function PageAdd() {
]),
m('div', {class: 'mb-2'}, [
m('label', {class: 'form-label'}, 'Текст'),
m('textarea', {class: 'form-control', cols: '40', rows: '8', id: 'page_body', oninput: function (e) {data.page.body = e.target.value}, value: data.page.body})
m('textarea', { class: 'form-control', cols: '40', rows: '8', id: `page_body_${data.uuid}`, oninput: function (e) {data.page.body = e.target.value}, value: data.page.body})
]),
m('div', {class: 'row'},
m('div', {class: 'col py-2'}, [
m('button', {class: 'btn btn-outline-success btn-lg float-end', type: 'submit'}, [m('i', {class: 'fa fa-save'}), ' Сохранить']),
m('button', {class: 'btn btn-outline-success btn-lg float-end', type: 'submit'}, [m('i', {class: 'fa fa-save me-2'}), 'Сохранить']),
])
),
])

View File

@@ -44,6 +44,16 @@ function Page() {
return m(m.route.Link, {class: "btn btn-outline-secondary", href: "/pages", title: "Список статей"}, m('i', {class: 'fa fa-chevron-left'}));
}
};
function panels_standart_render() {
if (data.panels.standart.visible) {
return m('div', { class: 'row' },
m('div', { class: 'col py-2' }, [
m(ComponentFavorite, { resource: data.page, name: 'page' }),
m(m.route.Link, { class: 'btn btn-outline-secondary me-2', href: `/page/${data.page.id}/edit`, title: 'Редактировать' }, m('i', { class: 'fa fa-edit' })),
])
);
}
};
return {
oninit: function(vnode) {
console.log('Page.oninit');
@@ -72,7 +82,9 @@ function Page() {
m.trust(data.page.title),
])
),
panels_standart_render(),
m('hr'),
m(ComponentTags, { resource: data.page, typeOf: 'page' }),
);
result.push(m.trust(data.page.body));
result.push(breadcrumbs_render());

View File

@@ -1,6 +1,10 @@
function Pages() {
let data = {
filter: PanelFilter(),
filter: {
value: '',
isregex: false,
visible: false
},
order_by: PanelOrderBy({
field: 'title',
fields: [
@@ -17,10 +21,12 @@ function Pages() {
let result = data.raw_pages.filter(page_filter);
return result;
},
pagination: Pagination({
clickHandler: pages_get,
pagination: {
page: 1,
size: 0,
// clickHandler: pages_get,
prefix_url: '/pages'
}),
},
};
function breadcrumbs_render() {
let result = m('ul', {class: 'breadcrumb mt-3'}, [
@@ -30,18 +36,26 @@ function Pages() {
return result;
};
function page_filter(page) {
let filter = data.filter.data;
let filter = data.filter;
let value = filter.value;
if (value.length < 1) {
return true;
}
if (page.title.toLowerCase().includes(value.toLowerCase())) {
let isTitle = null;
if (data.filter.isregex) {
let regex = new RegExp(value, 'ig');
isTitle = regex.test(page.title.toLowerCase());
} else {
isTitle = page.title.toLowerCase().includes(value.toLowerCase());
}
if (isTitle > 0) {
return true;
}
return false;
};
function pages_get() {
let pagination = data.pagination.data;
m.request({
url: '/api',
method: "POST",
@@ -50,19 +64,19 @@ function Pages() {
"jsonrpc": "2.0",
"method": 'pages',
"params": {
"page": pagination.page,
"page": data.pagination.page,
"order_by": {
"field": data.order_by.data.field,
'order': data.order_by.data.order
},
"fields": ["id", "title", "tags"]
},
"id": 1
"id": get_id()
},
{
"jsonrpc": "2.0",
"method": 'pages.count',
"id": 1
"id": get_id()
}
]
@@ -77,24 +91,9 @@ function Pages() {
}
);
};
function page_render(page, pageIdx) {
let odd = '';
if (pageIdx % 2) {
odd = ' bg-light'
};
return m('div', {class: 'row'},
m('div', {class: `col py-2 ${odd}`}, [
m(m.route.Link, {href: `/page/${page.id}`}, m.trust(page.title)),
m('div', {class: 'row'},
),
])
);
};
function pages_render() {
return data.pages.map(page_render);
};
return {
oninit: function(vnode) {
console.log('Pages.oninit');
let pagination = data.pagination.data;
if (vnode.attrs.page!==undefined) {
pagination.page = Number(vnode.attrs.page);
@@ -102,7 +101,11 @@ function Pages() {
document.title = `Список статей - ${SETTINGS.TITLE}`;
pages_get();
},
onbeforeupdate: function (vnode) {
console.log('Pages.onbeforeupdate');
},
view: function(vnode) {
console.log('Pages.view');
let result = [];
result.push(
breadcrumbs_render(),
@@ -110,7 +113,7 @@ function Pages() {
m('div', {class: 'col h1 py-1'}, [
m(m.route.Link, {class: "btn btn-outline-success btn-lg float-end", href: "/page/add", title: "Добавить статью"}, m('i', {class: 'fa fa-plus'})),
m('div', {class: "btn-group btn-group-lg me-2"}, [
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.filter.data) }},
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.filter) }},
m('i', {class: "fa fa-filter"})
),
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.order_by.data) }},
@@ -118,16 +121,18 @@ function Pages() {
)
]),
'Статьи',
{tag: '<', children: '<hr />'}
])
)
),
m('hr'),
m(PanelFilter, data.filter),
m(data.order_by),
m(Pagination, data.pagination),
);
result.push(m(data.filter));
result.push(m(data.order_by));
result.push(m(data.pagination));
if (data.pages.length>0) {
result.push(m(ComponentPages, {pages: data.pages}));
result.push(m(data.pagination));
result.push(
m(ComponentPages, {pages: data.pages}),
m(Pagination, data.pagination)
);
};
result.push(breadcrumbs_render());
return result

View File

@@ -1,6 +1,10 @@
function TagNotes() {
let data = {
filter: PanelFilter(),
filter: {
value: '',
isregex: false,
visible: false
},
order_by: PanelOrderBy({
field: 'title',
fields: [
@@ -34,7 +38,7 @@ function TagNotes() {
return result;
};
function note_filter(note) {
let filter = data.filter.data;
let filter = data.filter;
let value = filter.value;
if ( value.length<1 ) {
return true;
@@ -131,7 +135,7 @@ function TagNotes() {
m('div', {class: 'col h1 py-2'}, [
m('div', {class: "btn-group btn-group-lg me-2"}, [
m(m.route.Link, {class: "btn btn-outline-secondary", href: `/tag/${data.tag.id}`, title: "Вернуться"}, m('i', {class: "fa fa-chevron-left"})),
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.filter.data) }},
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.filter) }},
m('i', {class: "fa fa-filter"})
),
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.order_by.data) }},
@@ -141,15 +145,15 @@ function TagNotes() {
`Статьи с тегом [${data.tag.name}]`
]),
),
m('hr')
m('hr'),
// m(MenuTag, {menuitem: 'notes', tag: data.tag}),
{tag: MenuTag, attrs: {menuitem: 'notes', tag: data.tag}},
m(PanelFilter, data.filter),
m(data.order_by),
m(Pagination, data.pagination),
);
// result.push(m(MenuTag, {menuitem: 'notes', tag: data.tag}));
result.push({tag: MenuTag, attrs: {menuitem: 'notes', tag: data.tag}});
result.push(m(data.filter));
result.push(m(data.order_by));
result.push(m(Pagination, data.pagination));
if (data.notes.length>0) {
result.push(m(ComponentNotes, {notes: data.notes}));
result.push(m(Pagination, data.pagination));

View File

@@ -1,6 +1,10 @@
function TagPages() {
let data = {
filter: PanelFilter(),
filter: {
value: '',
isregex: false,
visible: false
},
order_by: PanelOrderBy({
field: 'title',
fields: [
@@ -34,7 +38,7 @@ function TagPages() {
return result;
};
function page_filter(page) {
let filter = data.filter.data;
let filter = data.filter;
let value = filter.value;
if ( value.length<1 ) {
return true;
@@ -131,7 +135,7 @@ function TagPages() {
m('div', {class: 'col h1 py-2'}, [
m('div', {class: "btn-group btn-group-lg me-2"}, [
m(m.route.Link, {class: "btn btn-outline-secondary", href: `/tag/${data.tag.id}`, title: "Вернуться"}, m('i', {class: "fa fa-chevron-left"})),
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.filter.data) }},
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.filter) }},
m('i', {class: "fa fa-filter"})
),
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.order_by.data) }},
@@ -141,15 +145,15 @@ function TagPages() {
`Статьи с тегом [${data.tag.name}]`
]),
),
m('hr')
m('hr'),
// m(MenuTag, {menuitem: 'pages', tag: data.tag}),
{tag: MenuTag, attrs: {menuitem: 'pages', tag: data.tag}},
m(data.filter),
m(data.order_by),
m(Pagination, data.pagination),
);
// result.push(m(MenuTag, {menuitem: 'pages', tag: data.tag}));
result.push({tag: MenuTag, attrs: {menuitem: 'pages', tag: data.tag}});
result.push(m(data.filter));
result.push(m(data.order_by));
result.push(m(Pagination, data.pagination));
if (data.pages.length>0) {
result.push(m(ComponentPages, {pages: data.pages}));
result.push(m(Pagination, data.pagination));

View File

@@ -1,6 +1,10 @@
function Tags() {
let data = {
filter: PanelFilter(),
filter: {
value: '',
isregex: false,
visible: false
},
raw_groups: {},
get groups() {
let result = {};
@@ -29,7 +33,7 @@ function Tags() {
return result;
};
function tag_filter(tag) {
let filter = data.filter.data;
let filter = data.filter;
let value = filter.value;
if ( value.length<1 ) {
return true;
@@ -115,7 +119,7 @@ function Tags() {
breadcrumbs_render(),
m('div', {class: 'row'},
m('div', {class: 'col h1 py-2'}, [
m('button', {type: "button", class: "btn btn-outline-secondary btn-lg me-2", onclick: function() { panel_show(data.filter.data) }},
m('button', {type: "button", class: "btn btn-outline-secondary btn-lg me-2", onclick: function() { panel_show(data.filter) }},
m('i', {class: "fa fa-filter"})
),
m('button', {class: 'btn btn-outline-success btn-lg float-end', onclick: function() { panel_show(data.panels.tag_new) }}, m('i', {class: 'fa fa-plus'})),
@@ -123,9 +127,9 @@ function Tags() {
])
),
m('hr'),
m(PanelFilter, data.filter),
form_tag_new_render(),
);
result.push(m(data.filter));
result.push(form_tag_new_render());
if (Object.keys(data.groups).length>0) {
let groups = [];
Object.keys(data.groups).forEach(

View File

@@ -1,6 +1,10 @@
function Users() {
let data = {
filter: PanelFilter(),
filter: {
value: '',
isregex: false,
visible: false
},
order_by: PanelOrderBy({
field: 'name',
fields: [
@@ -15,11 +19,11 @@ function Users() {
raw_users: [],
get users() {
/* Отфильтрованный список */
let value = data.filter.data.value;
let value = data.filter.value;
if ( value.length<1 ) {
return data.raw_users;
}
if (data.filter.data.isregex) {
if (data.filter.isregex) {
try {
let regex = new RegExp(value, 'ig');
} catch (e) {
@@ -37,12 +41,12 @@ function Users() {
};
function user_filter(user) {
/* Фильтр статей */
let value = data.filter.data.value;
let value = data.filter.value;
if ( value.length<1 ) {
return true;
}
let isTitle = null;
if ( data.filter.data.isregex) {
if ( data.filter.isregex) {
let regex = new RegExp(value, 'ig');
isTitle = regex.test(user.name.toLowerCase());
} else {
@@ -130,7 +134,7 @@ function Users() {
m('div', {class: 'row'},
m('div', {class: 'col h1 py-1'}, [
m('div', {class: "btn-group btn-group-lg me-2"}, [
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.filter.data) }},
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.filter) }},
m('i', {class: "fa fa-filter"})
),
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.order_by.data) }},
@@ -141,10 +145,10 @@ function Users() {
])
),
m('hr'),
m(PanelFilter, data.filter),
m(data.order_by),
m(data.pagination),
);
result.push(m(data.filter));
result.push(m(data.order_by));
result.push(m(data.pagination));
if (data.users.length>0) {
result.push(m(ComponentUsers, {users: data.users}));
result.push(m(data.pagination));

View File

@@ -39,8 +39,8 @@ function ComponentPages() {
data[key] = vnode.attrs[key];
};
},
onupdate: function(vnode) {
console.log('ComponentPages.onupdate');
onbeforeupdate: function(vnode) {
console.log('ComponentPages.onbeforeupdate');
for (let key in vnode.attrs){
data[key] = vnode.attrs[key];
};

View File

@@ -73,9 +73,10 @@ function Page() {
])
),
m('hr'),
m(TagsShort, { tags: data.page.tags }),
m.trust(data.page.body),
breadcrumbs_render()
);
result.push(m.trust(data.page.body));
result.push(breadcrumbs_render());
};
return result
}

View File

@@ -1,6 +1,10 @@
function Pages() {
let data = {
filter: PanelFilter(),
filter: {
value: '',
isregex: false,
visible: false
},
order_by: PanelOrderBy({
field: 'title',
fields: [
@@ -15,11 +19,12 @@ function Pages() {
raw_pages: [],
get pages() {
/* Отфильтрованный список */
let value = data.filter.data.value;
if ( value.length<1 ) {
let value = data.filter.value;
console.log('Pages.value get', data.filter.value)
if (value.length<1 ) {
return data.raw_pages;
}
if (data.filter.data.isregex) {
if (data.filter.isregex) {
try {
let regex = new RegExp(value, 'ig');
} catch (e) {
@@ -37,12 +42,12 @@ function Pages() {
};
function page_filter(page) {
/* Фильтр статей */
let value = data.filter.data.value;
let value = data.filter.value;
if ( value.length<1 ) {
return true;
}
let isTitle = null;
if ( data.filter.data.isregex) {
if ( data.filter.isregex) {
let regex = new RegExp(value, 'ig');
isTitle = regex.test(page.title.toLowerCase());
} else {
@@ -111,9 +116,6 @@ function Pages() {
])
);
};
function pages_render() {
return data.pages.map(page_render);
};
return {
oninit: function(vnode) {
let pagination = data.pagination.data;
@@ -130,7 +132,7 @@ function Pages() {
m('div', {class: 'row'},
m('div', {class: 'col h1 py-1'}, [
m('div', {class: "btn-group btn-group-lg me-2"}, [
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.filter.data) }},
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.filter) }},
m('i', {class: "fa fa-filter"})
),
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.order_by.data) }},
@@ -141,10 +143,10 @@ function Pages() {
])
),
m('hr'),
m(PanelFilter, data.filter),
m(data.order_by),
m(Pagination, data.pagination),
);
result.push(m(data.filter));
result.push(m(data.order_by));
result.push(m(data.pagination));
if (data.pages.length>0) {
result.push(m(ComponentPages, {pages: data.pages}));
result.push(m(data.pagination));
@@ -154,27 +156,3 @@ function Pages() {
}
}
};
/*
<div class="row" v-for="() in pages">
<div class="col py-2" :class="{'bg-light': pageIdx % 2}">
<a :href="'/page/' + page.id">{ page.title }</a>
<div class="row">
<div class="col small text-muted">
<span v-for="(tag, tagIdx) in page.tags">
<i class="fa fa-tag"></i> <a class="text-monospace" :href="'/tag/' + tag.id">{ tag.name }</a>&nbsp;
</span>
</div>
</div>
<div class="row">
<div class="col small text-muted">
<i class="fa fa-user"></i> <a :href="'/user/' + page.user.id">{ page.user.name }</a>&nbsp;
Создано: { page.created }&nbsp;
Обновлено: { page.updated }
</div>
</div>
</div>
</div>
*/

View File

@@ -1,6 +1,10 @@
function TagPages() {
let data = {
filter: PanelFilter(),
filter: {
value: '',
isregex: false,
visible: false
},
order_by: PanelOrderBy({
field: 'title',
fields: [
@@ -34,7 +38,7 @@ function TagPages() {
return result;
};
function page_filter(page) {
let filter = data.filter.data;
let filter = data.filter;
let value = filter.value;
if ( value.length<1 ) {
return true;
@@ -131,7 +135,7 @@ function TagPages() {
m('div', {class: 'col h1 py-2'}, [
m('div', {class: "btn-group btn-group-lg me-2"}, [
m(m.route.Link, {class: "btn btn-outline-secondary", href: `/tag/${data.tag.id}`, title: "Вернуться"}, m('i', {class: "fa fa-chevron-left"})),
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.filter.data) }},
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.filter) }},
m('i', {class: "fa fa-filter"})
),
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.order_by.data) }},
@@ -141,15 +145,15 @@ function TagPages() {
`Статьи с тегом [${data.tag.name}]`
]),
m('hr'),
)
),
{tag: MenuTag, attrs: {menuitem: 'pages', tag: data.tag}},
m(PanelFilter, data.filter),
m(data.order_by),
m(Pagination, data.pagination),
);
// result.push(m(MenuTag, {menuitem: 'pages', tag: data.tag}));
result.push({tag: MenuTag, attrs: {menuitem: 'pages', tag: data.tag}});
result.push(m(data.filter));
result.push(m(data.order_by));
result.push(m(Pagination, data.pagination));
if (data.pages.length>0) {
result.push(m(ComponentPages, {pages: data.pages}));
result.push(m(Pagination, data.pagination));

View File

@@ -1,6 +1,10 @@
function Tags() {
let data = {
filter: PanelFilter(),
filter: {
value: '',
isregex: false,
visible: false
},
raw_groups: {},
get groups() {
let result = {};
@@ -23,7 +27,7 @@ function Tags() {
return result;
};
function tag_filter(tag) {
let filter = data.filter.data;
let filter = data.filter;
let value = filter.value;
if (value.length < 1) {
return true;
@@ -64,15 +68,15 @@ function Tags() {
breadcrumbs_render(),
m('div', { class: 'row' },
m('div', { class: "col h1 py-2" }, [
m('button', { type: "button", class: "btn btn-outline-secondary btn-lg me-2", onclick: function () { panel_show(data.filter.data) } },
m('button', { type: "button", class: "btn btn-outline-secondary btn-lg me-2", onclick: function () { panel_show(data.filter) } },
m('i', { class: "fa fa-filter" })
),
'Облако тегов'
])
),
m('hr'),
m(PanelFilter, data.filter),
);
result.push(m(data.filter));
if (Object.keys(data.groups).length > 0) {
let groups = [];
Object.keys(data.groups).forEach(

View File

@@ -1,7 +1,11 @@
function Users() {
document.title = `Список пользователей - ${SETTINGS.TITLE}`;
let data = {
filter: PanelFilter(),
filter: {
value: '',
isregex: false,
visible: false
},
order_by: PanelOrderBy({
field: 'name',
fields: [
@@ -16,11 +20,11 @@ function Users() {
raw_users: [],
get users() {
/* Отфильтрованный список */
let value = data.filter.data.value;
let value = data.filter.value;
if ( value.length<1 ) {
return data.raw_users;
}
if (data.filter.data.isregex) {
if (data.filter.isregex) {
try {
let regex = new RegExp(value, 'ig');
} catch (e) {
@@ -38,12 +42,12 @@ function Users() {
};
function user_filter(user) {
/* Фильтр статей */
let value = data.filter.data.value;
let value = data.filter.value;
if ( value.length<1 ) {
return true;
}
let isTitle = null;
if ( data.filter.data.isregex) {
if ( data.filter.isregex) {
let regex = new RegExp(value, 'ig');
isTitle = regex.test(user.name.toLowerCase());
} else {
@@ -130,7 +134,7 @@ function Users() {
m('div', {class: 'row'},
m('div', {class: 'col h1 py-1'}, [
m('div', {class: "btn-group btn-group-lg me-2"}, [
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.filter.data) }},
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.filter) }},
m('i', {class: "fa fa-filter"})
),
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.order_by.data) }},
@@ -141,13 +145,15 @@ function Users() {
])
),
m('hr'),
m(PanelFilter, data.filter),
m(data.order_by),
m(Pagination, data.pagination),
);
result.push(m(data.filter));
result.push(m(data.order_by));
result.push(m(data.pagination));
if (data.users.length>0) {
result.push(m(ComponentUsers, {users: data.users}));
result.push(m(data.pagination));
result.push(
m(ComponentUsers, {users: data.users}),
m(Pagination, data.pagination),
);
};
result.push(breadcrumbs_render());
return result