Update
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
{% if user %}
|
||||
{% extends "/public/skeleton.html" %}
|
||||
{% else %}
|
||||
{% extends "/private/skeleton.html" %}
|
||||
{% else %}
|
||||
{% extends "/public/skeleton.html" %}
|
||||
{% endif %}
|
||||
{% block content %}
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
function tinymce_init(id) {
|
||||
let result = tinymce.init({
|
||||
selector: id,
|
||||
function tinymce_config_init() {
|
||||
return {
|
||||
selector: '',
|
||||
height: 400,
|
||||
language: 'ru',
|
||||
plugins: 'anchor autolink charmap code directionality fullscreen image importcss link lists media pagebreak preview save searchreplace table visualblocks visualchars',
|
||||
toolbar: 'code | undo redo | styles blocks | bold italic underline strikethrough removeformat | alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist | pagebreak | fullscreen | link image anchor charmap',
|
||||
plugins: 'anchor autolink charmap code directionality fullscreen image importcss link lists media pagebreak preview save searchreplace table visualblocks visualchars nonbreaking',
|
||||
toolbar: 'code | undo redo | styles blocks | bold italic underline strikethrough removeformat | alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist | pagebreak | fullscreen | link image anchor charmap | nonbreaking',
|
||||
|
||||
font_family_formats: 'Liberation Sans=Liberation Sans; Mono=Liberation Mono;',
|
||||
formats: {
|
||||
@@ -26,18 +26,24 @@ function tinymce_init(id) {
|
||||
{ title: 'Примечание', format: 'note' },
|
||||
{ title: 'Внимание', format: 'danger' },
|
||||
],
|
||||
content_css: '/static/css/tinymce-code.css',
|
||||
content_css: `${SETTINGS.STATIC}/css/tinymce-code.css`,
|
||||
relative_urls: false,
|
||||
convert_urls: false,
|
||||
// Table
|
||||
table_default_attributes: {},
|
||||
table_default_styles: {},
|
||||
table_class_list: [
|
||||
{title: 'default', value: 'table'},
|
||||
{title: 'None', value: ''},
|
||||
{ title: 'default', value: 'table' },
|
||||
{ title: 'None', value: '' },
|
||||
],
|
||||
});
|
||||
return result;
|
||||
setup: function (ed) {
|
||||
ed.on('change', function (e) {
|
||||
console.log('the event object ', e);
|
||||
console.log('the editor object ', ed);
|
||||
console.log('the content ', ed.getContent());
|
||||
});
|
||||
},
|
||||
};
|
||||
};
|
||||
function tinymce_remove(id) {
|
||||
tinymce.get(id).remove();
|
||||
|
||||
71
src/myapp/templates/private/components/favorite.js
Normal file
71
src/myapp/templates/private/components/favorite.js
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
Пример
|
||||
|
||||
m(ComponentFavorite, {resource: data.journal, name: 'journal'})
|
||||
*/
|
||||
function ComponentFavorite(arguments) {
|
||||
let data = {
|
||||
resource: null,
|
||||
name: null
|
||||
};
|
||||
function favorite_add() {
|
||||
/* Добавить журнал в Избранное */
|
||||
m.request({
|
||||
url: '/api',
|
||||
method: "POST",
|
||||
body: {
|
||||
"jsonrpc": "2.0",
|
||||
"method": `${data.name}.favorite.add`,
|
||||
"params": {
|
||||
"id": data.resource.id
|
||||
},
|
||||
"id": get_id()
|
||||
}
|
||||
}).then(
|
||||
function(response) {
|
||||
if ('result' in response) {
|
||||
data.resource.favorite = true;
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
function favorite_delete() {
|
||||
/* Удалить журнал из Избранного */
|
||||
m.request({
|
||||
url: '/api',
|
||||
method: "POST",
|
||||
body: {
|
||||
"jsonrpc": "2.0",
|
||||
"method": `${data.name}.favorite.delete`,
|
||||
"params": {
|
||||
"id": data.resource.id
|
||||
},
|
||||
"id": get_id()
|
||||
}
|
||||
}).then(
|
||||
function(response) {
|
||||
if ('result' in response) {
|
||||
data.resource.favorite = false;
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
function button_favorite_render() {
|
||||
if (data.resource.favorite) {
|
||||
return m('button', {class: "btn btn-primary me-2", type: 'button', onclick: favorite_delete, title: "Удалить из избранного"}, m('i', {class: 'fa fa-star'}));
|
||||
} else {
|
||||
return m('button', {class: "btn btn-outline-secondary me-2", type: 'button', onclick: favorite_add, title: "Добавить в избранное"}, m('i', {class: 'fa fa-star-o'}));
|
||||
}
|
||||
};
|
||||
return {
|
||||
oninit: function(vnode) {
|
||||
console.log('ComponentTags.oninit');
|
||||
for (let key in vnode.attrs){
|
||||
data[key] = vnode.attrs[key];
|
||||
};
|
||||
},
|
||||
view: function(vnode) {
|
||||
return button_favorite_render();
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -1,3 +1,4 @@
|
||||
{% include '/private/components/favorite.js' %}
|
||||
{% include '/private/components/menu-general.js' %}
|
||||
{% include '/private/components/pages.js' %}
|
||||
{% include '/private/components/users.js' %}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{% include '/private/domains/page/inc.j2' %}
|
||||
{% include '/private/domains/profile/inc.j2' %}
|
||||
{% include '/private/domains/tag/inc.j2' %}
|
||||
{% include '/private/domains/user/inc.j2' %}
|
||||
{% include '/private/domains/home.js' %}
|
||||
|
||||
|
||||
176
src/myapp/templates/private/domains/tag/edit.js
Normal file
176
src/myapp/templates/private/domains/tag/edit.js
Normal file
@@ -0,0 +1,176 @@
|
||||
function TagEdit() {
|
||||
let data = {
|
||||
uuid: get_id(),
|
||||
tag: 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: '/tags'}, 'Список тегов')),
|
||||
m('li', {class: 'breadcrumb-item'}, m(m.route.Link, {href: `/tag/${data.tag.id}`}, data.tag.name)),
|
||||
m('li', {class: 'breadcrumb-item active'}, 'Редактирование тега'),
|
||||
]);
|
||||
return result;
|
||||
};
|
||||
function tag_get(id) {
|
||||
m.request({
|
||||
url: '/api',
|
||||
method: "POST",
|
||||
body: {
|
||||
"jsonrpc": "2.0",
|
||||
"method": 'tag',
|
||||
"params": {
|
||||
"id": id,
|
||||
"fields": ["id", "name", "description"]
|
||||
},
|
||||
"id": get_id()
|
||||
}
|
||||
}).then(
|
||||
function(response) {
|
||||
if ('result' in response) {
|
||||
data.tag = response['result'];
|
||||
}
|
||||
}
|
||||
)
|
||||
};
|
||||
function apply() {
|
||||
/* Сохранить */
|
||||
if (data.tag.name.length<2) {
|
||||
return;
|
||||
};
|
||||
m.request({
|
||||
url: '/api',
|
||||
method: "POST",
|
||||
body: {
|
||||
"jsonrpc": "2.0",
|
||||
"method": "tag.update",
|
||||
"params": {
|
||||
"id": data.tag.id,
|
||||
"name": data.tag.name,
|
||||
"description": data.tag.description
|
||||
},
|
||||
"id": get_id()
|
||||
}
|
||||
}).then(
|
||||
function(response) {
|
||||
if ('result' in response) {
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
function apply_and_close() {
|
||||
/* Сохранить */
|
||||
if (data.tag.name.length<2) {
|
||||
return;
|
||||
};
|
||||
m.request({
|
||||
url: '/api',
|
||||
method: "POST",
|
||||
body: {
|
||||
"jsonrpc": "2.0",
|
||||
"method": "tag.update",
|
||||
"params": {
|
||||
"id": data.tag.id,
|
||||
"name": data.tag.name,
|
||||
"description": data.tag.description
|
||||
},
|
||||
"id": get_id()
|
||||
}
|
||||
}).then(
|
||||
function(response) {
|
||||
if ('result' in response) {
|
||||
m.route.set(`/tag/${data.tag.id}`);
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
function form_submit(e) {
|
||||
e.preventDefault();
|
||||
apply_and_close();
|
||||
};
|
||||
function editor_events(ed) {
|
||||
ed.on('change', function (e) {
|
||||
data.tag.description = ed.getContent();
|
||||
});
|
||||
};
|
||||
return {
|
||||
oncreate(vnode) {
|
||||
console.log('TagEdit.oncreate');
|
||||
if (data.tag!=null) {
|
||||
console.log(data.tag);
|
||||
if (data.editor==null) {
|
||||
tinymce_config = tinymce_config_init();
|
||||
tinymce_config.selector = `#tag_description_${data.uuid}`;
|
||||
tinymce_config.setup = editor_events;
|
||||
tinymce.init(tinymce_config).then(
|
||||
function (editors) {
|
||||
data.editor = editors[0];
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
oninit: function(vnode) {
|
||||
console.log('TagEdit.oninit');
|
||||
tag_get(Number(vnode.attrs.id));
|
||||
},
|
||||
onupdate: function(vnode) {
|
||||
console.log('TagEdit.onupdate');
|
||||
if (data.tag.id !== Number(vnode.attrs.id)) {
|
||||
tag_get(Number(vnode.attrs.id));
|
||||
};
|
||||
if (data.tag!=null) {
|
||||
if (data.editor==null) {
|
||||
tinymce_config = tinymce_config_init();
|
||||
tinymce_config.selector = `#tag_description_${data.uuid}`;
|
||||
tinymce_config.setup = editor_events;
|
||||
tinymce.init(tinymce_config).then(
|
||||
function (editors) {
|
||||
data.editor = editors[0];
|
||||
}
|
||||
);
|
||||
};
|
||||
};
|
||||
},
|
||||
view: function(vnode) {
|
||||
console.log('TagEdit.view');
|
||||
let result = [];
|
||||
if (data.tag!=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: `/tag/${data.tag.id}`, title: data.tag.name}, 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.tag.name = e.target.value}, value: data.tag.name}, 'Заголовок'),
|
||||
]),
|
||||
m('div', {class: 'mb-2'}, [
|
||||
m('label', {class: 'form-label'}, 'Текст'),
|
||||
m('textarea', { class: 'form-control', cols: '40', rows: '8', id: `tag_description_${data.uuid}`, oninput: function (e) {data.tag.description = e.target.value}, value: data.tag.description})
|
||||
]),
|
||||
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'}), 'Сохранить и закрыть']),
|
||||
])
|
||||
),
|
||||
]),
|
||||
breadcrumbs_render()
|
||||
);
|
||||
};
|
||||
return result;
|
||||
}
|
||||
};
|
||||
};
|
||||
19
src/myapp/templates/private/domains/tag/inc.j2
Normal file
19
src/myapp/templates/private/domains/tag/inc.j2
Normal file
@@ -0,0 +1,19 @@
|
||||
{% include '/private/domains/tag/edit.js' %}
|
||||
{% include '/private/domains/tag/menu.js' %}
|
||||
{% include '/private/domains/tag/pages.js' %}
|
||||
{% include '/private/domains/tag/tag.js' %}
|
||||
{% include '/private/domains/tag/tags.js' %}
|
||||
{% include '/private/domains/tag/users.js' %}
|
||||
|
||||
Object.assign(
|
||||
routes,
|
||||
{
|
||||
"/tag/:id/edit": layout_decorator(TagEdit),
|
||||
"/tag/:id/pages": layout_decorator(TagPages),
|
||||
"/tag/:id/pages/:page": layout_decorator(TagPages),
|
||||
"/tag/:id/users": layout_decorator(TagUsers),
|
||||
"/tag/:id/users/:page": layout_decorator(TagUsers),
|
||||
"/tag/:id": layout_decorator(Tag),
|
||||
"/tags": layout_decorator(Tags),
|
||||
}
|
||||
);
|
||||
52
src/myapp/templates/private/domains/tag/menu.js
Normal file
52
src/myapp/templates/private/domains/tag/menu.js
Normal file
@@ -0,0 +1,52 @@
|
||||
function MenuTag() {
|
||||
let data = {
|
||||
menuitem: null,
|
||||
tag: null,
|
||||
};
|
||||
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: `/tag/${data.tag.id}`, title: data.tag.name}, m('i', {class: 'fa fa-bars'}))
|
||||
}
|
||||
};
|
||||
function button_pages() {
|
||||
if (data.menuitem==='pages') {
|
||||
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: `/tag/${data.tag.id}/pages`}, 'Статьи')
|
||||
}
|
||||
};
|
||||
function button_users() {
|
||||
if (data.menuitem==='users') {
|
||||
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: `/tag/${data.tag.id}/users`}, 'Пользователи')
|
||||
}
|
||||
};
|
||||
return {
|
||||
oninit: function(vnode) {
|
||||
console.log('MenuTag.oninit');
|
||||
for (let key in vnode.attrs){
|
||||
data[key] = vnode.attrs[key];
|
||||
};
|
||||
},
|
||||
onupdate: function(vnode) {
|
||||
console.log('MenuTag.onupdate');
|
||||
for (let key in vnode.attrs){
|
||||
data[key] = vnode.attrs[key];
|
||||
};
|
||||
},
|
||||
view: function() {
|
||||
if (data.tag!=null) {
|
||||
return m('div', {class: 'row'}, [
|
||||
m('div', {class: 'col py-2'}, [
|
||||
button_common(),
|
||||
button_pages(),
|
||||
button_users(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
162
src/myapp/templates/private/domains/tag/pages.js
Normal file
162
src/myapp/templates/private/domains/tag/pages.js
Normal file
@@ -0,0 +1,162 @@
|
||||
function TagPages() {
|
||||
let data = {
|
||||
filter: PanelFilter(),
|
||||
order_by: PanelOrderBy({
|
||||
field: 'title',
|
||||
fields: [
|
||||
{value: 'id', text: 'ID'},
|
||||
{value: 'title', text: 'заголовку'},
|
||||
{value: 'created', text: 'дате создания'},
|
||||
{value: 'updated', text: 'дате обновления'}
|
||||
],
|
||||
clickHandler: pages_get,
|
||||
order: 'asc',
|
||||
}),
|
||||
tag: null,
|
||||
raw_pages: [],
|
||||
get pages() {
|
||||
let result = data.raw_pages.filter(page_filter);
|
||||
return result;
|
||||
},
|
||||
pagination: {
|
||||
page: 1,
|
||||
size: 0,
|
||||
prefix_url: '/pages'
|
||||
},
|
||||
};
|
||||
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: '/tags'}, 'Список тегов')),
|
||||
m('li', {class: 'breadcrumb-item'}, m(m.route.Link, {href: `/tag/${data.tag.id}`}, data.tag.name)),
|
||||
m('li', {class: 'breadcrumb-item active'}, 'Список статей'),
|
||||
]);
|
||||
return result;
|
||||
};
|
||||
function page_filter(page) {
|
||||
let filter = data.filter.data;
|
||||
let value = filter.value;
|
||||
if ( value.length<1 ) {
|
||||
return true;
|
||||
}
|
||||
if ( page.title.toLowerCase().includes(value.toLowerCase()) ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
function tag_get(id) {
|
||||
m.request({
|
||||
url: '/api',
|
||||
method: "POST",
|
||||
body: {
|
||||
"jsonrpc": "2.0",
|
||||
"method": 'tag',
|
||||
"params": {
|
||||
"id": id
|
||||
},
|
||||
"id": get_id()
|
||||
}
|
||||
}).then(
|
||||
function(response) {
|
||||
if ('result' in response) {
|
||||
data.tag = response['result'];
|
||||
data.pagination.prefix_url = `/tag/${data.tag.id}/pages`;
|
||||
document.title = `Статьи с тегом [${data.tag.name}] - ${SETTINGS.TITLE}`;
|
||||
pages_get();
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
function pages_get() {
|
||||
m.request({
|
||||
url: '/api',
|
||||
method: "POST",
|
||||
body: [
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"method": 'tag.pages',
|
||||
"params": {
|
||||
"id": data.tag.id,
|
||||
"page": data.pagination.page,
|
||||
"order_by": data.order_by.value,
|
||||
"fields": ["id", "title", "created", "updated", "tags", "user"]
|
||||
},
|
||||
"id": get_id()
|
||||
},
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"method": 'tag.pages.count',
|
||||
"params": {
|
||||
"id": data.tag.id,
|
||||
},
|
||||
"id": get_id()
|
||||
}
|
||||
]
|
||||
|
||||
}).then(
|
||||
function(response) {
|
||||
if ('result' in response[0]) {
|
||||
data.raw_pages = response[0]['result'];
|
||||
}
|
||||
if ('result' in response[1]) {
|
||||
data.pagination.size = response[1]['result'];
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
return {
|
||||
oninit: function(vnode) {
|
||||
console.log('TagPages.oninit');
|
||||
if (vnode.attrs.page!==undefined) {
|
||||
data.pagination.page = Number(vnode.attrs.page);
|
||||
};
|
||||
tag_get(vnode.attrs.id);
|
||||
},
|
||||
onbeforeupdate: function(vnode) {
|
||||
console.log('TagPages.onbeforeupdate');
|
||||
if (vnode.attrs.page!==undefined) {
|
||||
if (data.pagination.page != Number(vnode.attrs.page)) {
|
||||
data.pagination.page = Number(vnode.attrs.page);
|
||||
pages_get();
|
||||
};
|
||||
};
|
||||
},
|
||||
view: function(vnode) {
|
||||
console.log('TagPages.view');
|
||||
result = [];
|
||||
if (data.tag!=null) {
|
||||
result.push(
|
||||
breadcrumbs_render(),
|
||||
m('div', {class: 'row'},
|
||||
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('i', {class: "fa fa-filter"})
|
||||
),
|
||||
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.order_by.data) }},
|
||||
m('i', {class: "fa fa-sort-alpha-asc"})
|
||||
)
|
||||
]),
|
||||
`Статьи с тегом [${data.tag.name}]`
|
||||
]),
|
||||
),
|
||||
m('hr')
|
||||
);
|
||||
|
||||
// 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));
|
||||
};
|
||||
result.push(breadcrumbs_render());
|
||||
};
|
||||
return result;
|
||||
}
|
||||
}
|
||||
};
|
||||
86
src/myapp/templates/private/domains/tag/tag.js
Normal file
86
src/myapp/templates/private/domains/tag/tag.js
Normal file
@@ -0,0 +1,86 @@
|
||||
function Tag() {
|
||||
let data = {
|
||||
tag: null,
|
||||
menuitem: null,
|
||||
panels: {
|
||||
standart: {
|
||||
visible: false
|
||||
}
|
||||
},
|
||||
};
|
||||
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: '/tags'}, 'Список тегов')),
|
||||
m('li', {class: 'breadcrumb-item active'}, data.tag.name),
|
||||
]);
|
||||
return result;
|
||||
};
|
||||
function tag_get(id) {
|
||||
m.request({
|
||||
url: '/api',
|
||||
method: "POST",
|
||||
body: {
|
||||
"jsonrpc": "2.0",
|
||||
"method": 'tag',
|
||||
"params": {
|
||||
"id": id
|
||||
},
|
||||
"id": get_id()
|
||||
}
|
||||
}).then(
|
||||
function(response) {
|
||||
if ('result' in response) {
|
||||
data.tag = response['result'];
|
||||
document.title = `${data.tag.name} - ${SETTINGS.TITLE}`;
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
function panels_standart_render() {
|
||||
if (data.panels.standart.visible) {
|
||||
return m('div', {class: 'row'},
|
||||
m('div', {class: 'col py-2'}, [
|
||||
m(ComponentFavorite, {resource: data.tag, name: 'tag'}),
|
||||
m(m.route.Link, {class: 'btn btn-outline-secondary', href: `/tag/${data.tag.id}/edit`, title: 'Редактировать'}, m('i', {class: 'fa fa-edit'})),
|
||||
])
|
||||
);
|
||||
}
|
||||
};
|
||||
return {
|
||||
oninit: function(vnode) {
|
||||
console.log('Tag.oninit');
|
||||
tag_get(vnode.attrs.id);
|
||||
},
|
||||
view: function(vnode) {
|
||||
console.log('Tag.view');
|
||||
result = [];
|
||||
if (data.tag!=null) {
|
||||
result.push(
|
||||
breadcrumbs_render(),
|
||||
m('div', {class: 'row'},
|
||||
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: "/tags", title: "Облако тегов"}, m('i', {class: 'fa fa-chevron-left'})),
|
||||
m('button', {type: 'button', class: 'btn btn-outline-secondary', onclick: function() {panel_show(data.panels.standart)}}, m('i', {class: 'fa fa-cog'})),
|
||||
),
|
||||
data.tag.name
|
||||
]),
|
||||
),
|
||||
panels_standart_render(),
|
||||
m('hr')
|
||||
);
|
||||
|
||||
result.push({tag: MenuTag, attrs: {tag: data.tag}});
|
||||
|
||||
result.push(
|
||||
m('div', {class: 'row mt-1'},
|
||||
m('div', {class: "col py-2"}, m.trust(data.tag.description)),
|
||||
)
|
||||
);
|
||||
result.push(breadcrumbs_render());
|
||||
};
|
||||
return result;
|
||||
}
|
||||
};
|
||||
};
|
||||
173
src/myapp/templates/private/domains/tag/tags.js
Normal file
173
src/myapp/templates/private/domains/tag/tags.js
Normal file
@@ -0,0 +1,173 @@
|
||||
function Tags() {
|
||||
let data = {
|
||||
filter: PanelFilter(),
|
||||
raw_groups: {},
|
||||
get groups() {
|
||||
let result = {};
|
||||
Object.keys(data.raw_groups).forEach(
|
||||
function(group, groupIdx) {
|
||||
let tags = data.raw_groups[group].filter(tag_filter);
|
||||
if (tags.length>0) {
|
||||
result[group] = tags;
|
||||
}
|
||||
}
|
||||
);
|
||||
return result;
|
||||
},
|
||||
panels: {
|
||||
tag_new: {
|
||||
value: '',
|
||||
visible: false,
|
||||
}
|
||||
},
|
||||
};
|
||||
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 active'}, 'Список тегов'),
|
||||
]);
|
||||
return result;
|
||||
};
|
||||
function tag_filter(tag) {
|
||||
let filter = data.filter.data;
|
||||
let value = filter.value;
|
||||
if ( value.length<1 ) {
|
||||
return true;
|
||||
}
|
||||
if ( tag.name.toLowerCase().includes(value.toLowerCase()) ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
function tag_add() {
|
||||
/* Добавить новый тег */
|
||||
m.request({
|
||||
url: '/api',
|
||||
method: "POST",
|
||||
body: {
|
||||
"jsonrpc": "2.0",
|
||||
"method": 'tag.add',
|
||||
"params": {
|
||||
name: data.panels.tag_new.value
|
||||
},
|
||||
"id": get_id()
|
||||
}
|
||||
}).then(
|
||||
function(response) {
|
||||
if ('result' in response) {
|
||||
data.panels.tag_new.value = '';
|
||||
getTags();
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
function form_submit(e) {
|
||||
e.preventDefault();
|
||||
tag_add();
|
||||
};
|
||||
function tags_get() {
|
||||
m.request({
|
||||
url: '/api',
|
||||
method: "POST",
|
||||
body: {
|
||||
"jsonrpc": "2.0",
|
||||
"method": 'tags.groups',
|
||||
"params": {
|
||||
},
|
||||
"id": get_id()
|
||||
}
|
||||
}).then(
|
||||
function(response) {
|
||||
if ('result' in response) {
|
||||
data.raw_groups = response['result'];
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
function form_tag_new_render() {
|
||||
/* Форма для нового тега */
|
||||
let result = [];
|
||||
if (data.panels.tag_new.visible) {
|
||||
result.push(
|
||||
m('form', {onsubmit: form_submit},
|
||||
m('div', {class: 'mb-3'},
|
||||
m('div', {class: 'input-group'}, [
|
||||
m('span', {class: 'input-group-text'}, m('i', {class: 'fa fa-tag'})),
|
||||
m('input', {class: 'form-control', type: 'text', oninput: function (e) {data.panels.tag_new.value = e.target.value}, value: data.panels.tag_new.value}),
|
||||
m('button', {class: 'btn btn-outline-success', type: 'submit'}, m('i', {class: 'fa fa-save'}))
|
||||
])
|
||||
)
|
||||
)
|
||||
);
|
||||
};
|
||||
return result;
|
||||
};
|
||||
return {
|
||||
oninit: function(vnode) {
|
||||
console.log('Tags.oninit');
|
||||
tags_get();
|
||||
},
|
||||
view: function(vnode) {
|
||||
console.log('Tags.view');
|
||||
document.title = `Облако тегов - ${SETTINGS.TITLE}`;
|
||||
result = [];
|
||||
result.push(
|
||||
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('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'})),
|
||||
'Облако тегов',
|
||||
])
|
||||
),
|
||||
m('hr'),
|
||||
);
|
||||
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(
|
||||
function(group, groupIdx) {
|
||||
let odd = '';
|
||||
if (groupIdx % 2) {
|
||||
odd = 'btn-primary'
|
||||
};
|
||||
groups.push({tag: '<', children: `<a href="#${groupIdx}" class="btn ${odd} btn-lg my-1 mx-1">${group}</a>`});
|
||||
}
|
||||
);
|
||||
result.push(
|
||||
m('div', {class: 'row'},
|
||||
m('div', {class: "col text-justify"}, [...groups])
|
||||
)
|
||||
)
|
||||
groups = [];
|
||||
Object.keys(data.groups).forEach(
|
||||
function(group, groupIdx) {
|
||||
console.log(data.groups[group]);
|
||||
let odd = '';
|
||||
if (groupIdx % 2) {
|
||||
odd = ' bg-light'
|
||||
};
|
||||
let tags = data.groups[group].map(
|
||||
function(tag, tagIdx) {
|
||||
return m(m.route.Link, {class: "btn btn-outline-secondary font-monospace my-1 me-2", href: `/tag/${tag.id}`}, tag.name);
|
||||
}
|
||||
)
|
||||
groups.push(m('div', {class: 'row'}, [
|
||||
m('div', {class: "col-md-1 py-2" + odd}, [
|
||||
m('a', {id: groupIdx, class: 'btn btn-outline-danger w-100 my-1'}, group),
|
||||
// m(m.route.Link, {class: "text-decoration-none", href: "/tag/" + tag.id, title: "Тег #" + tag.id}, tag.name),
|
||||
]),
|
||||
m('div', {class: "col-md-11 py-2" + odd}, [...tags]),
|
||||
]))
|
||||
}
|
||||
);
|
||||
result.push(...groups);
|
||||
};
|
||||
result.push(breadcrumbs_render());
|
||||
return result;
|
||||
}
|
||||
};
|
||||
};
|
||||
145
src/myapp/templates/private/domains/tag/users.js
Normal file
145
src/myapp/templates/private/domains/tag/users.js
Normal file
@@ -0,0 +1,145 @@
|
||||
function TagUsers() {
|
||||
let data = {
|
||||
filter: PanelFilter(),
|
||||
order_by: PanelOrderBy({
|
||||
field: 'name',
|
||||
fields: [
|
||||
{value: 'id', text: 'ID'},
|
||||
{value: 'name', text: 'заголовку'}
|
||||
],
|
||||
clickHandler: users_get,
|
||||
order: 'asc',
|
||||
}),
|
||||
tag: null,
|
||||
users: [],
|
||||
pagination: {
|
||||
page: 1,
|
||||
size: 0,
|
||||
prefix_url: '/users'
|
||||
},
|
||||
};
|
||||
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: '/tags'}, 'Список тегов')),
|
||||
m('li', {class: 'breadcrumb-item'}, m(m.route.Link, {href: `/tag/${data.tag.id}`}, data.tag.name)),
|
||||
m('li', {class: 'breadcrumb-item active'}, 'Список пользователей'),
|
||||
]);
|
||||
return result;
|
||||
};
|
||||
function tag_get(id) {
|
||||
m.request({
|
||||
url: '/api',
|
||||
method: "POST",
|
||||
body: {
|
||||
"jsonrpc": "2.0",
|
||||
"method": 'tag',
|
||||
"params": {
|
||||
"id": id
|
||||
},
|
||||
"id": get_id()
|
||||
}
|
||||
}).then(
|
||||
function(response) {
|
||||
if ('result' in response) {
|
||||
data.tag = response['result'];
|
||||
data.pagination.prefix_url = `/tag/${data.tag.id}/users`;
|
||||
document.title = `Пользователи с навыком [${data.tag.name}] - ${SETTINGS.TITLE}`;
|
||||
users_get();
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
function users_get() {
|
||||
m.request({
|
||||
url: '/api',
|
||||
method: "POST",
|
||||
body: [
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"method": 'tag.users',
|
||||
"params": {
|
||||
"id": data.tag.id,
|
||||
"page": data.pagination.page,
|
||||
"order_by": data.order_by.value,
|
||||
"fields": ["id", "name", "skills"]
|
||||
},
|
||||
"id": get_id()
|
||||
},
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"method": 'tag.users.count',
|
||||
"params": {
|
||||
"id": data.tag.id
|
||||
},
|
||||
"id": get_id()
|
||||
}
|
||||
]
|
||||
|
||||
}).then(
|
||||
function(response) {
|
||||
if ('result' in response[0]) {
|
||||
data.users = response[0]['result'];
|
||||
}
|
||||
if ('result' in response[1]) {
|
||||
data.pagination.size = response[1]['result'];
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
return {
|
||||
oninit: function(vnode) {
|
||||
console.log('TagUsers.oninit');
|
||||
if (vnode.attrs.page!==undefined) {
|
||||
data.pagination.page = Number(vnode.attrs.page);
|
||||
};
|
||||
tag_get(vnode.attrs.id);
|
||||
},
|
||||
onbeforeupdate: function(vnode) {
|
||||
console.log('TagUsers.onbeforeupdate');
|
||||
if (vnode.attrs.page!==undefined) {
|
||||
if (data.pagination.page != Number(vnode.attrs.page)) {
|
||||
data.pagination.page = Number(vnode.attrs.page);
|
||||
users_get();
|
||||
};
|
||||
};
|
||||
},
|
||||
view: function(vnode) {
|
||||
console.log('TagUsers.view');
|
||||
result = [];
|
||||
if (data.tag!=null) {
|
||||
result.push(
|
||||
breadcrumbs_render(),
|
||||
m('div', {class: 'row'},
|
||||
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('i', {class: "fa fa-filter"})
|
||||
),
|
||||
m('button', {type: "button", class: "btn btn-outline-secondary", onclick: function() { panel_show(data.order_by.data) }},
|
||||
m('i', {class: "fa fa-sort-alpha-asc"})
|
||||
)
|
||||
]),
|
||||
`Пользователи с тегом [${data.tag.name}]`
|
||||
])
|
||||
),
|
||||
m('hr'),
|
||||
);
|
||||
|
||||
// result.push(m(MenuTag, {menuitem: 'users', tag: data.tag}));
|
||||
result.push({tag: MenuTag, attrs: {menuitem: 'users', tag: data.tag}});
|
||||
|
||||
result.push(m(data.filter));
|
||||
result.push(m(data.order_by));
|
||||
result.push(m(Pagination, data.pagination));
|
||||
if (data.users.length>0) {
|
||||
result.push(m(ComponentUsers, {users: data.users}));
|
||||
result.push(m(Pagination, data.pagination));
|
||||
};
|
||||
result.push(breadcrumbs_render());
|
||||
};
|
||||
return result;
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -2,4 +2,5 @@ const SETTINGS = {
|
||||
ITEMS_ON_PAGE: {{ ITEMS_ON_PAGE }},
|
||||
TITLE: 'Моя панель',
|
||||
ME: {{ user|tojson|safe }},
|
||||
STATIC: '{{ STATIC }}',
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
const SETTINGS = {
|
||||
ITEMS_ON_PAGE: {{ ITEMS_ON_PAGE }},
|
||||
TITLE: 'Моя панель',
|
||||
STATIC: '{{ STATIC }}',
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user