@geekity/cms 0.21.0 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -0
- package/admin/components/admin-bar.njk +27 -6
- package/admin/components/alert.njk +28 -0
- package/admin/components/badge.njk +58 -0
- package/admin/components/button.njk +56 -0
- package/admin/components/card.njk +40 -0
- package/admin/components/collapse.njk +36 -0
- package/admin/components/copy.njk +20 -0
- package/admin/components/dropdown.njk +32 -0
- package/admin/components/fields.njk +81 -45
- package/admin/components/flash.njk +12 -5
- package/admin/components/menu.njk +51 -0
- package/admin/components/navbar.njk +23 -0
- package/admin/components/pagination.njk +47 -0
- package/admin/components/public-admin-bar.njk +4 -41
- package/admin/components/stat.njk +35 -0
- package/admin/components/table.njk +74 -0
- package/admin/components/tabs.njk +33 -0
- package/admin/components/theme-choice.njk +18 -0
- package/admin/layouts/base.njk +9 -16
- package/admin/layouts/settings-page.njk +15 -10
- package/admin/layouts/shell.njk +23 -31
- package/admin/pages/account/forgot.njk +39 -33
- package/admin/pages/account/login.njk +22 -16
- package/admin/pages/account/reset.njk +34 -25
- package/admin/pages/account/setup.njk +21 -15
- package/admin/pages/appearance/themes.njk +50 -44
- package/admin/pages/comments/all.njk +88 -106
- package/admin/pages/dashboard/home.njk +50 -62
- package/admin/pages/documents/conflict.njk +29 -24
- package/admin/pages/documents/editor.njk +155 -275
- package/admin/pages/documents/list.njk +60 -69
- package/admin/pages/documents/syndication.njk +98 -60
- package/admin/pages/documents/taxonomy.njk +36 -32
- package/admin/pages/error.njk +8 -5
- package/admin/pages/federation/followers.njk +91 -97
- package/admin/pages/federation/settings.njk +10 -11
- package/admin/pages/indieauth/consent.njk +60 -44
- package/admin/pages/indieauth/refused.njk +6 -3
- package/admin/pages/media/library.njk +86 -107
- package/admin/pages/messages/all.njk +71 -77
- package/admin/pages/navigation/menus.njk +90 -85
- package/admin/pages/placeholder.njk +13 -8
- package/admin/pages/settings/discussion.njk +30 -29
- package/admin/pages/settings/email.njk +26 -28
- package/admin/pages/settings/general.njk +10 -4
- package/admin/pages/settings/permalinks.njk +8 -9
- package/admin/pages/settings/privacy.njk +3 -3
- package/admin/pages/settings/reading.njk +3 -3
- package/admin/pages/tools/content-index.njk +79 -73
- package/admin/pages/tools/personal-data.njk +61 -55
- package/admin/pages/users/activity-entry.njk +12 -12
- package/admin/pages/users/activity.njk +13 -19
- package/admin/pages/users/apps.njk +112 -100
- package/admin/pages/users/edit.njk +65 -58
- package/admin/pages/users/list.njk +26 -24
- package/admin/pages/users/new.njk +11 -7
- package/admin/src/admin.css +174 -0
- package/admin/static/admin-bar.css +33 -31
- package/admin/static/admin-bar.js +22 -0
- package/admin/static/admin.css +7388 -1195
- package/admin/static/copy.js +1 -1
- package/admin/static/editor.js +18 -18
- package/dist/admin/accounts.d.ts +20 -0
- package/dist/admin/accounts.d.ts.map +1 -1
- package/dist/admin/accounts.js +25 -0
- package/dist/admin/accounts.js.map +1 -1
- package/dist/admin/admin-theme.d.ts +157 -0
- package/dist/admin/admin-theme.d.ts.map +1 -0
- package/dist/admin/admin-theme.js +52 -0
- package/dist/admin/admin-theme.js.map +1 -0
- package/dist/admin/assets.d.ts +4 -3
- package/dist/admin/assets.d.ts.map +1 -1
- package/dist/admin/assets.js +4 -3
- package/dist/admin/assets.js.map +1 -1
- package/dist/admin/documents.js +1 -1
- package/dist/admin/documents.js.map +1 -1
- package/dist/admin/headers.js +1 -1
- package/dist/admin/headers.js.map +1 -1
- package/dist/admin/routes.d.ts.map +1 -1
- package/dist/admin/routes.js +17 -8
- package/dist/admin/routes.js.map +1 -1
- package/dist/admin/templates.d.ts +6 -3
- package/dist/admin/templates.d.ts.map +1 -1
- package/dist/admin/templates.js +25 -3
- package/dist/admin/templates.js.map +1 -1
- package/dist/admin/users.d.ts +4 -0
- package/dist/admin/users.d.ts.map +1 -1
- package/dist/admin/users.js +37 -1
- package/dist/admin/users.js.map +1 -1
- package/dist/content/post-type.d.ts.map +1 -1
- package/dist/content/post-type.js +7 -2
- package/dist/content/post-type.js.map +1 -1
- package/dist/web/admin-bar.d.ts +4 -4
- package/dist/web/admin-bar.d.ts.map +1 -1
- package/dist/web/admin-bar.js +11 -34
- package/dist/web/admin-bar.js.map +1 -1
- package/package.json +8 -4
- package/themes/default/README.md +3 -1
|
@@ -1,112 +1,103 @@
|
|
|
1
1
|
{# The listing behind /admin/posts and /admin/pages. One template for both:
|
|
2
2
|
`kind` says which, and whether the table has a date column and taxonomy
|
|
3
|
-
ones.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
Posts, Pages, Categories and Tags are four menu entries over three
|
|
7
|
-
templates — this listing, the editor beside it and the taxonomy screen —
|
|
8
|
-
because a post and a page differ by a `kind`, not by a screen. A folder per
|
|
9
|
-
menu entry would mean either a second copy of each template or a re-export
|
|
10
|
-
that exists only to make the directory look like the menu, so the folder is
|
|
11
|
-
named after what the screens are about instead. #}
|
|
3
|
+
ones. `pages/documents/` is named after what its screens are about rather
|
|
4
|
+
than after the menu, because Posts, Pages, Categories and Tags are four
|
|
5
|
+
menu entries over three templates. #}
|
|
12
6
|
{% extends "layouts/shell.njk" %}
|
|
7
|
+
{% from "components/badge.njk" import status %}
|
|
8
|
+
{% from "components/button.njk" import button, buttonLink %}
|
|
9
|
+
{% from "components/pagination.njk" import pagination %}
|
|
10
|
+
{% from "components/table.njk" import table, row, heading, cell, rowToggle %}
|
|
11
|
+
{% from "components/tabs.njk" import tabs %}
|
|
13
12
|
|
|
14
13
|
{% block title %}{{ kind.plural }}{% endblock %}
|
|
15
14
|
|
|
16
15
|
{% block content %}
|
|
17
|
-
<
|
|
16
|
+
<div class="mb-6 flex flex-wrap items-center gap-4">
|
|
17
|
+
<h1 class="text-2xl font-bold">{{ kind.plural }}</h1>
|
|
18
|
+
{{ buttonLink('Add new', newUrl, color='primary') }}
|
|
19
|
+
</div>
|
|
18
20
|
|
|
19
|
-
<
|
|
20
|
-
{
|
|
21
|
-
|
|
22
|
-
<a href="{{ entry.url }}"{% if entry.current %} aria-current="true"{% endif %}>{{ entry.label }}</a>
|
|
23
|
-
</li>
|
|
24
|
-
{% endfor %}
|
|
25
|
-
</ul>
|
|
21
|
+
<div class="mb-4 max-w-full overflow-x-auto contain-inline-size">
|
|
22
|
+
{{ tabs(filters, 'Show ' + (kind.plural | lower)) }}
|
|
23
|
+
</div>
|
|
26
24
|
|
|
27
25
|
{% if documents.length %}
|
|
28
|
-
|
|
29
|
-
<caption class="admin-visually-hidden">{{ kind.plural }}</caption>
|
|
26
|
+
{% call table(kind.plural) %}
|
|
30
27
|
<thead>
|
|
31
28
|
<tr>
|
|
32
29
|
<th scope="col">Title</th>
|
|
33
|
-
|
|
30
|
+
{{ heading('Author') }}
|
|
34
31
|
{% if kind.tagged %}
|
|
35
|
-
|
|
32
|
+
{{ heading('Tags') }}
|
|
36
33
|
{% endif %}
|
|
37
34
|
{% if kind.categorised %}
|
|
38
|
-
|
|
35
|
+
{{ heading('Categories') }}
|
|
39
36
|
{% endif %}
|
|
40
37
|
{% if kind.dated %}
|
|
41
|
-
|
|
38
|
+
{{ heading('Date') }}
|
|
42
39
|
{% else %}
|
|
43
|
-
|
|
40
|
+
{{ heading('Updated') }}
|
|
44
41
|
{% endif %}
|
|
45
|
-
|
|
46
|
-
<th scope="col">Actions</th>
|
|
42
|
+
{{ heading('Status') }}
|
|
47
43
|
</tr>
|
|
48
44
|
</thead>
|
|
49
45
|
<tbody>
|
|
50
46
|
{% for document in documents %}
|
|
51
|
-
|
|
52
|
-
<td
|
|
53
|
-
|
|
47
|
+
{% call row() %}
|
|
48
|
+
<td>
|
|
49
|
+
<a class="link link-hover font-medium" href="{{ document.editUrl }}">{{ document.title }}</a>{% if document.role %} — {{ document.role }}{% endif %}
|
|
50
|
+
<div class="-ms-2 mt-1 flex items-center gap-1 whitespace-nowrap transition-opacity lg:[@media(hover:hover)]:opacity-0 group-hover:opacity-100 group-focus-within:opacity-100">
|
|
51
|
+
{{ buttonLink('Edit', document.editUrl, style='ghost', size='xs') }}
|
|
52
|
+
<form method="post" action="{{ document.editUrl }}">
|
|
53
|
+
<input type="hidden" name="csrf_token" value="{{ csrfToken }}" />
|
|
54
|
+
<input type="hidden" name="return" value="{{ returnUrl }}" />
|
|
55
|
+
{% if document.trashed %}
|
|
56
|
+
{{ button('Restore', type='submit', name='action', value='restore', style='ghost', size='xs') }}
|
|
57
|
+
{% else %}
|
|
58
|
+
{{ button('Move to trash', type='submit', name='action', value='trash', style='ghost', size='xs') }}
|
|
59
|
+
{% endif %}
|
|
60
|
+
</form>
|
|
61
|
+
{% if document.viewUrl %}
|
|
62
|
+
{{ buttonLink('View', document.viewUrl, style='ghost', size='xs') }}
|
|
63
|
+
{% endif %}
|
|
64
|
+
</div>
|
|
65
|
+
{{ rowToggle(document.title) }}
|
|
66
|
+
</td>
|
|
67
|
+
{% call cell('Author', nowrap=true) %}{{ document.author }}{% endcall %}
|
|
54
68
|
{% if kind.tagged %}
|
|
55
|
-
|
|
69
|
+
{% call cell('Tags') %}{{ document.tags }}{% endcall %}
|
|
56
70
|
{% endif %}
|
|
57
71
|
{% if kind.categorised %}
|
|
58
|
-
|
|
72
|
+
{% call cell('Categories') %}{{ document.categories }}{% endcall %}
|
|
59
73
|
{% endif %}
|
|
60
74
|
{% if kind.dated %}
|
|
61
|
-
|
|
75
|
+
{% call cell('Date', nowrap=true) %}{{ document.date | date('html') }}{% endcall %}
|
|
62
76
|
{% else %}
|
|
63
|
-
|
|
77
|
+
{% call cell('Updated', nowrap=true) %}{{ document.updated | date('html') }}{% endcall %}
|
|
64
78
|
{% endif %}
|
|
65
|
-
|
|
79
|
+
{% call cell('Status') %}
|
|
66
80
|
{% if document.trashed %}
|
|
67
|
-
|
|
81
|
+
{{ status('trashed', 'Trash') }}
|
|
68
82
|
{% elif document.draft %}
|
|
69
|
-
|
|
83
|
+
{{ status('draft', 'Draft') }}
|
|
70
84
|
{% elif document.scheduled %}
|
|
71
|
-
|
|
85
|
+
{{ status('scheduled', 'Scheduled') }}
|
|
72
86
|
{% elif document.hidden %}
|
|
73
|
-
|
|
87
|
+
{{ status('hidden', 'Hidden') }}
|
|
74
88
|
{% else %}
|
|
75
|
-
|
|
89
|
+
{{ status('published', 'Published') }}
|
|
76
90
|
{% endif %}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
<a href="{{ document.editUrl }}">Edit</a>
|
|
80
|
-
<form method="post" action="{{ document.editUrl }}">
|
|
81
|
-
<input type="hidden" name="csrf_token" value="{{ csrfToken }}" />
|
|
82
|
-
<input type="hidden" name="return" value="{{ returnUrl }}" />
|
|
83
|
-
{% if document.trashed %}
|
|
84
|
-
<button type="submit" name="action" value="restore">Restore</button>
|
|
85
|
-
{% else %}
|
|
86
|
-
<button type="submit" name="action" value="trash">Move to trash</button>
|
|
87
|
-
{% endif %}
|
|
88
|
-
</form>
|
|
89
|
-
{% if document.viewUrl %}
|
|
90
|
-
<a href="{{ document.viewUrl }}">View</a>
|
|
91
|
-
{% endif %}
|
|
92
|
-
</td>
|
|
93
|
-
</tr>
|
|
91
|
+
{% endcall %}
|
|
92
|
+
{% endcall %}
|
|
94
93
|
{% endfor %}
|
|
95
94
|
</tbody>
|
|
96
|
-
|
|
95
|
+
{% endcall %}
|
|
97
96
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
<a rel="prev" href="{{ previousUrl }}">Newer</a>
|
|
102
|
-
{% endif %}
|
|
103
|
-
<span>Page {{ page }}</span>
|
|
104
|
-
{% if nextUrl %}
|
|
105
|
-
<a rel="next" href="{{ nextUrl }}">Older</a>
|
|
106
|
-
{% endif %}
|
|
107
|
-
</nav>
|
|
108
|
-
{% endif %}
|
|
97
|
+
<div class="mt-4">
|
|
98
|
+
{{ pagination(page, previousUrl=previousUrl, nextUrl=nextUrl) }}
|
|
99
|
+
</div>
|
|
109
100
|
{% else %}
|
|
110
|
-
<p
|
|
101
|
+
<p>Nothing here.</p>
|
|
111
102
|
{% endif %}
|
|
112
103
|
{% endblock %}
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
{# /admin/syndication: the services a post can be sent to, which is
|
|
2
2
|
content/_data/syndicationTargets.json itself.
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
no forms, because saving over it
|
|
4
|
+
A table of every entry the file holds, in file order, the broken ones too,
|
|
5
|
+
each marked offered or ignored; then one card per entry that saves or
|
|
6
|
+
removes it, and the Add card that appends one. An entry that declares
|
|
7
|
+
nothing says why, so it can be fixed or removed here. A file that is not a
|
|
8
|
+
JSON list is shown with its problem and no forms, because saving over it
|
|
9
|
+
would lose what it holds. #}
|
|
9
10
|
{% extends "layouts/shell.njk" %}
|
|
10
11
|
{% import "components/fields.njk" as field %}
|
|
12
|
+
{% from "components/alert.njk" import alert %}
|
|
13
|
+
{% from "components/badge.njk" import status %}
|
|
14
|
+
{% from "components/button.njk" import button %}
|
|
15
|
+
{% from "components/card.njk" import card, cardActions %}
|
|
16
|
+
{% from "components/table.njk" import table %}
|
|
11
17
|
|
|
12
18
|
{% block title %}{{ heading }}{% endblock %}
|
|
13
19
|
|
|
@@ -30,23 +36,25 @@
|
|
|
30
36
|
{% endmacro %}
|
|
31
37
|
|
|
32
38
|
{% block content %}
|
|
33
|
-
<h1>{{ heading }}</h1>
|
|
39
|
+
<h1 class="mb-6 text-2xl font-bold">{{ heading }}</h1>
|
|
34
40
|
|
|
35
41
|
{% if hasProblems %}
|
|
36
|
-
|
|
37
|
-
{%
|
|
38
|
-
{%
|
|
39
|
-
{
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
<div class="max-w-2xl">
|
|
43
|
+
{% call field.summary('Nothing was saved. Fix the fields marked below and try again.') %}
|
|
44
|
+
{% for panel in panels.concat([adding]) %}
|
|
45
|
+
{% if panel.key == refusedKey %}
|
|
46
|
+
{{ field.problem(panel.key + '-id', panel.problems.id) }}
|
|
47
|
+
{{ field.problem(panel.key + '-name', panel.problems.name) }}
|
|
48
|
+
{{ field.problem(panel.key + '-url', panel.problems.url) }}
|
|
49
|
+
{{ field.problem(panel.key + '-tag', panel.problems.tag) }}
|
|
50
|
+
{{ field.problem(panel.key + '-languages', panel.problems.languages) }}
|
|
51
|
+
{% endif %}
|
|
52
|
+
{% endfor %}
|
|
53
|
+
{% endcall %}
|
|
54
|
+
</div>
|
|
47
55
|
{% endif %}
|
|
48
56
|
|
|
49
|
-
<p class="
|
|
57
|
+
<p class="mb-6 max-w-prose text-sm">
|
|
50
58
|
Services such as IndieNews and Bridgy Publish copy a post when it links to them and sends
|
|
51
59
|
them a webmention. Each target listed here gets a checkbox in the post editor and is offered
|
|
52
60
|
to Micropub clients. They are kept in <code>content/{{ file }}</code>, which this screen reads
|
|
@@ -54,57 +62,87 @@
|
|
|
54
62
|
</p>
|
|
55
63
|
|
|
56
64
|
{% if fileProblem %}
|
|
57
|
-
<div class="
|
|
58
|
-
|
|
59
|
-
|
|
65
|
+
<div class="max-w-2xl">
|
|
66
|
+
{% call alert(color='error') %}
|
|
67
|
+
<p>{{ fileProblem }} No target is offered until it is fixed. Fix or remove the file by hand;
|
|
68
|
+
this screen will not save over it, because that would lose what it holds.</p>
|
|
69
|
+
{% endcall %}
|
|
60
70
|
</div>
|
|
61
71
|
{% else %}
|
|
62
|
-
<h2>Targets</h2>
|
|
63
|
-
|
|
64
72
|
{% if panels.length %}
|
|
65
|
-
<
|
|
73
|
+
<div class="mb-8">
|
|
74
|
+
{% call table('Targets') %}
|
|
75
|
+
<thead>
|
|
76
|
+
<tr>
|
|
77
|
+
<th scope="col">Name</th>
|
|
78
|
+
<th scope="col">Id</th>
|
|
79
|
+
<th scope="col">URL</th>
|
|
80
|
+
<th scope="col">Status</th>
|
|
81
|
+
</tr>
|
|
82
|
+
</thead>
|
|
83
|
+
<tbody>
|
|
84
|
+
{% for panel in panels %}
|
|
85
|
+
<tr>
|
|
86
|
+
<td><a class="link link-hover font-medium" href="#{{ panel.key }}">{{ panel.form.name or ('Entry ' + (panel.index + 1)) }}</a></td>
|
|
87
|
+
<td><code>{{ panel.form.id }}</code></td>
|
|
88
|
+
<td class="break-all">{{ panel.form.url }}</td>
|
|
89
|
+
<td>
|
|
90
|
+
{% if panel.fileProblems.length %}
|
|
91
|
+
{{ status('failed', 'Ignored') }}
|
|
92
|
+
{% else %}
|
|
93
|
+
{{ status('accepted', 'Offered') }}
|
|
94
|
+
{% endif %}
|
|
95
|
+
</td>
|
|
96
|
+
</tr>
|
|
97
|
+
{% endfor %}
|
|
98
|
+
</tbody>
|
|
99
|
+
{% endcall %}
|
|
100
|
+
</div>
|
|
101
|
+
|
|
102
|
+
<div class="grid max-w-2xl grid-cols-1 gap-6">
|
|
66
103
|
{% for panel in panels %}
|
|
67
|
-
<
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
104
|
+
<div id="{{ panel.key }}">
|
|
105
|
+
{% call card(title=(panel.form.name or ('Entry ' + (panel.index + 1)))) %}
|
|
106
|
+
{% if panel.fileProblems.length %}
|
|
107
|
+
{% for problem in panel.fileProblems %}
|
|
108
|
+
<p>This entry is ignored. {{ problem }}</p>
|
|
109
|
+
{% endfor %}
|
|
110
|
+
{% else %}
|
|
111
|
+
<p><code>{{ panel.form.id }}</code></p>
|
|
112
|
+
{% endif %}
|
|
76
113
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
</p>
|
|
85
|
-
</form>
|
|
114
|
+
<form method="post" action="{{ saveUrl }}">
|
|
115
|
+
<input type="hidden" name="csrf_token" value="{{ csrfToken }}" />
|
|
116
|
+
<input type="hidden" name="{{ fields.entry }}" value="{{ panel.index }}" />
|
|
117
|
+
<input type="hidden" name="{{ fields.was }}" value="{{ panel.was }}" />
|
|
118
|
+
{{ boxes(panel, fields) }}
|
|
119
|
+
<div class="mt-4">{{ button('Save target', type='submit', color='primary') }}</div>
|
|
120
|
+
</form>
|
|
86
121
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
122
|
+
<form method="post" action="{{ deleteUrl }}">
|
|
123
|
+
<input type="hidden" name="csrf_token" value="{{ csrfToken }}" />
|
|
124
|
+
<input type="hidden" name="{{ fields.entry }}" value="{{ panel.index }}" />
|
|
125
|
+
<input type="hidden" name="{{ fields.was }}" value="{{ panel.was }}" />
|
|
126
|
+
{% call cardActions() %}
|
|
127
|
+
{{ button('Remove this target', type='submit', color='error', style='ghost') }}
|
|
128
|
+
{% endcall %}
|
|
129
|
+
</form>
|
|
130
|
+
{% endcall %}
|
|
131
|
+
</div>
|
|
94
132
|
{% endfor %}
|
|
95
|
-
</
|
|
133
|
+
</div>
|
|
96
134
|
{% else %}
|
|
97
|
-
<p class="
|
|
135
|
+
<p class="mb-8">This site declares no targets, so the editor offers none.</p>
|
|
98
136
|
{% endif %}
|
|
99
137
|
|
|
100
|
-
<
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
</
|
|
138
|
+
<div class="mt-8 max-w-2xl">
|
|
139
|
+
{% call card(title='Add a target') %}
|
|
140
|
+
<form method="post" action="{{ addUrl }}">
|
|
141
|
+
<input type="hidden" name="csrf_token" value="{{ csrfToken }}" />
|
|
142
|
+
{{ boxes(adding, fields) }}
|
|
143
|
+
<div class="mt-4">{{ button('Add target', type='submit', color='primary') }}</div>
|
|
144
|
+
</form>
|
|
145
|
+
{% endcall %}
|
|
146
|
+
</div>
|
|
109
147
|
{% endif %}
|
|
110
148
|
{% endblock %}
|
|
@@ -1,48 +1,51 @@
|
|
|
1
1
|
{# /admin/tags and /admin/categories: every term in use, what carries it, and
|
|
2
|
-
the three things that can be done to it
|
|
2
|
+
the three things that can be done to it: rename, merge and delete. One
|
|
3
3
|
template for both taxonomies; `kind` says which. #}
|
|
4
4
|
{% extends "layouts/shell.njk" %}
|
|
5
|
+
{% from "components/alert.njk" import alert %}
|
|
6
|
+
{% from "components/button.njk" import button, buttonLink %}
|
|
7
|
+
{% from "components/card.njk" import card, cardActions %}
|
|
8
|
+
{% from "components/table.njk" import table %}
|
|
5
9
|
|
|
6
10
|
{% block title %}{{ heading }}{% endblock %}
|
|
7
11
|
|
|
8
12
|
{% block content %}
|
|
9
|
-
<h1>{{ heading }}</h1>
|
|
13
|
+
<h1 class="mb-6 text-2xl font-bold">{{ heading }}</h1>
|
|
10
14
|
|
|
11
15
|
{# Above the table rather than under the field it came from: a refusal may be
|
|
12
16
|
about a term the table no longer has a row for. #}
|
|
13
17
|
{% if problems.to %}
|
|
14
|
-
<
|
|
18
|
+
<div class="mb-6 max-w-2xl">
|
|
19
|
+
{% call alert(color='error') %}<span id="taxonomy-problem">{{ problems.to }}</span>{% endcall %}
|
|
20
|
+
</div>
|
|
15
21
|
{% endif %}
|
|
16
22
|
|
|
17
23
|
{% if confirm %}
|
|
18
|
-
<form class="
|
|
24
|
+
<form class="mb-6 max-w-2xl" method="post" action="{{ renameUrl }}">
|
|
19
25
|
<input type="hidden" name="csrf_token" value="{{ csrfToken }}" />
|
|
20
26
|
<input type="hidden" name="{{ fields.term }}" value="{{ confirm.term }}" />
|
|
21
27
|
<input type="hidden" name="{{ fields.to }}" value="{{ confirm.to }}" />
|
|
22
28
|
<input type="hidden" name="{{ fields.confirm }}" value="1" />
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
<a href="{{ listUrl }}">Cancel</a>
|
|
37
|
-
</p>
|
|
29
|
+
{% call card(title='Merge “' + confirm.term + '” into “' + confirm.to + '”?', style='border') %}
|
|
30
|
+
<p>
|
|
31
|
+
There is already a {{ label }} called “{{ confirm.to }}”, on
|
|
32
|
+
{{ confirm.targetFiles }} {% if confirm.targetFiles == 1 %}file{% else %}files{% endif %}.
|
|
33
|
+
Renaming “{{ confirm.term }}” merges the
|
|
34
|
+
{{ confirm.files }} {% if confirm.files == 1 %}file{% else %}files{% endif %} carrying it
|
|
35
|
+
into that one. A file that already carries both keeps it once.
|
|
36
|
+
</p>
|
|
37
|
+
{% call cardActions() %}
|
|
38
|
+
{{ buttonLink('Cancel', listUrl, style='ghost') }}
|
|
39
|
+
{{ button('Merge them', type='submit', color='primary') }}
|
|
40
|
+
{% endcall %}
|
|
41
|
+
{% endcall %}
|
|
38
42
|
</form>
|
|
39
43
|
{% endif %}
|
|
40
44
|
|
|
41
45
|
{% if terms.length == 0 %}
|
|
42
46
|
<p>Nothing carries a {{ label }} yet.</p>
|
|
43
47
|
{% else %}
|
|
44
|
-
|
|
45
|
-
<caption class="admin-visually-hidden">{{ heading }}</caption>
|
|
48
|
+
{% call table(heading) %}
|
|
46
49
|
<thead>
|
|
47
50
|
<tr>
|
|
48
51
|
<th scope="col">{{ kind.singular | capitalize }}</th>
|
|
@@ -54,42 +57,43 @@
|
|
|
54
57
|
</thead>
|
|
55
58
|
<tbody>
|
|
56
59
|
{% for entry in terms %}
|
|
60
|
+
{% set refused = problems.to and form.term == entry.term %}
|
|
57
61
|
<tr>
|
|
58
|
-
<td><a href="{{ entry.archiveUrl }}">{{ entry.term }}</a></td>
|
|
62
|
+
<td><a class="link link-hover font-medium" href="{{ entry.archiveUrl }}">{{ entry.term }}</a></td>
|
|
59
63
|
<td>{{ entry.published }}</td>
|
|
60
64
|
<td>{{ entry.total }}</td>
|
|
61
65
|
<td>
|
|
62
|
-
<form class="
|
|
66
|
+
<form class="flex items-center gap-2" method="post" action="{{ renameUrl }}">
|
|
63
67
|
<input type="hidden" name="csrf_token" value="{{ csrfToken }}" />
|
|
64
68
|
<input type="hidden" name="{{ fields.term }}" value="{{ entry.term }}" />
|
|
65
|
-
<label class="
|
|
66
|
-
Rename {{ entry.term }} to
|
|
67
|
-
</label>
|
|
69
|
+
<label class="sr-only" for="rename-{{ loop.index }}">Rename {{ entry.term }} to</label>
|
|
68
70
|
<input
|
|
69
71
|
id="rename-{{ loop.index }}"
|
|
70
72
|
name="{{ fields.to }}"
|
|
71
73
|
type="text"
|
|
72
74
|
value="{% if form.term == entry.term %}{{ form.to }}{% endif %}"
|
|
73
75
|
required
|
|
76
|
+
class="input input-sm w-40"
|
|
77
|
+
{% if refused %}aria-invalid="true" aria-describedby="taxonomy-problem"{% endif %}
|
|
74
78
|
/>
|
|
75
|
-
|
|
79
|
+
{{ button('Rename', type='submit', size='sm') }}
|
|
76
80
|
</form>
|
|
77
81
|
</td>
|
|
78
|
-
<td
|
|
82
|
+
<td>
|
|
79
83
|
<form method="post" action="{{ deleteUrl }}">
|
|
80
84
|
<input type="hidden" name="csrf_token" value="{{ csrfToken }}" />
|
|
81
85
|
<input type="hidden" name="{{ fields.term }}" value="{{ entry.term }}" />
|
|
82
|
-
|
|
86
|
+
{{ button('Delete', type='submit', style='ghost', size='xs') }}
|
|
83
87
|
</form>
|
|
84
88
|
</td>
|
|
85
89
|
</tr>
|
|
86
90
|
{% endfor %}
|
|
87
91
|
</tbody>
|
|
88
|
-
|
|
92
|
+
{% endcall %}
|
|
89
93
|
|
|
90
|
-
<p class="
|
|
94
|
+
<p class="mt-4 max-w-prose text-sm">
|
|
91
95
|
Renaming, merging and deleting rewrite the front matter of every file carrying the
|
|
92
|
-
{{ label }}
|
|
96
|
+
{{ label }} (drafts, scheduled posts and the trash included) and tell the feeds and the
|
|
93
97
|
fediverse about each published post that changed. The Files column is how many that is.
|
|
94
98
|
</p>
|
|
95
99
|
{% endif %}
|
package/admin/pages/error.njk
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
{# The page an admin request that threw answers with. It extends the bare
|
|
2
|
+
layout rather than the shell because the shell reads the session, the menu
|
|
3
|
+
and the site, and any of those may be what failed. #}
|
|
1
4
|
{% extends "layouts/base.njk" %}
|
|
5
|
+
{% from "components/card.njk" import card %}
|
|
2
6
|
|
|
3
7
|
{% block title %}Something went wrong{% endblock %}
|
|
4
8
|
|
|
5
9
|
{% block content %}
|
|
6
|
-
{
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
<p>This screen could not be shown because of a problem on the server. The error has been logged. Try again in a moment, or go back to the <a href="{{ adminUrl }}">dashboard</a>.</p>
|
|
10
|
+
{% call card() %}
|
|
11
|
+
<h1 class="card-title text-2xl">Something went wrong</h1>
|
|
12
|
+
<p>This screen could not be shown because of a problem on the server. The error has been logged. Try again in a moment, or go back to the <a class="link" href="{{ adminUrl }}">dashboard</a>.</p>
|
|
13
|
+
{% endcall %}
|
|
11
14
|
{% endblock %}
|