This commit is contained in:
2024-07-16 17:35:15 +03:00
parent f68f4f322a
commit 6be194b900
10 changed files with 239 additions and 21 deletions

View File

@@ -1,5 +1,6 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="author" content="Ремизов Александр" />
<meta name="copyright" lang="ru" content="RemiZOffAlex" />
<link rel="shortcut icon" href="/static/favicon.ico">

View File

@@ -4,7 +4,23 @@ function arrayRemove(arr, value) {
return ele.id != value.id;
});
};
function arrayRemoveByID(arr, value) {
/* Удаление элемента из списка */
return arr.filter(function (ele) {
return ele.id != value.id;
});
};
function arrayRemoveByItem(arr, value) {
/* Удаление элемента из списка */
return arr.filter(function (ele) {
return ele != value;
});
};
function panel_show(panel) {
/* Показать/скрыть панель */
panel.visible = !panel.visible;
};
function get_id() {
/* Получить рандомный ID */
return Math.random().toString(16).slice(2);
};

View File

@@ -3,17 +3,7 @@
{% include 'header.html' %}
<body>
<section id="app" class="container">
{% include '/private/navbar.html' %}
{% block content %}
{% endblock content %}
{% block breadcrumb %}
{% endblock %}
{% include 'footer.html' %}
</section>
<section id="app" class="container"></section>
<script type="text/javascript" src="{{ STATIC }}/tinymce/tinymce.min.js"></script>

View File

@@ -10,7 +10,6 @@ let MenuGeneral = {
m(m.route.Link, {class: 'btn btn-outline-secondary', href: '/'}, m('i', {class: 'fa fa-home'})),
m(m.route.Link, {class: 'btn btn-outline-secondary border-0', href: '/pages'}, 'Статьи'),
m(m.route.Link, {class: 'btn btn-outline-secondary border-0', href: '/tags'}, 'Метки'),
m(m.route.Link, {class: 'btn btn-outline-secondary border-0', href: '/users'}, 'Пользователи'),
m(m.route.Link, {class: 'btn btn-outline-secondary border-0', href: '/api/browse'}, 'API JSON-RPC'),
m(m.route.Link, {class: 'btn btn-outline-success float-end', href: '/login'}, m('i', {class: 'fa fa-sign-in'})),
])

View File

@@ -1,5 +1,6 @@
{% include '/public/domains/auth/inc.j2' %}
{% include '/public/domains/page/inc.j2' %}
{% include '/public/domains/tag/inc.j2' %}
{% include '/public/domains/user/inc.j2' %}
{% include '/public/domains/home.js' %}

View File

@@ -0,0 +1,10 @@
{% include '/public/domains/tag/tag.js' %}
{% include '/public/domains/tag/tags.js' %}
Object.assign(
routes,
{
"/tag/:id": layout_decorator(Tag),
"/tags": layout_decorator(Tags),
}
);

View File

@@ -0,0 +1,82 @@
function Tag() {
let data = {
tag: null,
menuitem: 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 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,
"fields": ["id", "name", "description"]
},
"id": get_id()
}
}).then(
function (response) {
if ('result' in response) {
data.tag = response['result'];
document.title = `${data.tag.name} - ${SETTINGS.TITLE}`;
}
}
);
};
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' })),
),
data.tag.name
]),
),
m('hr'),
);
// result.push(m(MenuTag, {"tag1": data.tag}));
result.push({ tag: MenuTag, attrs: { tag: data.tag } });
result.push(
m('div', { class: 'row' }, [
m('div', { class: "col-md-4 py-2" },
m(m.route.Link, { class: "btn btn-outline-secondary btn-lg w-100", href: `/tag/${data.tag.id}/notes` }, 'Заметки с тегом'),
),
m('div', { class: "col-md-4 py-2" },
m(m.route.Link, { class: "btn btn-outline-secondary btn-lg w-100", href: `/tag/${data.tag.id}/pages` }, 'Статьи с тегом'),
),
])
);
result.push(
m('div', { class: 'row' },
m('div', { class: "col py-2" }, m.trust(data.tag.description)),
)
);
result.push(breadcrumbs_render());
};
return result;
}
}
};

View File

@@ -0,0 +1,119 @@
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;
},
};
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 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'];
}
}
);
};
return {
oninit: function (vnode) {
console.log('Tags.oninit');
tags_get();
},
view: function (vnode) {
console.log('Tags.view');
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('hr'),
);
result.push(m(data.filter));
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) {
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 }, [
{ tag: '<', children: `<a id=${groupIdx} class="btn btn-outline-danger w-100 my-1">${group}</a>` },
// 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;
}
}
};

View File

@@ -1,6 +1,6 @@
<!DOCTYPE html>
<html lang="ru">
{% include 'header.html' %}
{% include 'header.html' %}
<body>
<section id="app" class="container">