mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-01-09 17:00:27 +00:00
MWS - added DELETE functionality to both Recipes and Bags
This commit is contained in:
parent
060bea89ae
commit
1758a9ce12
@ -13,23 +13,50 @@ description
|
|||||||
\*/
|
\*/
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
/*jslint node: true, browser: true */
|
/*jslint node: true, browser: true */
|
||||||
/*global $tw: false */
|
/*global $tw: false */
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
exports.method = "POST";
|
exports.method = "POST";
|
||||||
|
|
||||||
exports.path = /^\/bags$/;
|
exports.path = /^\/bags$/;
|
||||||
|
|
||||||
exports.bodyFormat = "www-form-urlencoded";
|
exports.bodyFormat = "www-form-urlencoded";
|
||||||
|
|
||||||
exports.csrfDisable = true;
|
exports.csrfDisable = true;
|
||||||
|
|
||||||
exports.useACL = true;
|
exports.useACL = true;
|
||||||
|
|
||||||
exports.entityName = "bag"
|
exports.entityName = "bag"
|
||||||
|
|
||||||
|
exports.handler = function(request,response,state) {
|
||||||
|
var server = state.server,
|
||||||
|
sqlTiddlerDatabase = server.sqlTiddlerDatabase;
|
||||||
|
|
||||||
|
// Handle DELETE request
|
||||||
|
if(state.data._method === "DELETE") {
|
||||||
|
if(state.data.bag_name) {
|
||||||
|
const result = $tw.mws.store.deleteBag(state.data.bag_name);
|
||||||
|
if(!result) {
|
||||||
|
state.sendResponse(302,{
|
||||||
|
"Content-Type": "text/plain",
|
||||||
|
"Location": "/"
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
state.sendResponse(400,{
|
||||||
|
"Content-Type": "text/plain"
|
||||||
|
},
|
||||||
|
result.message,
|
||||||
|
"utf8");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
state.sendResponse(400,{
|
||||||
|
"Content-Type": "text/plain"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
exports.handler = function(request,response,state) {
|
|
||||||
if(state.data.bag_name) {
|
if(state.data.bag_name) {
|
||||||
const result = $tw.mws.store.createBag(state.data.bag_name,state.data.description);
|
const result = $tw.mws.store.createBag(state.data.bag_name,state.data.description);
|
||||||
if(!result) {
|
if(!result) {
|
||||||
@ -49,6 +76,7 @@ exports.handler = function(request,response,state) {
|
|||||||
"Content-Type": "text/plain"
|
"Content-Type": "text/plain"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}());
|
||||||
|
|
||||||
}());
|
|
||||||
|
@ -4,9 +4,9 @@ type: application/javascript
|
|||||||
module-type: mws-route
|
module-type: mws-route
|
||||||
|
|
||||||
POST /recipes
|
POST /recipes
|
||||||
|
DELETE /recipes (via _method=DELETE)
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
|
|
||||||
recipe_name
|
recipe_name
|
||||||
description
|
description
|
||||||
bag_names: space separated list of bags
|
bag_names: space separated list of bags
|
||||||
@ -14,25 +14,51 @@ bag_names: space separated list of bags
|
|||||||
\*/
|
\*/
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
/*jslint node: true, browser: true */
|
/*jslint node: true, browser: true */
|
||||||
/*global $tw: false */
|
/*global $tw: false */
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
exports.method = "POST";
|
exports.method = "POST";
|
||||||
|
|
||||||
exports.path = /^\/recipes$/;
|
exports.path = /^\/recipes$/;
|
||||||
|
|
||||||
exports.bodyFormat = "www-form-urlencoded";
|
exports.bodyFormat = "www-form-urlencoded";
|
||||||
|
|
||||||
exports.csrfDisable = true;
|
exports.csrfDisable = true;
|
||||||
|
|
||||||
exports.useACL = true;
|
exports.useACL = true;
|
||||||
|
|
||||||
exports.entityName = "recipe"
|
exports.entityName = "recipe"
|
||||||
|
|
||||||
exports.handler = function(request,response,state) {
|
exports.handler = function(request,response,state) {
|
||||||
var server = state.server,
|
var server = state.server,
|
||||||
sqlTiddlerDatabase = server.sqlTiddlerDatabase
|
sqlTiddlerDatabase = server.sqlTiddlerDatabase;
|
||||||
|
|
||||||
|
// Check and handle if this is a DELETE request
|
||||||
|
if(state.data._method === "DELETE") {
|
||||||
|
if(state.data.recipe_name && state.data.bag_names) {
|
||||||
|
const result = sqlTiddlerDatabase.deleteRecipe(state.data.recipe_name);
|
||||||
|
if(!result) {
|
||||||
|
state.sendResponse(302,{
|
||||||
|
"Content-Type": "text/plain",
|
||||||
|
"Location": "/"
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
state.sendResponse(400,{
|
||||||
|
"Content-Type": "text/plain"
|
||||||
|
},
|
||||||
|
result.message,
|
||||||
|
"utf8");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
state.sendResponse(400,{
|
||||||
|
"Content-Type": "text/plain"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle POST request (original code)
|
||||||
if(state.data.recipe_name && state.data.bag_names) {
|
if(state.data.recipe_name && state.data.bag_names) {
|
||||||
const result = $tw.mws.store.createRecipe(state.data.recipe_name,$tw.utils.parseStringArray(state.data.bag_names),state.data.description);
|
const result = $tw.mws.store.createRecipe(state.data.recipe_name,$tw.utils.parseStringArray(state.data.bag_names),state.data.description);
|
||||||
if(!result) {
|
if(!result) {
|
||||||
@ -55,6 +81,6 @@ exports.handler = function(request,response,state) {
|
|||||||
"Content-Type": "text/plain"
|
"Content-Type": "text/plain"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}());
|
}());
|
File diff suppressed because it is too large
Load Diff
@ -15,15 +15,15 @@ This class is largely a wrapper for the sql-tiddler-database.js class, adding th
|
|||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Create a tiddler store. Options include:
|
Create a tiddler store. Options include:
|
||||||
|
|
||||||
databasePath - path to the database file (can be ":memory:" to get a temporary database)
|
databasePath - path to the database file (can be ":memory:" to get a temporary database)
|
||||||
adminWiki - reference to $tw.Wiki object used for configuration
|
adminWiki - reference to $tw.Wiki object used for configuration
|
||||||
attachmentStore - reference to associated attachment store
|
attachmentStore - reference to associated attachment store
|
||||||
engine - wasm | better
|
engine - wasm | better
|
||||||
*/
|
*/
|
||||||
function SqlTiddlerStore(options) {
|
function SqlTiddlerStore(options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
this.attachmentStore = options.attachmentStore;
|
this.attachmentStore = options.attachmentStore;
|
||||||
this.adminWiki = options.adminWiki || $tw.wiki;
|
this.adminWiki = options.adminWiki || $tw.wiki;
|
||||||
@ -37,14 +37,14 @@ function SqlTiddlerStore(options) {
|
|||||||
engine: options.engine
|
engine: options.engine
|
||||||
});
|
});
|
||||||
this.sqlTiddlerDatabase.createTables();
|
this.sqlTiddlerDatabase.createTables();
|
||||||
}
|
}
|
||||||
|
|
||||||
SqlTiddlerStore.prototype.addEventListener = function(type,listener) {
|
SqlTiddlerStore.prototype.addEventListener = function(type,listener) {
|
||||||
this.eventListeners[type] = this.eventListeners[type] || [];
|
this.eventListeners[type] = this.eventListeners[type] || [];
|
||||||
this.eventListeners[type].push(listener);
|
this.eventListeners[type].push(listener);
|
||||||
};
|
};
|
||||||
|
|
||||||
SqlTiddlerStore.prototype.removeEventListener = function(type,listener) {
|
SqlTiddlerStore.prototype.removeEventListener = function(type,listener) {
|
||||||
const listeners = this.eventListeners[type];
|
const listeners = this.eventListeners[type];
|
||||||
if(listeners) {
|
if(listeners) {
|
||||||
var p = listeners.indexOf(listener);
|
var p = listeners.indexOf(listener);
|
||||||
@ -52,9 +52,9 @@ SqlTiddlerStore.prototype.removeEventListener = function(type,listener) {
|
|||||||
listeners.splice(p,1);
|
listeners.splice(p,1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
SqlTiddlerStore.prototype.dispatchEvent = function(type /*, args */) {
|
SqlTiddlerStore.prototype.dispatchEvent = function(type /*, args */) {
|
||||||
const self = this;
|
const self = this;
|
||||||
if(!this.eventOutstanding[type]) {
|
if(!this.eventOutstanding[type]) {
|
||||||
$tw.utils.nextTick(function() {
|
$tw.utils.nextTick(function() {
|
||||||
@ -70,12 +70,12 @@ SqlTiddlerStore.prototype.dispatchEvent = function(type /*, args */) {
|
|||||||
});
|
});
|
||||||
this.eventOutstanding[type] = true;
|
this.eventOutstanding[type] = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Returns null if a bag/recipe name is valid, or a string error message if not
|
Returns null if a bag/recipe name is valid, or a string error message if not
|
||||||
*/
|
*/
|
||||||
SqlTiddlerStore.prototype.validateItemName = function(name,allowPrivilegedCharacters) {
|
SqlTiddlerStore.prototype.validateItemName = function(name,allowPrivilegedCharacters) {
|
||||||
if(typeof name !== "string") {
|
if(typeof name !== "string") {
|
||||||
return "Not a valid string";
|
return "Not a valid string";
|
||||||
}
|
}
|
||||||
@ -93,12 +93,52 @@ SqlTiddlerStore.prototype.validateItemName = function(name,allowPrivilegedCharac
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Returns null if the argument is an array of valid bag/recipe names, or a string error message if not
|
Delete a recipe. Returns null on success, or {message:} on error
|
||||||
*/
|
*/
|
||||||
SqlTiddlerStore.prototype.validateItemNames = function(names,allowPrivilegedCharacters) {
|
SqlTiddlerStore.prototype.deleteRecipe = function(recipe_name) {
|
||||||
|
var self = this;
|
||||||
|
return this.sqlTiddlerDatabase.transaction(function() {
|
||||||
|
// Check if recipe exists
|
||||||
|
const recipes = self.sqlTiddlerDatabase.listRecipes();
|
||||||
|
const recipeExists = recipes.some(recipe => recipe.recipe_name === recipe_name);
|
||||||
|
if(!recipeExists) {
|
||||||
|
return {message: "Recipe does not exist"};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the recipe
|
||||||
|
self.sqlTiddlerDatabase.deleteRecipe(recipe_name);
|
||||||
|
self.dispatchEvent("change");
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Delete a bag. Returns null on success, or {message:} on error
|
||||||
|
*/
|
||||||
|
SqlTiddlerStore.prototype.deleteBag = function(bag_name) {
|
||||||
|
var self = this;
|
||||||
|
return this.sqlTiddlerDatabase.transaction(function() {
|
||||||
|
// Check if bag exists
|
||||||
|
const bags = self.sqlTiddlerDatabase.listBags();
|
||||||
|
const bagExists = bags.some(bag => bag.bag_name === bag_name);
|
||||||
|
if(!bagExists) {
|
||||||
|
return {message: "Bag does not exist"};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the bag
|
||||||
|
self.sqlTiddlerDatabase.deleteBag(bag_name);
|
||||||
|
self.dispatchEvent("change");
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Returns null if the argument is an array of valid bag/recipe names, or a string error message if not
|
||||||
|
*/
|
||||||
|
SqlTiddlerStore.prototype.validateItemNames = function(names,allowPrivilegedCharacters) {
|
||||||
if(!$tw.utils.isArray(names)) {
|
if(!$tw.utils.isArray(names)) {
|
||||||
return "Not a valid array";
|
return "Not a valid array";
|
||||||
}
|
}
|
||||||
@ -114,19 +154,19 @@ SqlTiddlerStore.prototype.validateItemNames = function(names,allowPrivilegedChar
|
|||||||
} else {
|
} else {
|
||||||
return errors.join("\n");
|
return errors.join("\n");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
SqlTiddlerStore.prototype.close = function() {
|
SqlTiddlerStore.prototype.close = function() {
|
||||||
this.sqlTiddlerDatabase.close();
|
this.sqlTiddlerDatabase.close();
|
||||||
this.sqlTiddlerDatabase = undefined;
|
this.sqlTiddlerDatabase = undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Given tiddler fields, tiddler_id and a bag_name, return the tiddler fields after the following process:
|
Given tiddler fields, tiddler_id and a bag_name, return the tiddler fields after the following process:
|
||||||
- Apply the tiddler_id as the revision field
|
- Apply the tiddler_id as the revision field
|
||||||
- Apply the bag_name as the bag field
|
- Apply the bag_name as the bag field
|
||||||
*/
|
*/
|
||||||
SqlTiddlerStore.prototype.processOutgoingTiddler = function(tiddlerFields,tiddler_id,bag_name,attachment_blob) {
|
SqlTiddlerStore.prototype.processOutgoingTiddler = function(tiddlerFields,tiddler_id,bag_name,attachment_blob) {
|
||||||
if(attachment_blob !== null) {
|
if(attachment_blob !== null) {
|
||||||
return $tw.utils.extend(
|
return $tw.utils.extend(
|
||||||
{},
|
{},
|
||||||
@ -139,11 +179,11 @@ SqlTiddlerStore.prototype.processOutgoingTiddler = function(tiddlerFields,tiddle
|
|||||||
} else {
|
} else {
|
||||||
return tiddlerFields;
|
return tiddlerFields;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*/
|
*/
|
||||||
SqlTiddlerStore.prototype.processIncomingTiddler = function(tiddlerFields, existing_attachment_blob, existing_canonical_uri) {
|
SqlTiddlerStore.prototype.processIncomingTiddler = function(tiddlerFields, existing_attachment_blob, existing_canonical_uri) {
|
||||||
let attachmentSizeLimit = $tw.utils.parseNumber(this.adminWiki.getTiddlerText("$:/config/MultiWikiServer/AttachmentSizeLimit"));
|
let attachmentSizeLimit = $tw.utils.parseNumber(this.adminWiki.getTiddlerText("$:/config/MultiWikiServer/AttachmentSizeLimit"));
|
||||||
if(attachmentSizeLimit < 100 * 1024) {
|
if(attachmentSizeLimit < 100 * 1024) {
|
||||||
attachmentSizeLimit = 100 * 1024;
|
attachmentSizeLimit = 100 * 1024;
|
||||||
@ -188,9 +228,9 @@ SqlTiddlerStore.prototype.processIncomingTiddler = function(tiddlerFields, exist
|
|||||||
attachment_blob: existing_attachment_blob
|
attachment_blob: existing_attachment_blob
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
SqlTiddlerStore.prototype.saveTiddlersFromPath = function(tiddler_files_path,bag_name) {
|
SqlTiddlerStore.prototype.saveTiddlersFromPath = function(tiddler_files_path,bag_name) {
|
||||||
var self = this;
|
var self = this;
|
||||||
this.sqlTiddlerDatabase.transaction(function() {
|
this.sqlTiddlerDatabase.transaction(function() {
|
||||||
// Clear out the bag
|
// Clear out the bag
|
||||||
@ -206,18 +246,18 @@ SqlTiddlerStore.prototype.saveTiddlersFromPath = function(tiddler_files_path,bag
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
self.dispatchEvent("change");
|
self.dispatchEvent("change");
|
||||||
};
|
};
|
||||||
|
|
||||||
SqlTiddlerStore.prototype.listBags = function() {
|
SqlTiddlerStore.prototype.listBags = function() {
|
||||||
return this.sqlTiddlerDatabase.listBags();
|
return this.sqlTiddlerDatabase.listBags();
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Options include:
|
Options include:
|
||||||
|
|
||||||
allowPrivilegedCharacters - allows "$", ":" and "/" to appear in recipe name
|
allowPrivilegedCharacters - allows "$", ":" and "/" to appear in recipe name
|
||||||
*/
|
*/
|
||||||
SqlTiddlerStore.prototype.createBag = function(bag_name,description,options) {
|
SqlTiddlerStore.prototype.createBag = function(bag_name,description,options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var self = this;
|
var self = this;
|
||||||
return this.sqlTiddlerDatabase.transaction(function() {
|
return this.sqlTiddlerDatabase.transaction(function() {
|
||||||
@ -229,20 +269,20 @@ SqlTiddlerStore.prototype.createBag = function(bag_name,description,options) {
|
|||||||
self.dispatchEvent("change");
|
self.dispatchEvent("change");
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
SqlTiddlerStore.prototype.listRecipes = function() {
|
SqlTiddlerStore.prototype.listRecipes = function() {
|
||||||
return this.sqlTiddlerDatabase.listRecipes();
|
return this.sqlTiddlerDatabase.listRecipes();
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Returns null on success, or {message:} on error
|
Returns null on success, or {message:} on error
|
||||||
|
|
||||||
Options include:
|
Options include:
|
||||||
|
|
||||||
allowPrivilegedCharacters - allows "$", ":" and "/" to appear in recipe name
|
allowPrivilegedCharacters - allows "$", ":" and "/" to appear in recipe name
|
||||||
*/
|
*/
|
||||||
SqlTiddlerStore.prototype.createRecipe = function(recipe_name,bag_names,description,options) {
|
SqlTiddlerStore.prototype.createRecipe = function(recipe_name,bag_names,description,options) {
|
||||||
bag_names = bag_names || [];
|
bag_names = bag_names || [];
|
||||||
description = description || "";
|
description = description || "";
|
||||||
options = options || {};
|
options = options || {};
|
||||||
@ -259,12 +299,12 @@ SqlTiddlerStore.prototype.createRecipe = function(recipe_name,bag_names,descript
|
|||||||
self.dispatchEvent("change");
|
self.dispatchEvent("change");
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Returns {tiddler_id:}
|
Returns {tiddler_id:}
|
||||||
*/
|
*/
|
||||||
SqlTiddlerStore.prototype.saveBagTiddler = function(incomingTiddlerFields,bag_name) {
|
SqlTiddlerStore.prototype.saveBagTiddler = function(incomingTiddlerFields,bag_name) {
|
||||||
let _canonical_uri;
|
let _canonical_uri;
|
||||||
const existing_attachment_blob = this.sqlTiddlerDatabase.getBagTiddlerAttachmentBlob(incomingTiddlerFields.title,bag_name)
|
const existing_attachment_blob = this.sqlTiddlerDatabase.getBagTiddlerAttachmentBlob(incomingTiddlerFields.title,bag_name)
|
||||||
if(existing_attachment_blob) {
|
if(existing_attachment_blob) {
|
||||||
@ -274,19 +314,19 @@ SqlTiddlerStore.prototype.saveBagTiddler = function(incomingTiddlerFields,bag_na
|
|||||||
const result = this.sqlTiddlerDatabase.saveBagTiddler(tiddlerFields,bag_name,attachment_blob);
|
const result = this.sqlTiddlerDatabase.saveBagTiddler(tiddlerFields,bag_name,attachment_blob);
|
||||||
this.dispatchEvent("change");
|
this.dispatchEvent("change");
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Create a tiddler in a bag adopting the specified file as the attachment. The attachment file must be on the same disk as the attachment store
|
Create a tiddler in a bag adopting the specified file as the attachment. The attachment file must be on the same disk as the attachment store
|
||||||
Options include:
|
Options include:
|
||||||
|
|
||||||
filepath - filepath to the attachment file
|
filepath - filepath to the attachment file
|
||||||
hash - string hash of the attachment file
|
hash - string hash of the attachment file
|
||||||
type - content type of file as uploaded
|
type - content type of file as uploaded
|
||||||
|
|
||||||
Returns {tiddler_id:}
|
Returns {tiddler_id:}
|
||||||
*/
|
*/
|
||||||
SqlTiddlerStore.prototype.saveBagTiddlerWithAttachment = function(incomingTiddlerFields,bag_name,options) {
|
SqlTiddlerStore.prototype.saveBagTiddlerWithAttachment = function(incomingTiddlerFields,bag_name,options) {
|
||||||
const attachment_blob = this.attachmentStore.adoptAttachment(options.filepath,options.type,options.hash,options._canonical_uri);
|
const attachment_blob = this.attachmentStore.adoptAttachment(options.filepath,options.type,options.hash,options._canonical_uri);
|
||||||
if(attachment_blob) {
|
if(attachment_blob) {
|
||||||
const result = this.sqlTiddlerDatabase.saveBagTiddler(incomingTiddlerFields,bag_name,attachment_blob);
|
const result = this.sqlTiddlerDatabase.saveBagTiddler(incomingTiddlerFields,bag_name,attachment_blob);
|
||||||
@ -295,29 +335,29 @@ SqlTiddlerStore.prototype.saveBagTiddlerWithAttachment = function(incomingTiddle
|
|||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Returns {tiddler_id:,bag_name:}
|
Returns {tiddler_id:,bag_name:}
|
||||||
*/
|
*/
|
||||||
SqlTiddlerStore.prototype.saveRecipeTiddler = function(incomingTiddlerFields,recipe_name) {
|
SqlTiddlerStore.prototype.saveRecipeTiddler = function(incomingTiddlerFields,recipe_name) {
|
||||||
const existing_attachment_blob = this.sqlTiddlerDatabase.getRecipeTiddlerAttachmentBlob(incomingTiddlerFields.title,recipe_name)
|
const existing_attachment_blob = this.sqlTiddlerDatabase.getRecipeTiddlerAttachmentBlob(incomingTiddlerFields.title,recipe_name)
|
||||||
const {tiddlerFields, attachment_blob} = this.processIncomingTiddler(incomingTiddlerFields,existing_attachment_blob,incomingTiddlerFields._canonical_uri);
|
const {tiddlerFields, attachment_blob} = this.processIncomingTiddler(incomingTiddlerFields,existing_attachment_blob,incomingTiddlerFields._canonical_uri);
|
||||||
const result = this.sqlTiddlerDatabase.saveRecipeTiddler(tiddlerFields,recipe_name,attachment_blob);
|
const result = this.sqlTiddlerDatabase.saveRecipeTiddler(tiddlerFields,recipe_name,attachment_blob);
|
||||||
this.dispatchEvent("change");
|
this.dispatchEvent("change");
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
SqlTiddlerStore.prototype.deleteTiddler = function(title,bag_name) {
|
SqlTiddlerStore.prototype.deleteTiddler = function(title,bag_name) {
|
||||||
const result = this.sqlTiddlerDatabase.deleteTiddler(title,bag_name);
|
const result = this.sqlTiddlerDatabase.deleteTiddler(title,bag_name);
|
||||||
this.dispatchEvent("change");
|
this.dispatchEvent("change");
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
returns {tiddler_id:,tiddler:}
|
returns {tiddler_id:,tiddler:}
|
||||||
*/
|
*/
|
||||||
SqlTiddlerStore.prototype.getBagTiddler = function(title,bag_name) {
|
SqlTiddlerStore.prototype.getBagTiddler = function(title,bag_name) {
|
||||||
var tiddlerInfo = this.sqlTiddlerDatabase.getBagTiddler(title,bag_name);
|
var tiddlerInfo = this.sqlTiddlerDatabase.getBagTiddler(title,bag_name);
|
||||||
if(tiddlerInfo) {
|
if(tiddlerInfo) {
|
||||||
return Object.assign(
|
return Object.assign(
|
||||||
@ -329,16 +369,16 @@ SqlTiddlerStore.prototype.getBagTiddler = function(title,bag_name) {
|
|||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get an attachment ready to stream. Returns null if there is an error or:
|
Get an attachment ready to stream. Returns null if there is an error or:
|
||||||
tiddler_id: revision of tiddler
|
tiddler_id: revision of tiddler
|
||||||
stream: stream of file
|
stream: stream of file
|
||||||
type: type of file
|
type: type of file
|
||||||
Returns {tiddler_id:,bag_name:}
|
Returns {tiddler_id:,bag_name:}
|
||||||
*/
|
*/
|
||||||
SqlTiddlerStore.prototype.getBagTiddlerStream = function(title,bag_name) {
|
SqlTiddlerStore.prototype.getBagTiddlerStream = function(title,bag_name) {
|
||||||
const tiddlerInfo = this.sqlTiddlerDatabase.getBagTiddler(title,bag_name);
|
const tiddlerInfo = this.sqlTiddlerDatabase.getBagTiddler(title,bag_name);
|
||||||
if(tiddlerInfo) {
|
if(tiddlerInfo) {
|
||||||
if(tiddlerInfo.attachment_blob) {
|
if(tiddlerInfo.attachment_blob) {
|
||||||
@ -370,12 +410,12 @@ SqlTiddlerStore.prototype.getBagTiddlerStream = function(title,bag_name) {
|
|||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Returns {bag_name:, tiddler: {fields}, tiddler_id:}
|
Returns {bag_name:, tiddler: {fields}, tiddler_id:}
|
||||||
*/
|
*/
|
||||||
SqlTiddlerStore.prototype.getRecipeTiddler = function(title,recipe_name) {
|
SqlTiddlerStore.prototype.getRecipeTiddler = function(title,recipe_name) {
|
||||||
var tiddlerInfo = this.sqlTiddlerDatabase.getRecipeTiddler(title,recipe_name);
|
var tiddlerInfo = this.sqlTiddlerDatabase.getRecipeTiddler(title,recipe_name);
|
||||||
if(tiddlerInfo) {
|
if(tiddlerInfo) {
|
||||||
return Object.assign(
|
return Object.assign(
|
||||||
@ -387,52 +427,52 @@ SqlTiddlerStore.prototype.getRecipeTiddler = function(title,recipe_name) {
|
|||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get the titles of the tiddlers in a bag. Returns an empty array for bags that do not exist
|
Get the titles of the tiddlers in a bag. Returns an empty array for bags that do not exist
|
||||||
*/
|
*/
|
||||||
SqlTiddlerStore.prototype.getBagTiddlers = function(bag_name) {
|
SqlTiddlerStore.prototype.getBagTiddlers = function(bag_name) {
|
||||||
return this.sqlTiddlerDatabase.getBagTiddlers(bag_name);
|
return this.sqlTiddlerDatabase.getBagTiddlers(bag_name);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get the tiddler_id of the newest tiddler in a bag. Returns null for bags that do not exist
|
Get the tiddler_id of the newest tiddler in a bag. Returns null for bags that do not exist
|
||||||
*/
|
*/
|
||||||
SqlTiddlerStore.prototype.getBagLastTiddlerId = function(bag_name) {
|
SqlTiddlerStore.prototype.getBagLastTiddlerId = function(bag_name) {
|
||||||
return this.sqlTiddlerDatabase.getBagLastTiddlerId(bag_name);
|
return this.sqlTiddlerDatabase.getBagLastTiddlerId(bag_name);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get the titles of the tiddlers in a recipe as {title:,bag_name:}. Returns null for recipes that do not exist
|
Get the titles of the tiddlers in a recipe as {title:,bag_name:}. Returns null for recipes that do not exist
|
||||||
*/
|
*/
|
||||||
SqlTiddlerStore.prototype.getRecipeTiddlers = function(recipe_name,options) {
|
SqlTiddlerStore.prototype.getRecipeTiddlers = function(recipe_name,options) {
|
||||||
return this.sqlTiddlerDatabase.getRecipeTiddlers(recipe_name,options);
|
return this.sqlTiddlerDatabase.getRecipeTiddlers(recipe_name,options);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get the tiddler_id of the newest tiddler in a recipe. Returns null for recipes that do not exist
|
Get the tiddler_id of the newest tiddler in a recipe. Returns null for recipes that do not exist
|
||||||
*/
|
*/
|
||||||
SqlTiddlerStore.prototype.getRecipeLastTiddlerId = function(recipe_name) {
|
SqlTiddlerStore.prototype.getRecipeLastTiddlerId = function(recipe_name) {
|
||||||
return this.sqlTiddlerDatabase.getRecipeLastTiddlerId(recipe_name);
|
return this.sqlTiddlerDatabase.getRecipeLastTiddlerId(recipe_name);
|
||||||
};
|
};
|
||||||
|
|
||||||
SqlTiddlerStore.prototype.deleteAllTiddlersInBag = function(bag_name) {
|
SqlTiddlerStore.prototype.deleteAllTiddlersInBag = function(bag_name) {
|
||||||
var self = this;
|
var self = this;
|
||||||
return this.sqlTiddlerDatabase.transaction(function() {
|
return this.sqlTiddlerDatabase.transaction(function() {
|
||||||
const result = self.sqlTiddlerDatabase.deleteAllTiddlersInBag(bag_name);
|
const result = self.sqlTiddlerDatabase.deleteAllTiddlersInBag(bag_name);
|
||||||
self.dispatchEvent("change");
|
self.dispatchEvent("change");
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get the names of the bags in a recipe. Returns an empty array for recipes that do not exist
|
Get the names of the bags in a recipe. Returns an empty array for recipes that do not exist
|
||||||
*/
|
*/
|
||||||
SqlTiddlerStore.prototype.getRecipeBags = function(recipe_name) {
|
SqlTiddlerStore.prototype.getRecipeBags = function(recipe_name) {
|
||||||
return this.sqlTiddlerDatabase.getRecipeBags(recipe_name);
|
return this.sqlTiddlerDatabase.getRecipeBags(recipe_name);
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.SqlTiddlerStore = SqlTiddlerStore;
|
exports.SqlTiddlerStore = SqlTiddlerStore;
|
||||||
|
|
||||||
})();
|
})();
|
@ -87,6 +87,14 @@ title: $:/plugins/tiddlywiki/multiwikiserver/templates/get-index
|
|||||||
<div class="mws-wiki-card-description">
|
<div class="mws-wiki-card-description">
|
||||||
<$text text={{{ [<recipe-info>jsonget[description]] }}}/>
|
<$text text={{{ [<recipe-info>jsonget[description]] }}}/>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mws-wiki-card-actions">
|
||||||
|
<form action="/recipes" method="post">
|
||||||
|
<input type="hidden" name="_method" value="DELETE"/>
|
||||||
|
<input type="hidden" name="recipe_name" value={{{ [<recipe-info>jsonget[recipe_name]] }}}/>
|
||||||
|
<input type="hidden" name="bag_names" value={{{ [<recipe-info>jsonget[bag_names]join[ ]] }}}/>
|
||||||
|
<button type="submit" class="mws-delete-button">Delete Recipe</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</$let>
|
</$let>
|
||||||
@ -133,8 +141,15 @@ title: $:/plugins/tiddlywiki/multiwikiserver/templates/get-index
|
|||||||
>
|
>
|
||||||
<$transclude $variable="bagPill"/>
|
<$transclude $variable="bagPill"/>
|
||||||
<$text text={{{ [<bag-info>jsonget[description]] }}}/>
|
<$text text={{{ [<bag-info>jsonget[description]] }}}/>
|
||||||
|
<div class="mws-wiki-card-actions">
|
||||||
|
<form action="/bags" method="post" onsubmit="return confirmBagDelete(this)">
|
||||||
|
<input type="hidden" name="_method" value="DELETE"/>
|
||||||
|
<input type="hidden" name="bag_name" value={{{ [<bag-info>jsonget[bag_name]] }}}/>
|
||||||
|
<button type="submit" class="mws-delete-button">Delete Bag</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</$let>
|
</$let>
|
||||||
</li>
|
</li>
|
||||||
</$list>
|
</$list>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@ -241,6 +256,27 @@ title: $:/plugins/tiddlywiki/multiwikiserver/templates/get-index
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mws-delete-button {
|
||||||
|
background-color: #f44336;
|
||||||
|
color: white;
|
||||||
|
padding: 5px 10px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mws-delete-button:hover {
|
||||||
|
background-color: #d32f2f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mws-wiki-card-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
.mws-admin-dropdown-content a:hover {background-color: #ddd;}
|
.mws-admin-dropdown-content a:hover {background-color: #ddd;}
|
||||||
|
|
||||||
.mws-admin-dropdown:hover .mws-admin-dropdown-content {display: block;}
|
.mws-admin-dropdown:hover .mws-admin-dropdown-content {display: block;}
|
||||||
|
Loading…
Reference in New Issue
Block a user