Implement updating pools of a post from details sidebar

This commit is contained in:
Ruin0x11 2020-05-04 14:44:16 -07:00
parent 8795279a73
commit ffba010ae4
10 changed files with 79 additions and 35 deletions

View file

@ -301,8 +301,12 @@ function makeOutputDirs() {
makeOutputDirs();
bundleConfig();
if (!process.argv.includes('--no-binary-assets')) {
bundleBinaryAssets();
}
if (!process.argv.includes('--no-web-app-files')) {
bundleWebAppFiles();
}
if (!process.argv.includes('--no-html')) {
bundleHtml();
}

View file

@ -4,7 +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</a></li><!--
--><li data-name='pools'><a href='<%- ctx.formatClientLink('help', 'search', 'pools') %>'>Pools></li><!--
--></ul><!--
--></nav>

View file

@ -26,6 +26,7 @@
<%= ctx.makeTextInput({
text: 'Posts',
value: '',
placeholder: 'space-separated post IDs',
}) %>
</li>
</ul>

View file

@ -32,6 +32,7 @@
<% if (ctx.canEditPosts) { %>
<%= ctx.makeTextInput({
text: 'Posts',
placeholder: 'space-separated post IDs',
value: ctx.pool.posts.map(post => post.id).join(' ')
}) %>
<% } %>

View file

@ -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>
@ -87,12 +93,6 @@
</section>
<% } %>
<% if (ctx.canEditPoolPosts) { %>
<section class='pools'>
<%= ctx.makeTextInput({}) %>
</section>
<% } %>
<% if (ctx.canEditPostContent) { %>
<section class='post-content'>
<label>Content</label>

View file

@ -34,7 +34,7 @@ class PoolAutoCompleteControl extends AutoCompleteControl {
return new Promise((resolve, reject) => {
PoolList.search(
query, 0, this._options.maxResults,
['id', 'names', 'category', 'postCount'])
['id', 'names', 'category', 'postCount', 'version'])
.then(
response => resolve(
_poolListToMatches(response.results, this._options)),

View file

@ -80,27 +80,6 @@ class PoolInputControl extends events.EventTarget {
}
}
addPoolByText(text, source) {
for (let poolName of text.split(/\s+/).filter(word => word).reverse()) {
this.addPoolByName(poolName, source);
}
}
addPoolByName(name, source) {
name = name.trim();
if (!name) {
return;
}
return Pool.get(name).then(pool => {
return this.addPool(pool, source);
}, () => {
const pool = new Pool();
pool.names = [name];
pool.category = null;
return this.addPool(pool, source);
});
}
addPool(pool, source) {
if (source != SOURCE_INIT && this.pools.hasPoolId(pool.id)) {
return Promise.resolve();
@ -178,10 +157,11 @@ class PoolInputControl extends events.EventTarget {
}
searchLinkNode.setAttribute(
'href', uri.formatClientLink(
'posts', {query: uri.escapeColons(pool.names[0])}));
'posts', {query: "pool:" + pool.id}));
searchLinkNode.textContent = pool.names[0] + ' ';
searchLinkNode.addEventListener('click', e => {
e.preventDefault();
// TODO?
// e.preventDefault();
});
const usagesNode = document.createElement('span');

View file

@ -86,6 +86,10 @@ class AbstractList extends events.EventTarget {
return this._list.map(...args);
}
filter(...args) {
return this._list.filter(...args);
}
[Symbol.iterator]() {
return this._list[Symbol.iterator]();
}

View file

@ -96,6 +96,29 @@ class Post extends events.EventTarget {
});
}
_savePoolPosts() {
const difference = (a, b) => a.filter(post => !b.hasPoolId(post.id));
const added = difference(this.pools, this._orig._pools);
const removed = difference(this._orig._pools, this.pools);
let ops = [];
for (let pool of added) {
if (!pool.posts.hasPostId(this._id)) {
pool.posts.addById(this._id);
ops.push(pool.save());
}
}
for (let pool of removed) {
if (pool.posts.hasPostId(this._id)) {
pool.posts.removeById(this._id);
ops.push(pool.save());
}
}
return Promise.all(ops);
}
save(anonymous) {
const files = {};
const detail = {version: this._version};
@ -131,13 +154,18 @@ class Post extends events.EventTarget {
if (this._source !== this._orig._source) {
detail.source = this._source;
}
// TODO pools
let apiPromise = this._id ?
api.put(uri.formatApiLink('post', this.id), detail, files) :
api.post(uri.formatApiLink('posts'), detail, files);
return apiPromise.then(response => {
if (this._pools !== this._orig._pools) {
return this._savePoolPosts()
.then(() => Promise.resolve(response));
}
return Promise.resolve(response);
}).then(response => {
this._updateFromResponse(response);
this.dispatchEvent(
new CustomEvent('change', {detail: {post: this}}));
@ -149,6 +177,7 @@ class Post extends events.EventTarget {
this.dispatchEvent(
new CustomEvent('changeThumbnail', {detail: {post: this}}));
}
return Promise.resolve();
}, error => {
if (error.response &&

View file

@ -49,6 +49,31 @@ class PostList extends AbstractList {
return text.trim();
}
hasPostId(testId) {
for (let post of this._list) {
if (post.id === testId) {
return true;
}
}
return false;
}
addById(id) {
if (this.hasPostId(id)) {
return;
}
let post = new Post.fromResponse({id: id});
this.add(post);
}
removeById(testId) {
for (let post of this._list) {
if (post.id === testId) {
this.remove(post);
}
}
}
}
PostList._itemClass = Post;