summaryrefslogtreecommitdiff
path: root/client/html
diff options
context:
space:
mode:
authorShyam Sunder <sgsunder1@gmail.com>2020-06-04 21:01:28 -0400
committerShyam Sunder <sgsunder1@gmail.com>2020-06-04 21:01:28 -0400
commitc5358f7f83ef49f51d5ba557dde1b16ce2c83d1d (patch)
tree253e0be234540c266202993567d998a5c951947d /client/html
parent4329b1620fe38c2a7bf44615cfb176daa2837590 (diff)
parentb0f1b8c2309277a7b170972d463b4e8d16a79ecc (diff)
client+server: add post pools feature
Diffstat (limited to 'client/html')
-rw-r--r--client/html/help_search.tpl1
-rw-r--r--client/html/help_search_pools.tpl97
-rw-r--r--client/html/help_search_posts.tpl6
-rw-r--r--client/html/pool.tpl18
-rw-r--r--client/html/pool_categories.tpl30
-rw-r--r--client/html/pool_category_row.tpl43
-rw-r--r--client/html/pool_create.tpl42
-rw-r--r--client/html/pool_delete.tpl21
-rw-r--r--client/html/pool_edit.tpl50
-rw-r--r--client/html/pool_input.tpl7
-rw-r--r--client/html/pool_merge.tpl22
-rw-r--r--client/html/pool_summary.tpl23
-rw-r--r--client/html/pools_header.tpl22
-rw-r--r--client/html/pools_page.tpl48
-rw-r--r--client/html/post_edit_sidebar.tpl6
-rw-r--r--client/html/tags_page.tpl10
16 files changed, 440 insertions, 6 deletions
diff --git a/client/html/help_search.tpl b/client/html/help_search.tpl
index 7073789..e382f2e 100644
--- a/client/html/help_search.tpl
+++ b/client/html/help_search.tpl
@@ -4,6 +4,7 @@
--><li data-name='posts'><a href='<%- ctx.formatClientLink('help', 'search', 'posts') %>'>Posts</a></li><!--
--><li data-name='users'><a href='<%- ctx.formatClientLink('help', 'search', 'users') %>'>Users</a></li><!--
--><li data-name='tags'><a href='<%- ctx.formatClientLink('help', 'search', 'tags') %>'>Tags</a></li><!--
+ --><li data-name='pools'><a href='<%- ctx.formatClientLink('help', 'search', 'pools') %>'>Pools</li><!--
--></ul><!--
--></nav>
diff --git a/client/html/help_search_pools.tpl b/client/html/help_search_pools.tpl
new file mode 100644
index 0000000..a1f0c80
--- /dev/null
+++ b/client/html/help_search_pools.tpl
@@ -0,0 +1,97 @@
+<p><strong>Anonymous tokens</strong></p>
+
+<p>Same as <code>name</code> token.</p>
+
+<p><strong>Named tokens</strong></p>
+
+<table>
+ <tbody>
+ <tr>
+ <td><code>name</code></td>
+ <td>having given name (accepts wildcards)</td>
+ </tr>
+ <tr>
+ <td><code>category</code></td>
+ <td>having given category (accepts wildcards)</td>
+ </tr>
+ <tr>
+ <td><code>creation-date</code></td>
+ <td>created at given date</td>
+ </tr>
+ <tr>
+ <td><code>creation-time</code></td>
+ <td>alias of <code>creation-date</code></td>
+ </tr>
+ <tr>
+ <td><code>last-edit-date</code></td>
+ <td>edited at given date</td>
+ </tr>
+ <tr>
+ <td><code>last-edit-time</code></td>
+ <td>alias of <code>last-edit-date</code></td>
+ </tr>
+ <tr>
+ <td><code>edit-date</code></td>
+ <td>alias of <code>last-edit-date</code></td>
+ </tr>
+ <tr>
+ <td><code>edit-time</code></td>
+ <td>alias of <code>last-edit-date</code></td>
+ </tr>
+ <tr>
+ <td><code>post-count</code></td>
+ <td>alias of <code>usages</code></td>
+ </tr>
+ </tbody>
+</table>
+
+<p><strong>Sort style tokens</strong></p>
+
+<table>
+ <tbody>
+ <tr>
+ <td><code>random</code></td>
+ <td>as random as it can get</td>
+ </tr>
+ <tr>
+ <td><code>name</code></td>
+ <td>A to Z</td>
+ </tr>
+ <tr>
+ <td><code>category</code></td>
+ <td>category (A to Z)</td>
+ </tr>
+ <tr>
+ <td><code>creation-date</code></td>
+ <td>recently created first</td>
+ </tr>
+ <tr>
+ <td><code>creation-time</code></td>
+ <td>alias of <code>creation-date</code></td>
+ </tr>
+ <tr>
+ <td><code>last-edit-date</code></td>
+ <td>recently edited first</td>
+ </tr>
+ <tr>
+ <td><code>last-edit-time</code></td>
+ <td>alias of <code>creation-time</code></td>
+ </tr>
+ <tr>
+ <td><code>edit-date</code></td>
+ <td>alias of <code>creation-time</code></td>
+ </tr>
+ <tr>
+ <td><code>edit-time</code></td>
+ <td>alias of <code>creation-time</code></td>
+ </tr>
+ <tr>
+ <td><code>post-count</code></td>
+ <td>number of posts</td>
+ </tr>
+ </tbody>
+</table>
+
+<p><strong>Special tokens</strong></p>
+
+<p>None.</p>
diff --git a/client/html/help_search_posts.tpl b/client/html/help_search_posts.tpl
index d1097b7..e6cb707 100644
--- a/client/html/help_search_posts.tpl
+++ b/client/html/help_search_posts.tpl
@@ -20,7 +20,7 @@
</tr>
<tr>
<td><code>uploader</code></td>
- <td>uploaded by given use (accepts wildcards)r</td>
+ <td>uploaded by given user (accepts wildcards)</td>
</tr>
<tr>
<td><code>upload</code></td>
@@ -43,6 +43,10 @@
<td>having given source URL (accepts wildcards)</td>
</tr>
<tr>
+ <td><code>pool</code></td>
+ <td>belonging to the pool with the given ID</td>
+ </tr>
+ <tr>
<td><code>tag-count</code></td>
<td>having given number of tags</td>
</tr>
diff --git a/client/html/pool.tpl b/client/html/pool.tpl
new file mode 100644
index 0000000..e1e5311
--- /dev/null
+++ b/client/html/pool.tpl
@@ -0,0 +1,18 @@
+<div class='content-wrapper' id='pool'>
+ <h1><%- ctx.pool.names[0] %></h1>
+ <nav class='buttons'><!--
+ --><ul><!--
+ --><li data-name='summary'><a href='<%- ctx.formatClientLink('pool', ctx.pool.id) %>'>Summary</a></li><!--
+ --><% if (ctx.canEditAnything) { %><!--
+ --><li data-name='edit'><a href='<%- ctx.formatClientLink('pool', ctx.pool.id, 'edit') %>'>Edit</a></li><!--
+ --><% } %><!--
+ --><% if (ctx.canMerge) { %><!--
+ --><li data-name='merge'><a href='<%- ctx.formatClientLink('pool', ctx.pool.id, 'merge') %>'>Merge with&hellip;</a></li><!--
+ --><% } %><!--
+ --><% if (ctx.canDelete) { %><!--
+ --><li data-name='delete'><a href='<%- ctx.formatClientLink('pool', ctx.pool.id, 'delete') %>'>Delete</a></li><!--
+ --><% } %><!--
+ --></ul><!--
+ --></nav>
+ <div class='pool-content-holder'></div>
+</div>
diff --git a/client/html/pool_categories.tpl b/client/html/pool_categories.tpl
new file mode 100644
index 0000000..b045038
--- /dev/null
+++ b/client/html/pool_categories.tpl
@@ -0,0 +1,30 @@
+<div class='content-wrapper pool-categories'>
+ <form>
+ <h1>Pool categories</h1>
+ <div class="table-wrap">
+ <table>
+ <thead>
+ <tr>
+ <th class='name'>Category name</th>
+ <th class='color'>CSS color</th>
+ <th class='usages'>Usages</th>
+ </tr>
+ </thead>
+ <tbody>
+ </tbody>
+ </table>
+ </div>
+
+ <% if (ctx.canCreate) { %>
+ <p><a href class='add'>Add new category</a></p>
+ <% } %>
+
+ <div class='messages'></div>
+
+ <% if (ctx.canCreate || ctx.canEditName || ctx.canEditColor || ctx.canDelete) { %>
+ <div class='buttons'>
+ <input type='submit' class='save' value='Save changes'>
+ </div>
+ <% } %>
+ </form>
+</div>
diff --git a/client/html/pool_category_row.tpl b/client/html/pool_category_row.tpl
new file mode 100644
index 0000000..5ff4456
--- /dev/null
+++ b/client/html/pool_category_row.tpl
@@ -0,0 +1,43 @@
+<% if (ctx.poolCategory.isDefault) { %><%
+ %><tr data-category='<%- ctx.poolCategory.name %>' class='default'><%
+%><% } else { %><%
+ %><tr data-category='<%- ctx.poolCategory.name %>'><%
+%><% } %>
+ <td class='name'>
+ <% if (ctx.canEditName) { %>
+ <%= ctx.makeTextInput({value: ctx.poolCategory.name, required: true}) %>
+ <% } else { %>
+ <%- ctx.poolCategory.name %>
+ <% } %>
+ </td>
+ <td class='color'>
+ <% if (ctx.canEditColor) { %>
+ <%= ctx.makeColorInput({value: ctx.poolCategory.color}) %>
+ <% } else { %>
+ <%- ctx.poolCategory.color %>
+ <% } %>
+ </td>
+ <td class='usages'>
+ <% if (ctx.poolCategory.name) { %>
+ <a href='<%- ctx.formatClientLink('pools', {query: 'category:' + ctx.poolCategory.name}) %>'>
+ <%- ctx.poolCategory.poolCount %>
+ </a>
+ <% } else { %>
+ <%- ctx.poolCategory.poolCount %>
+ <% } %>
+ </td>
+ <% if (ctx.canDelete) { %>
+ <td class='remove'>
+ <% if (ctx.poolCategory.poolCount) { %>
+ <a class='inactive' title="Can't delete category in use">Remove</a>
+ <% } else { %>
+ <a href>Remove</a>
+ <% } %>
+ </td>
+ <% } %>
+ <% if (ctx.canSetDefault) { %>
+ <td class='set-default'>
+ <a href>Make default</a>
+ </td>
+ <% } %>
+</tr>
diff --git a/client/html/pool_create.tpl b/client/html/pool_create.tpl
new file mode 100644
index 0000000..3c04545
--- /dev/null
+++ b/client/html/pool_create.tpl
@@ -0,0 +1,42 @@
+<div class='content-wrapper pool-create'>
+ <form>
+ <ul class='input'>
+ <li class='names'>
+ <%= ctx.makeTextInput({
+ text: 'Names',
+ value: '',
+ required: true,
+ }) %>
+ </li>
+ <li class='category'>
+ <%= ctx.makeSelect({
+ text: 'Category',
+ keyValues: ctx.categories,
+ selectedKey: 'default',
+ required: true,
+ }) %>
+ </li>
+ <li class='description'>
+ <%= ctx.makeTextarea({
+ text: 'Description',
+ value: '',
+ }) %>
+ </li>
+ <li class='posts'>
+ <%= ctx.makeTextInput({
+ text: 'Posts',
+ value: '',
+ placeholder: 'space-separated post IDs',
+ }) %>
+ </li>
+ </ul>
+
+ <% if (ctx.canCreate) { %>
+ <div class='messages'></div>
+
+ <div class='buttons'>
+ <input type='submit' class='save' value='Create pool'>
+ </div>
+ <% } %>
+ </form>
+</div>
diff --git a/client/html/pool_delete.tpl b/client/html/pool_delete.tpl
new file mode 100644
index 0000000..1ef7fb5
--- /dev/null
+++ b/client/html/pool_delete.tpl
@@ -0,0 +1,21 @@
+<div class='pool-delete'>
+ <form>
+ <p>This pool has <a href='<%- ctx.formatClientLink('posts', {query: 'pool:' + ctx.pool.id}) %>'><%- ctx.pool.postCount %> post(s)</a>.</p>
+
+ <ul class='input'>
+ <li>
+ <%= ctx.makeCheckbox({
+ name: 'confirm-deletion',
+ text: 'I confirm that I want to delete this pool.',
+ required: true,
+ }) %>
+ </li>
+ </ul>
+
+ <div class='messages'></div>
+
+ <div class='buttons'>
+ <input type='submit' value='Delete pool'/>
+ </div>
+ </form>
+</div>
diff --git a/client/html/pool_edit.tpl b/client/html/pool_edit.tpl
new file mode 100644
index 0000000..c9f2adb
--- /dev/null
+++ b/client/html/pool_edit.tpl
@@ -0,0 +1,50 @@
+<div class='content-wrapper pool-edit'>
+ <form>
+ <ul class='input'>
+ <li class='names'>
+ <% if (ctx.canEditNames) { %>
+ <%= ctx.makeTextInput({
+ text: 'Names',
+ value: ctx.pool.names.join(' '),
+ required: true,
+ }) %>
+ <% } %>
+ </li>
+ <li class='category'>
+ <% if (ctx.canEditCategory) { %>
+ <%= ctx.makeSelect({
+ text: 'Category',
+ keyValues: ctx.categories,
+ selectedKey: ctx.pool.category,
+ required: true,
+ }) %>
+ <% } %>
+ </li>
+ <li class='description'>
+ <% if (ctx.canEditDescription) { %>
+ <%= ctx.makeTextarea({
+ text: 'Description',
+ value: ctx.pool.description,
+ }) %>
+ <% } %>
+ </li>
+ <li class='posts'>
+ <% if (ctx.canEditPosts) { %>
+ <%= ctx.makeTextInput({
+ text: 'Posts',
+ placeholder: 'space-separated post IDs',
+ value: ctx.pool.posts.map(post => post.id).join(' ')
+ }) %>
+ <% } %>
+ </li>
+ </ul>
+
+ <% if (ctx.canEditAnything) { %>
+ <div class='messages'></div>
+
+ <div class='buttons'>
+ <input type='submit' class='save' value='Save changes'>
+ </div>
+ <% } %>
+ </form>
+</div>
diff --git a/client/html/pool_input.tpl b/client/html/pool_input.tpl
new file mode 100644
index 0000000..483e790
--- /dev/null
+++ b/client/html/pool_input.tpl
@@ -0,0 +1,7 @@
+<div class='pool-input'>
+ <div class='main-control'>
+ <input type='text' placeholder='type to add…'/>
+ </div>
+
+ <ul class='compact-pools'></ul>
+</div>
diff --git a/client/html/pool_merge.tpl b/client/html/pool_merge.tpl
new file mode 100644
index 0000000..ea5776a
--- /dev/null
+++ b/client/html/pool_merge.tpl
@@ -0,0 +1,22 @@
+<div class='pool-merge'>
+ <form>
+ <ul class='input'>
+ <li class='target'>
+ <%= ctx.makeTextInput({name: 'target-pool', required: true, text: 'Target pool', pattern: ctx.poolNamePattern}) %>
+ </li>
+
+ <li>
+ <p>Posts in the two pools will be combined.
+ Category needs to be handled manually.</p>
+
+ <%= ctx.makeCheckbox({required: true, text: 'I confirm that I want to merge this pool.'}) %>
+ </li>
+ </ul>
+
+ <div class='messages'></div>
+
+ <div class='buttons'>
+ <input type='submit' value='Merge pool'/>
+ </div>
+ </form>
+</div>
diff --git a/client/html/pool_summary.tpl b/client/html/pool_summary.tpl
new file mode 100644
index 0000000..2b70d27
--- /dev/null
+++ b/client/html/pool_summary.tpl
@@ -0,0 +1,23 @@
+<div class='content-wrapper pool-summary'>
+ <section class='details'>
+ <section>
+ Category:
+ <span class='<%= ctx.makeCssName(ctx.pool.category, 'pool') %>'><%- ctx.pool.category %></span>
+ </section>
+
+ <section>
+ Aliases:<br/>
+ <ul>
+ <% for (let name of ctx.pool.names.slice(1)) { %>
+ <li><%= ctx.makePoolLink(ctx.pool.id, false, false, ctx.pool, name) %></li>
+ <% } %>
+ </ul>
+ </section>
+ </section>
+
+ <section class='description'>
+ <hr/>
+ <%= ctx.makeMarkdown(ctx.pool.description || 'This pool has no description yet.') %>
+ <p>This pool has <a href='<%- ctx.formatClientLink('posts', {query: 'pool:' + ctx.pool.id}) %>'><%- ctx.pool.postCount %> post(s)</a>.</p>
+ </section>
+</div>
diff --git a/client/html/pools_header.tpl b/client/html/pools_header.tpl
new file mode 100644
index 0000000..c54959f
--- /dev/null
+++ b/client/html/pools_header.tpl
@@ -0,0 +1,22 @@
+<div class='pool-list-header'>
+ <form class='horizontal'>
+ <ul class='input'>
+ <li>
+ <%= ctx.makeTextInput({text: 'Search query', id: 'search-text', name: 'search-text', value: ctx.parameters.query}) %>
+ </li>
+ </ul>
+
+ <div class='buttons'>
+ <input type='submit' value='Search'/>
+ <a class='button append' href='<%- ctx.formatClientLink('help', 'search', 'pools') %>'>Syntax help</a>
+
+ <% if (ctx.canCreate) { %>
+ <a class='append' href='<%- ctx.formatClientLink('pool', 'create') %>'>Add new pool</a>
+ <% } %>
+
+ <% if (ctx.canEditPoolCategories) { %>
+ <a class='append' href='<%- ctx.formatClientLink('pool-categories') %>'>Pool categories</a>
+ <% } %>
+ </div>
+ </form>
+</div>
diff --git a/client/html/pools_page.tpl b/client/html/pools_page.tpl
new file mode 100644
index 0000000..0d81180
--- /dev/null
+++ b/client/html/pools_page.tpl
@@ -0,0 +1,48 @@
+<div class='pool-list table-wrap'>
+ <% if (ctx.response.results.length) { %>
+ <table>
+ <thead>
+ <th class='names'>
+ <% if (ctx.parameters.query == 'sort:name' || !ctx.parameters.query) { %>
+ <a href='<%- ctx.formatClientLink('pools', {query: '-sort:name'}) %>'>Pool name(s)</a>
+ <% } else { %>
+ <a href='<%- ctx.formatClientLink('pools', {query: 'sort:name'}) %>'>Pool name(s)</a>
+ <% } %>
+ </th>
+ <th class='post-count'>
+ <% if (ctx.parameters.query == 'sort:post-count') { %>
+ <a href='<%- ctx.formatClientLink('pools', {query: '-sort:post-count'}) %>'>Post count</a>
+ <% } else { %>
+ <a href='<%- ctx.formatClientLink('pools', {query: 'sort:post-count'}) %>'>Post count</a>
+ <% } %>
+ </th>
+ <th class='creation-time'>
+ <% if (ctx.parameters.query == 'sort:creation-time') { %>
+ <a href='<%- ctx.formatClientLink('pools', {query: '-sort:creation-time'}) %>'>Created on</a>
+ <% } else { %>
+ <a href='<%- ctx.formatClientLink('pools', {query: 'sort:creation-time'}) %>'>Created on</a>
+ <% } %>
+ </th>
+ </thead>
+ <tbody>
+ <% for (let pool of ctx.response.results) { %>
+ <tr>
+ <td class='names'>
+ <ul>
+ <% for (let name of pool.names) { %>
+ <li><%= ctx.makePoolLink(pool.id, false, false, pool, name) %></li>
+ <% } %>
+ </ul>
+ </td>
+ <td class='post-count'>
+ <a href='<%- ctx.formatClientLink('posts', {query: 'pool:' + pool.id}) %>'><%- pool.postCount %></a>
+ </td>
+ <td class='creation-time'>
+ <%= ctx.makeRelativeTime(pool.creationTime) %>
+ </td>
+ </tr>
+ <% } %>
+ </tbody>
+ </table>
+ <% } %>
+</div>
diff --git a/client/html/post_edit_sidebar.tpl b/client/html/post_edit_sidebar.tpl
index ecc6569..07dcf6f 100644
--- a/client/html/post_edit_sidebar.tpl
+++ b/client/html/post_edit_sidebar.tpl
@@ -73,6 +73,12 @@
</section>
<% } %>
+ <% if (ctx.canEditPoolPosts) { %>
+ <section class='pools'>
+ <%= ctx.makeTextInput({}) %>
+ </section>
+ <% } %>
+
<% if (ctx.canEditPostNotes) { %>
<section class='notes'>
<a href class='add'>Add a note</a>
diff --git a/client/html/tags_page.tpl b/client/html/tags_page.tpl
index 8c97398..2e08239 100644
--- a/client/html/tags_page.tpl
+++ b/client/html/tags_page.tpl
@@ -3,35 +3,35 @@
<table>
<thead>
<th class='names'>
- <% if (ctx.query == 'sort:name' || !ctx.query) { %>
+ <% if (ctx.parameters.query == 'sort:name' || !ctx.parameters.query) { %>
<a href='<%- ctx.formatClientLink('tags', {query: '-sort:name'}) %>'>Tag name(s)</a>
<% } else { %>
<a href='<%- ctx.formatClientLink('tags', {query: 'sort:name'}) %>'>Tag name(s)</a>
<% } %>
</th>
<th class='implications'>
- <% if (ctx.query == 'sort:implication-count') { %>
+ <% if (ctx.parameters.query == 'sort:implication-count') { %>
<a href='<%- ctx.formatClientLink('tags', {query: '-sort:implication-count'}) %>'>Implications</a>
<% } else { %>
<a href='<%- ctx.formatClientLink('tags', {query: 'sort:implication-count'}) %>'>Implications</a>
<% } %>
</th>
<th class='suggestions'>
- <% if (ctx.query == 'sort:suggestion-count') { %>
+ <% if (ctx.parameters.query == 'sort:suggestion-count') { %>
<a href='<%- ctx.formatClientLink('tags', {query: '-sort:suggestion-count'}) %>'>Suggestions</a>
<% } else { %>
<a href='<%- ctx.formatClientLink('tags', {query: 'sort:suggestion-count'}) %>'>Suggestions</a>
<% } %>
</th>
<th class='usages'>
- <% if (ctx.query == 'sort:usages') { %>
+ <% if (ctx.parameters.query == 'sort:usages') { %>
<a href='<%- ctx.formatClientLink('tags', {query: '-sort:usages'}) %>'>Usages</a>
<% } else { %>
<a href='<%- ctx.formatClientLink('tags', {query: 'sort:usages'}) %>'>Usages</a>
<% } %>
</th>
<th class='creation-time'>
- <% if (ctx.query == 'sort:creation-time') { %>
+ <% if (ctx.parameters.query == 'sort:creation-time') { %>
<a href='<%- ctx.formatClientLink('tags', {query: '-sort:creation-time'}) %>'>Created on</a>
<% } else { %>
<a href='<%- ctx.formatClientLink('tags', {query: 'sort:creation-time'}) %>'>Created on</a>