changelog updates

This commit is contained in:
flash 2018-07-07 03:32:09 +02:00
parent 80f9c7d0dc
commit 074a89e6b1
18 changed files with 869 additions and 16 deletions

View file

@ -0,0 +1,47 @@
.changelog-change {
display: flex;
justify-content: space-between;
align-items: flex-start;
&__datetime,
&__text {
margin: 2px 5px;
}
&__text {
font-size: 1.2em;
line-height: 1.5em;
}
&__tags {
list-style: none;
display: flex;
margin-top: 4px;
}
&__tag {
padding: 2px 5px;
margin: 1px;
background-color: #444;
border-radius: 2px;
&--dark {
color: #000;
}
}
&__contributor {
display: flex;
align-items: center;
}
&__avatar {
width: 50px;
height: 50px;
}
&__username {
font-size: 1.2em;
margin: 2px 5px;
}
}

View file

@ -0,0 +1,27 @@
.changelog-tags {
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
&__entry {
margin: 2px;
width: 296px;
}
&__content {
height: 100%;
padding: 5px;
display: flex;
flex-direction: column;
justify-content: center;
}
&__text {
font-size: 1.2em;
line-height: 1.5em;
}
&__description {
font-size: .9em;
}
}

View file

@ -30,3 +30,6 @@ body {
@import "classes/pagination";
@import "classes/user-listing";
@import "classes/changelog-change";
@import "classes/changelog-tags";

View file

@ -47,8 +47,10 @@ function migrate_up(PDO $conn): void
`tag_name` VARCHAR(255) NOT NULL,
`tag_description` TEXT NULL,
`tag_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`tag_archived` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (`tag_id`),
UNIQUE INDEX `tag_name` (`tag_name`)
UNIQUE INDEX `tag_name` (`tag_name`),
INDEX `tag_archived` (`tag_archived`)
)
");
@ -56,8 +58,8 @@ function migrate_up(PDO $conn): void
CREATE TABLE `msz_changelog_change_tags` (
`change_id` INT(10) UNSIGNED NOT NULL,
`tag_id` INT(10) UNSIGNED NOT NULL,
INDEX `tag_id_foreign_key` (`tag_id`),
INDEX `change_tag_constraint` (`change_id`, `tag_id`),
INDEX `tag_id_foreign_key` (`tag_id`),
UNIQUE INDEX `change_tag_unique` (`change_id`, `tag_id`),
CONSTRAINT `change_id_foreign_key`
FOREIGN KEY (`change_id`)
REFERENCES `msz_changelog_changes` (`change_id`)

369
public/manage/changelog.php Normal file
View file

@ -0,0 +1,369 @@
<?php
use Misuzu\Database;
require_once __DIR__ . '/../../misuzu.php';
$db = Database::connection();
$tpl = $app->getTemplating();
$queryOffset = (int)($_GET['o'] ?? 0);
switch ($_GET['v'] ?? null) {
case 'changes':
$changesTake = 20;
$changesCount = (int)$db->query('
SELECT COUNT(`change_id`)
FROM `msz_changelog_changes`
')->fetchColumn();
$getChanges = $db->prepare('
SELECT
c.`change_id`, c.`change_log`, c.`change_created`,
a.`action_name`, a.`action_colour`, a.`action_class`,
u.`user_id`, u.`username`,
COALESCE(r.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `user_colour`
FROM `msz_changelog_changes` as c
LEFT JOIN `msz_changelog_actions` as a
ON a.`action_id` = c.`action_id`
LEFT JOIN `msz_users` as u
ON u.`user_id` = c.`user_id`
LEFT JOIN `msz_roles` as r
ON r.`role_id` = u.`display_role`
ORDER BY c.`change_id` DESC
LIMIT :offset, :take
');
$getChanges->bindValue('take', $changesTake);
$getChanges->bindValue('offset', $queryOffset);
$changes = $getChanges->execute() ? $getChanges->fetchAll(PDO::FETCH_ASSOC) : [];
$getTags = $db->prepare('
SELECT
t.`tag_id`, t.`tag_name`, t.`tag_description`
FROM `msz_changelog_change_tags` as ct
LEFT JOIN `msz_changelog_tags` as t
ON t.`tag_id` = ct.`tag_id`
WHERE ct.`change_id` = :change_id
');
// grab tags
for ($i = 0; $i < count($changes); $i++) {
$getTags->bindValue('change_id', $changes[$i]['change_id']);
$changes[$i]['tags'] = $getTags->execute() ? $getTags->fetchAll(PDO::FETCH_ASSOC) : [];
}
echo $tpl->render('@manage.changelog.changes', [
'changelog_changes' => $changes,
'changelog_changes_count' => $changesCount,
'changelog_offset' => $queryOffset,
'changelog_take' => $changesTake,
]);
break;
case 'change':
$changeId = (int)($_GET['c'] ?? 0);
if ($_SERVER['REQUEST_METHOD'] === 'POST' && tmp_csrf_verify($_POST['csrf'] ?? '')) {
if (!empty($_POST['change']) && is_array($_POST['change'])) {
if ($changeId > 0) {
$postChange = $db->prepare('
UPDATE `msz_changelog_changes`
SET `change_log` = :log,
`change_text` = :text,
`action_id` = :action,
`user_id` = :user,
`change_created` = :created
WHERE `change_id` = :change_id
');
$postChange->bindValue('change_id', $changeId);
} else {
$postChange = $db->prepare('
INSERT INTO `msz_changelog_changes`
(`change_log`, `change_text`, `action_id`, `user_id`, `change_created`)
VALUES
(:log, :text, :action, :user, :created)
');
}
$postChange->bindValue('log', $_POST['change']['log']);
$postChange->bindValue('action', $_POST['change']['action']);
$postChange->bindValue('text', strlen($_POST['change']['text'])
? $_POST['change']['text']
: null);
$postChange->bindValue('user', is_numeric($_POST['change']['user'])
? $_POST['change']['user']
: null);
$postChange->bindValue('created', strlen($_POST['change']['created'])
? $_POST['change']['created']
: null);
$postChange->execute();
if ($changeId < 1) {
header('Location: ?v=change&c=' . $db->lastInsertId());
return;
}
}
if (!empty($_POST['add_tag']) && is_numeric($_POST['add_tag'])) {
$addTag = $db->prepare('REPLACE INTO `msz_changelog_change_tags` VALUES (:change_id, :tag_id)');
$addTag->bindValue('change_id', $changeId);
$addTag->bindValue('tag_id', $_POST['add_tag']);
$addTag->execute();
}
if (!empty($_POST['remove_tag']) && is_numeric($_POST['remove_tag'])) {
$removeTag = $db->prepare('
DELETE FROM `msz_changelog_change_tags`
WHERE `change_id` = :change_id
AND `tag_id` = :tag_id
');
$removeTag->bindValue('change_id', $changeId);
$removeTag->bindValue('tag_id', $_POST['remove_tag']);
$removeTag->execute();
}
}
$actions = $db->query('
SELECT `action_id`, `action_name`
FROM `msz_changelog_actions`
')->fetchAll(PDO::FETCH_ASSOC);
$tpl->var('changelog_actions', $actions);
if ($changeId > 0) {
$getChange = $db->prepare('
SELECT `change_id`, `change_log`, `change_text`, `user_id`, `action_id`, `change_created`
FROM `msz_changelog_changes`
WHERE `change_id` = :change_id
');
$getChange->bindValue('change_id', $changeId);
$change = $getChange->execute() ? $getChange->fetch(PDO::FETCH_ASSOC) : [];
if ($change) {
$tpl->var('edit_change', $change);
$assignedTags = $db->prepare('
SELECT `tag_id`, `tag_name`
FROM `msz_changelog_tags`
WHERE `tag_id` IN (
SELECT `tag_id`
FROM `msz_changelog_change_tags`
WHERE `change_id` = :change_id
)
');
$assignedTags->bindValue('change_id', $change['change_id']);
$assignedTags = $assignedTags->execute() ? $assignedTags->fetchAll(PDO::FETCH_ASSOC) : [];
$availableTags = $db->prepare('
SELECT `tag_id`, `tag_name`
FROM `msz_changelog_tags`
WHERE `tag_id` NOT IN (
SELECT `tag_id`
FROM `msz_changelog_change_tags`
WHERE `change_id` = :change_id
)
AND `tag_archived` IS NULL
');
$availableTags->bindValue('change_id', $change['change_id']);
$availableTags = $availableTags->execute() ? $availableTags->fetchAll(PDO::FETCH_ASSOC) : [];
$tpl->vars([
'edit_change_assigned_tags' => $assignedTags,
'edit_change_available_tags' => $availableTags,
]);
} else {
header('Location: ?v=changes');
return;
}
}
echo $tpl->render('@manage.changelog.change_edit');
break;
case 'tags':
$tagsTake = 32;
$tagsCount = (int)$db->query('
SELECT COUNT(`tag_id`)
FROM `msz_changelog_tags`
')->fetchColumn();
$getTags = $db->prepare('
SELECT
t.`tag_id`, t.`tag_name`, t.`tag_description`, t.`tag_created`,
(
SELECT COUNT(ct.`change_id`)
FROM `msz_changelog_change_tags` as ct
WHERE ct.`tag_id` = t.`tag_id`
) as `tag_count`
FROM `msz_changelog_tags` as t
ORDER BY t.`tag_id` ASC
LIMIT :offset, :take
');
$getTags->bindValue('take', $tagsTake);
$getTags->bindValue('offset', $queryOffset);
$tags = $getTags->execute() ? $getTags->fetchAll(PDO::FETCH_ASSOC) : [];
echo $tpl->render('@manage.changelog.tags', [
'changelog_tags' => $tags,
'changelog_tags_count' => $tagsCount,
'changelog_take' => $tagsTake,
'changelog_offset' => $queryOffset,
]);
break;
case 'tag':
$tagId = (int)($_GET['t'] ?? 0);
if ($_SERVER['REQUEST_METHOD'] === 'POST' && tmp_csrf_verify($_POST['csrf'] ?? '')) {
if (!empty($_POST['tag']) && is_array($_POST['tag'])) {
if ($tagId > 0) {
$updateTag = $db->prepare('
UPDATE `msz_changelog_tags`
SET `tag_name` = :name,
`tag_description` = :description,
`tag_archived` = :archived
WHERE `tag_id` = :id
');
$updateTag->bindValue('id', $tagId);
} else {
$updateTag = $db->prepare('
INSERT INTO `msz_changelog_tags`
(`tag_name`, `tag_description`, `tag_archived`)
VALUES
(:name, :description, :archived)
');
}
$updateTag->bindValue('name', $_POST['tag']['name']);
$updateTag->bindValue('description', $_POST['tag']['description']);
$updateTag->bindValue('archived', empty($_POST['tag']['description']) ? null : date('Y-m-d H:i:s'));
$updateTag->execute();
if ($tagId < 1) {
header('Location: ?v=tag&t=' . $db->lastInsertId());
return;
}
}
}
if ($tagId > 0) {
$getTag = $db->prepare('
SELECT `tag_id`, `tag_name`, `tag_description`, `tag_archived`, `tag_created`
FROM `msz_changelog_tags`
WHERE `tag_id` = :tag_id
');
$getTag->bindValue('tag_id', $tagId);
$tag = $getTag->execute() ? $getTag->fetch(PDO::FETCH_ASSOC) : [];
if ($tag) {
$tpl->var('edit_tag', $tag);
} else {
header('Location: ?v=tags');
return;
}
}
echo $tpl->render('@manage.changelog.tag_edit');
break;
case 'actions':
$actionTake = 32;
$actionCount = (int)$db->query('
SELECT COUNT(`action_id`)
FROM `msz_changelog_actions`
')->fetchColumn();
$getActions = $db->prepare('
SELECT
a.`action_id`, a.`action_name`, a.`action_colour`,
(
SELECT COUNT(c.`action_id`)
FROM `msz_changelog_changes` as c
WHERE c.`action_id` = a.`action_id`
) as `action_count`
FROM `msz_changelog_actions` as a
ORDER BY a.`action_id` ASC
LIMIT :offset, :take
');
$getActions->bindValue('take', $actionTake);
$getActions->bindValue('offset', $queryOffset);
$actions = $getActions->execute() ? $getActions->fetchAll(PDO::FETCH_ASSOC) : [];
echo $tpl->render('@manage.changelog.actions', [
'changelog_actions' => $actions,
'changelog_actions_count' => $actionTake,
'changelog_take' => $actionTake,
'changelog_offset' => $queryOffset,
]);
break;
case 'action':
$actionId = (int)($_GET['a'] ?? 0);
if ($_SERVER['REQUEST_METHOD'] === 'POST' && tmp_csrf_verify($_POST['csrf'] ?? '')) {
if (!empty($_POST['action']) && is_array($_POST['action'])) {
if ($actionId > 0) {
$updateAction = $db->prepare('
UPDATE `msz_changelog_actions`
SET `action_name` = :name,
`action_colour` = :colour,
`action_class` = :class
WHERE `action_id` = :id
');
$updateAction->bindValue('id', $actionId);
} else {
$updateAction = $db->prepare('
INSERT INTO `msz_changelog_actions`
(`action_name`, `action_colour`, `action_class`)
VALUES
(:name, :colour, :class)
');
}
$actionColour = colour_create();
if (!empty($_POST['action']['colour']['inherit'])) {
colour_set_inherit($actionColour);
} else {
colour_set_red($actionColour, $_POST['action']['colour']['red']);
colour_set_green($actionColour, $_POST['action']['colour']['green']);
colour_set_blue($actionColour, $_POST['action']['colour']['blue']);
}
$updateAction->bindValue('name', $_POST['action']['name']);
$updateAction->bindValue('colour', $actionColour);
$updateAction->bindValue('class', $_POST['action']['class']);
$updateAction->execute();
if ($actionId < 1) {
header('Location: ?v=action&a=' . $db->lastInsertId());
return;
}
}
}
if ($actionId > 0) {
$getAction = $db->prepare('
SELECT `action_id`, `action_name`, `action_colour`, `action_class`
FROM `msz_changelog_actions`
WHERE `action_id` = :action_id
');
$getAction->bindValue('action_id', $actionId);
$action = $getAction->execute() ? $getAction->fetch(PDO::FETCH_ASSOC) : [];
if ($action) {
$tpl->var('edit_action', $action);
} else {
header('Location: ?v=actions');
return;
}
}
echo $tpl->render('@manage.changelog.action_edit');
break;
default:
header('Location: ?v=changes');
break;
}

View file

@ -20,7 +20,7 @@ switch ($_GET['v'] ?? null) {
echo 'somewhat soon i guess';
break;
case null:
default:
header('Location: ?v=overview');
break;
}

View file

@ -0,0 +1,63 @@
{% extends '@manage/changelog/master.twig' %}
{% block content %}
<div class="container">
<form action="?v=action{{ edit_action is defined ? '&a=' ~ edit_action.action_id : '' }}" method="post">
<h1 class="container__title">
{% if edit_action is defined %}
Editing <span style="{{ edit_action.action_colour|html_colour }}">{{ edit_action.action_name }}</span> ({{ edit_action.action_id }})
{% else %}
Adding a new action
{% endif %}
</h1>
<label class="form__label">
<div class="form__label__text">Name</div>
<div class="form__label__input">
<input class="input input--text" type="text" value="{{ edit_action is defined ? edit_action.action_name : '' }}" name="action[name]" maxlength="50">
</div>
</label>
<label class="form__label">
<div class="form__label__text">Class</div>
<div class="form__label__input">
<input class="input input--text" type="text" value="{{ edit_action is defined ? edit_action.action_class : '' }}" name="action[class]" maxlength="20">
</div>
</label>
<h2 class="container__subtitle">Colour</h2>
<label class="form__label">
<div class="form__label__text">Inherit Colour</div>
<div class="form__label__input">
<input class="input" type="checkbox" name="action[colour][inherit]"{% if edit_action is defined and edit_action.action_colour|colour_get_inherit %} checked{% endif %}>
</div>
</label>
<label class="form__label">
<div class="form__label__text">Red</div>
<div class="form__label__input">
<input class="input input--number" type="number" value="{{ edit_action is defined ? edit_action.action_colour|colour_get_red : '0' }}" min="0" max="255" name="action[colour][red]">
</div>
</label>
<label class="form__label">
<div class="form__label__text">Green</div>
<div class="form__label__input">
<input class="input input--number" type="number" value="{{ edit_action is defined ? edit_action.action_colour|colour_get_green : '0' }}" min="0" max="255" name="action[colour][green]">
</div>
</label>
<label class="form__label">
<div class="form__label__text">Blue</div>
<div class="form__label__input">
<input class="input input--number" type="number" value="{{ edit_action is defined ? edit_action.action_colour|colour_get_blue : '0' }}" min="0" max="255" name="action[colour][blue]">
</div>
</label>
<div>
<button class="button" name="csrf" value="{{ csrf_token() }}">Save</button>
</div>
</form>
</div>
{% endblock %}

View file

@ -0,0 +1,25 @@
{% extends '@manage/changelog/master.twig' %}
{% from '@manage/macros.twig' import pagination %}
{% block content %}
<div class="container">
<a href="?v=action" class="button">Create new action</a>
</div>
<div class="container listing changelog-tags">
{% for action in changelog_actions %}
<a href="?v=action&amp;a={{ action.action_id }}" class="listing__entry changelog-tags__entry"
style="{{ action.action_colour|html_colour({'border-color':'%s'}) }}">
<div class="listing__entry__content changelog-tags__content">
<div class="changelog-tags__text">
{{ action.action_name }} ({{ action.action_count }})
</div>
</div>
</a>
{% endfor %}
</div>
<div class="container container--center">
{{ pagination(changelog_actions_count, changelog_take, changelog_offset, '?v=actions') }}
</div>
{% endblock %}

View file

@ -0,0 +1,108 @@
{% extends '@manage/changelog/master.twig' %}
{% block content %}
<div class="container">
<form action="?v=change{{ edit_change is defined ? '&c=' ~ edit_change.change_id : '' }}" method="post">
<h1 class="container__title">
{% if edit_change is defined %}
Editing #{{ edit_change.change_id }}
{% else %}
Adding a new change
{% endif %}
</h1>
<label class="form__label" style="width:100%">
<div class="form__label__text">Log</div>
<div class="form__label__input">
<input class="input input--text" type="text" value="{{ edit_change is defined ? edit_change.change_log : '' }}" name="change[log]" maxlength="255">
</div>
</label>
<label class="form__label" style="width:100%">
<div class="form__label__text">Text</div>
<div class="form__label__input">
<textarea class="input input--textarea" name="change[text]" maxlength="65535">{{ edit_change is defined ? edit_change.change_text : '' }}</textarea>
</div>
</label>
<label class="form__label">
<div class="form__label__text">Action</div>
<div class="form__label__input">
<select name="change[action]" class="input input--select">
{% for action in changelog_actions %}
<option value="{{ action.action_id }}"{% if edit_change is defined and action.action_id == edit_change.action_id %} selected{% endif %}>
{{ action.action_name }}
</option>
{% endfor %}
</select>
</div>
</label>
<label class="form__label">
<div class="form__label__text">Contributor Id</div>
<div class="form__label__input">
<input class="input input--text" type="number" value="{{ edit_change is defined ? edit_change.user_id : current_user.user_id }}" name="change[user]" min="1">
</div>
</label>
<label class="form__label">
<div class="form__label__text">Created</div>
<div class="form__label__input">
<input class="input input--text" type="text" value="{{ edit_change is defined ? edit_change.change_created : ''|date('Y-m-d H:i:s') }}" name="change[created]">
</div>
</label>
<div>
<button class="button" name="csrf" value="{{ csrf_token() }}">Save</button>
</div>
</form>
{% if edit_change is defined %}
<h1 class="container__title">
Tags
</h1>
{% if edit_change_assigned_tags|length > 0 %}
<form class="container" method="post" action="" style="display:inline-block">
<label class="form__label">
<div class="form__label__text">Assigned Tags</div>
<div class="form__label__input">
<select name="remove_tag" class="input input--select">
{% for tag in edit_change_assigned_tags %}
<option value="{{ tag.tag_id }}">
{{ tag.tag_name }}
</option>
{% endfor %}
</select>
</div>
</label>
<div>
<button class="button" name="csrf" value="{{ csrf_token() }}">Remove</button>
</div>
</form>
{% endif %}
{% if edit_change_available_tags|length > 0 %}
<form class="container" method="post" action="" style="display:inline-block">
<label class="form__label">
<div class="form__label__text">Available Tags</div>
<div class="form__label__input">
<select name="add_tag" class="input input--select">
{% for tag in edit_change_available_tags %}
<option value="{{ tag.tag_id }}">
{{ tag.tag_name }}
</option>
{% endfor %}
</select>
</div>
</label>
<div>
<button class="button" name="csrf" value="{{ csrf_token() }}">Add</button>
</div>
</form>
{% endif %}
{% endif %}
</div>
{% endblock %}

View file

@ -0,0 +1,54 @@
{% extends '@manage/changelog/master.twig' %}
{% from '@manage/macros.twig' import pagination %}
{% block content %}
<div class="container">
<a href="?v=change" class="button">Create new change</a>
</div>
<div class="container listing">
{% for change in changelog_changes %}
<a href="?v=change&amp;c={{ change.change_id }}" class="listing__entry" style="{{ change.action_colour|html_colour({'border-color':'%s'}) }}">
<div class="listing__entry__content changelog-change">
<div class="changelog-change__change">
<div class="changelog-change__text">
{{ change.change_log }}
</div>
<time class="changelog-change__datetime"
datetime="{{ change.change_created|date('c') }}"
title="{{ change.change_created|date('r') }}">
{{ change.change_created|time_diff }}
</time>
<ul class="changelog-change__tags">
<li style="{{ change.action_colour|html_colour({'background-color':'%s'}) }}"
class="changelog-change__tag changelog-change__tag--{{ change.action_colour|colour_get_css_contrast }}">
{{ change.action_name }}
</li>
{% for tag in change.tags %}
<li class="changelog-change__tag">{{ tag.tag_name }}</li>
{% endfor %}
</ul>
</div>
<div class="changelog-change__contributor">
<div class="changelog-change__username"
style="{{ change.user_colour|html_colour }}">
{{ change.username }}
</div>
<div class="avatar changelog-change__avatar"
style="background-image:url('/profile.php?u={{ change.user_id }}&amp;m=avatar')">
</div>
</div>
</div>
</a>
{% endfor %}
</div>
<div class="container container--center">
{{ pagination(changelog_changes_count, changelog_take, changelog_offset, '?v=changes') }}
</div>
{% endblock %}

View file

@ -0,0 +1 @@
{% extends '@manage/master.twig' %}

View file

@ -0,0 +1,97 @@
{% extends '@manage/changelog/master.twig' %}
{% block content %}
<div class="container">
<form action="?v=tag{{ edit_tag is defined ? '&t=' ~ edit_tag.tag_id : '' }}" method="post">
<h1 class="container__title">
{% if edit_tag is defined %}
Editing {{ edit_tag.tag_name }} ({{ edit_tag.tag_id }})
{% else %}
Adding a new tag
{% endif %}
</h1>
<label class="form__label" style="width:100%">
<div class="form__label__text">Name</div>
<div class="form__label__input">
<input class="input input--text" type="text" value="{{ edit_tag is defined ? edit_tag.tag_name : '' }}" name="tag[name]" maxlength="255">
</div>
</label>
<label class="form__label" style="width:100%">
<div class="form__label__text">Description</div>
<div class="form__label__input">
<textarea class="input input--textarea" name="tag[description]" maxlength="65535">{{ edit_tag is defined ? edit_tag.tag_description : '' }}</textarea>
</div>
</label>
<label class="form__label">
<div class="form__label__text">Archived</div>
<div class="form__label__input">
<input class="input" type="checkbox" name="tag[archived]"{% if edit_role is defined and edit_role.tag_archived is not null %} checked{% endif %}>
</div>
</label>
{% if edit_tag is defined %}
<label class="form__label">
<div class="form__label__text">Created</div>
<div class="form__label__input">
<input class="input input--text" type="text" value="{{ edit_tag.tag_created }}" readonly>
</div>
</label>
{% endif %}
<div>
<button class="button" name="csrf" value="{{ csrf_token() }}">Save</button>
</div>
</form>
{% if edit_change is defined %}
<h1 class="container__title">
Tags
</h1>
{% if edit_change_assigned_tags|length > 0 %}
<form class="container" method="post" action="" style="display:inline-block">
<label class="form__label">
<div class="form__label__text">Assigned Tags</div>
<div class="form__label__input">
<select name="remove_tag" class="input input--select">
{% for tag in edit_change_assigned_tags %}
<option value="{{ tag.tag_id }}">
{{ tag.tag_name }}
</option>
{% endfor %}
</select>
</div>
</label>
<div>
<button class="button" name="csrf" value="{{ csrf_token() }}">Remove</button>
</div>
</form>
{% endif %}
{% if edit_change_available_tags|length > 0 %}
<form class="container" method="post" action="" style="display:inline-block">
<label class="form__label">
<div class="form__label__text">Available Tags</div>
<div class="form__label__input">
<select name="add_tag" class="input input--select">
{% for tag in edit_change_available_tags %}
<option value="{{ tag.tag_id }}">
{{ tag.tag_name }}
</option>
{% endfor %}
</select>
</div>
</label>
<div>
<button class="button" name="csrf" value="{{ csrf_token() }}">Add</button>
</div>
</form>
{% endif %}
{% endif %}
</div>
{% endblock %}

View file

@ -0,0 +1,28 @@
{% extends '@manage/changelog/master.twig' %}
{% from '@manage/macros.twig' import pagination %}
{% block content %}
<div class="container">
<a href="?v=tag" class="button">Create new tag</a>
</div>
<div class="container listing changelog-tags">
{% for tag in changelog_tags %}
<a href="?v=tag&amp;t={{ tag.tag_id }}" class="listing__entry changelog-tags__entry">
<div class="listing__entry__content changelog-tags__content">
<div class="changelog-tags__text">
{{ tag.tag_name }} ({{ tag.tag_count }})
</div>
<div class="changelog-tags__description">
{{ tag.tag_description }}
</div>
</div>
</a>
{% endfor %}
</div>
<div class="container container--center">
{{ pagination(changelog_tags_count, changelog_take, changelog_offset, '?v=tags') }}
</div>
{% endblock %}

View file

@ -1,9 +1,3 @@
{% macro link(url, content, class) %}
{% spaceless %}
<a href="{{ url }}" {% if '://' in url %} target="_blank" rel="noreferrer noopener"{% endif %} {% if class is defined %}class="{{ class }}"{% endif %}>{{ content|raw }}</a>
{% endspaceless %}
{% endmacro %}
{% macro pagination_segment(url_window, base_url, currentPage) %}
{% for page, url in url_window %}
<li class="pagination__option{{ currentPage == page ? ' pagination__option--active' : '' }}">

View file

@ -1,5 +1,3 @@
{% from '@manage/macros.twig' import link %}
{% set menus = [
{
'name': 'general',
@ -96,6 +94,29 @@
],
],
},
{
'name': 'changelog',
'title': 'Changelog',
'sections': [
[
{
'name': 'changes',
'title': 'Changes',
'url': '/manage/changelog.php?v=changes',
},
{
'name': 'tags',
'title': 'Tags',
'url': '/manage/changelog.php?v=tags',
},
{
'name': 'actions',
'title': 'Actions',
'url': '/manage/changelog.php?v=actions',
},
],
],
},
] %}
<!DOCTYPE html>
@ -160,11 +181,20 @@
{% endblock %}
<footer class="footer">
{{ link('https://flash.moe', 'flash.moe', 'footer__link') }} 2013-{{
{{ 'https://flash.moe'|html_link('Flashwave', 'footer__link')|raw }} 2013-{{
''|date('Y') }} /
{{ link('https://github.com/flashwave/misuzu/tree/' ~ git_branch(), git_branch(), 'footer__link') }} # {{ link('https://github.com/flashwave/misuzu/commit/' ~ git_hash(true), git_hash(), 'footer__link') }}
<span title="{{ git_hash(true) }}">
{{ git_branch() }} # {{ git_hash() }}
</span>
{# link('https://github.com/flashwave/misuzu/tree/' ~ git_branch(), git_branch(), 'footer__link') }} # {{ link('https://github.com/flashwave/misuzu/commit/' ~ git_hash(true), git_hash(), 'footer__link') #}
</footer>
</div>
<script src="/js/libraries.js" charset="utf-8"></script>
<script>
window.addEventListener('load', () => {
timeago().render(document.querySelectorAll('time'));
hljs.initHighlighting();
});
</script>
</body>
</html>

View file

@ -6,6 +6,8 @@
{% if is_valid %}
{% set canonical_url = '/changelog.php?c=' ~ change.change_id %}
{% set manage_link = '/manage/changelog.php?v=change&c=' ~ change.change_id %}
{% set description = change.change_log %}
{% endif %}
{% block content %}
@ -36,7 +38,7 @@
</div>
<div class="changelog__change__user__info">
<div class="changelog__change__user__name">
<div class="changelog__change__user__name" style="{{ change.user_colour|html_colour }}">
{{ change.username }}
</div>

View file

@ -1 +1,5 @@
{% extends '@mio/master.twig' %}
{% if manage_link is not defined %}
{% set manage_link = '/manage/changelog.php' %}
{% endif %}

View file

@ -75,7 +75,6 @@
<div class="footer__links">
{% autoescape false %}
{{ '#'|html_link('Terms of Service', 'footer__links__link') }} |
{{ '#'|html_link('Rules', 'footer__links__link') }} |
{{ '#'|html_link('Contact', 'footer__links__link') }} |
{{ '#'|html_link('Status', 'footer__links__link') }} |