mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-01-05 23:10:28 +00:00
Add support for bag descriptions, validate bags and recipes, and complete the UI for creating bags and recipes
Styling to come
This commit is contained in:
parent
0b9749f3a4
commit
b0a67300cc
@ -1,107 +1,169 @@
|
||||
title: MultiWikiServer Administration
|
||||
|
||||
\procedure createBag(name)
|
||||
|
||||
\procedure completion-createBag()
|
||||
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
||||
<$action-log msg="In completion-createBag"/>
|
||||
<$action-log/>
|
||||
\end completion-createBag
|
||||
|
||||
<$action-sendmessage
|
||||
$message="tm-http-request"
|
||||
url=`/wiki/$(name)$/bags/$(name)$`
|
||||
method="PUT"
|
||||
oncompletion=<<completion-createBag>>
|
||||
/>
|
||||
\procedure createBag(name,description)
|
||||
\procedure completion-createBag()
|
||||
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
||||
<$action-log msg="In completion-createBag"/>
|
||||
<$action-log/>
|
||||
\end completion-createBag
|
||||
<$action-sendmessage
|
||||
$message="tm-http-request"
|
||||
url=`/wiki/$(name)$/bags/$(name)$`
|
||||
method="PUT"
|
||||
body=`{"description":"${ [<description>encodeuricomponent[]] }$"}`
|
||||
oncompletion=<<completion-createBag>>
|
||||
/>
|
||||
\end createBag
|
||||
|
||||
\procedure createBagButton(name)
|
||||
<$button class="">
|
||||
<$transclude $variable="createBag" name={{$:/state/NewBagName}}/>
|
||||
{{$:/core/images/new-button}}
|
||||
</$button><span class="tc-btn-text"><$text text="Create a new bag:"/></span><$edit-text tiddler="$:/state/NewBagName" tag="input"/>
|
||||
\whitespace trim
|
||||
<form class="mws-form">
|
||||
<div class="mws-form-heading">
|
||||
<$text text="Create a new bag"/>
|
||||
</div>
|
||||
<div class="mws-form-fields">
|
||||
<div class="mws-form-field">
|
||||
<label class="mws-form-field-description">
|
||||
Bag name
|
||||
</label>
|
||||
<$edit-text tiddler="$:/state/NewBagName" tag="input" placeholder="(bag name)" class="mws-form-field-input"/>
|
||||
</div>
|
||||
<div class="mws-form-field">
|
||||
<label class="mws-form-field-description">
|
||||
Bag description
|
||||
</label>
|
||||
<$edit-text tiddler="$:/state/NewBagDescription" tag="input" placeholder="(description)" class="mws-form-field-input"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mws-form-buttons">
|
||||
<$button class="mws-form-button">
|
||||
<$transclude
|
||||
$variable="createBag"
|
||||
name={{$:/state/NewBagName}}
|
||||
description={{$:/state/NewBagDescription}}
|
||||
/>
|
||||
Create Bag
|
||||
</$button>
|
||||
</div>
|
||||
</form>
|
||||
\end createBagButton
|
||||
|
||||
\procedure createRecipe(name)
|
||||
|
||||
\procedure completion-createRecipe()
|
||||
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
||||
<$action-log msg="In completion-createRecipe"/>
|
||||
<$action-log/>
|
||||
\end completion-createRecipe
|
||||
|
||||
<$action-sendmessage
|
||||
$message="tm-http-request"
|
||||
url=`/wiki/$(name)$/recipes/$(name)$`
|
||||
method="PUT"
|
||||
oncompletion=<<completion-createRecipe>>
|
||||
/>
|
||||
\procedure createRecipe(name,bag_names,description)
|
||||
\procedure completion-createRecipe()
|
||||
\import [subfilter{$:/core/config/GlobalImportFilter}]
|
||||
<$action-log msg="In completion-createRecipe"/>
|
||||
<$action-log/>
|
||||
\end completion-createRecipe
|
||||
\procedure emptyArray() []
|
||||
\function createRecipeJson()
|
||||
[<bag_names>enlist-input[]] :reduce[<accumulator>!match[]else<emptyArray>jsonset<index>,<currentTiddler>]
|
||||
\end createRecipeJson
|
||||
<$action-log message="Sending" body=<<createRecipeJson>>/>
|
||||
<$action-sendmessage
|
||||
$message="tm-http-request"
|
||||
url=`/wiki/$(name)$/recipes/$(name)$`
|
||||
method="PUT"
|
||||
body=`{"bag_names":${ [<createRecipeJson>] }$,"description":"${ [<description>encodeuricomponent[]] }$"}`
|
||||
oncompletion=<<completion-createRecipe>>
|
||||
/>
|
||||
\end createRecipe
|
||||
|
||||
\procedure createRecipeButton(name)
|
||||
<$button class="">
|
||||
<$transclude $variable="createRecipe" name={{$:/state/NewRecipeName}}/>
|
||||
{{$:/core/images/new-button}}
|
||||
</$button><span class="tc-btn-text"><$text text="Create a new recipe:"/></span><$edit-text tiddler="$:/state/NewRecipeName" tag="input"/>
|
||||
\procedure createRecipeButton()
|
||||
\whitespace trim
|
||||
<form class="mws-form">
|
||||
<div class="mws-form-heading">
|
||||
<$text text="Create a new recipe"/>
|
||||
</div>
|
||||
<div class="mws-form-fields">
|
||||
<div class="mws-form-field">
|
||||
<label class="mws-form-field-description">
|
||||
Recipe name
|
||||
</label>
|
||||
<$edit-text tiddler="$:/state/NewRecipeName" tag="input" placeholder="(recipe name)" class="mws-form-field-input"/>
|
||||
</div>
|
||||
<div class="mws-form-field">
|
||||
<label class="mws-form-field-description">
|
||||
Bag names
|
||||
</label>
|
||||
<$edit-text tiddler="$:/state/NewRecipeBagNames" tag="input" placeholder="(space separated list of bags)"/>
|
||||
</div>
|
||||
<div class="mws-form-field">
|
||||
<label class="mws-form-field-description">
|
||||
Recipe description
|
||||
</label>
|
||||
<$edit-text tiddler="$:/state/NewRecipeDescription" tag="input" placeholder="(description)" class="mws-form-field-input"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mws-form-buttons">
|
||||
<$button class="mws-form-button">
|
||||
<$transclude
|
||||
$variable="createRecipe"
|
||||
name={{$:/state/NewRecipeName}}
|
||||
bag_names={{$:/state/NewRecipeBagNames}}
|
||||
description={{$:/state/NewRecipeDescription}}
|
||||
/>
|
||||
Create Recipe
|
||||
</$button>
|
||||
</div>
|
||||
</form>
|
||||
\end createRecipeButton
|
||||
|
||||
<!-- Expects currentTiddler to be the title of a bag entity state tiddler -->
|
||||
\procedure bagPill(element-tag:"span",is-topmost:"no")
|
||||
\whitespace trim
|
||||
<$genesis $type=<<element-tag>> class={{{ mws-bag-pill [<is-topmost>match[yes]then[mws-bag-pill-topmost]] +[join[ ]] }}}>
|
||||
<a class="mws-bag-pill-link" href=`/wiki/${ [{!!bag-name}encodeuricomponent[]] }$/bags/${ [{!!bag-name}encodeuricomponent[]] }$` rel="noopener noreferrer" target="_blank">
|
||||
<$image
|
||||
source=`/wiki/${ [{!!bag-name}encodeuricomponent[]] }$/bags/${ [{!!bag-name}encodeuricomponent[]] }$/tiddlers/%24%3A%2Ffavicon.ico`
|
||||
class="mws-favicon-small"
|
||||
>
|
||||
\whitespace trim
|
||||
<$genesis $type=<<element-tag>> class={{{ mws-bag-pill [<is-topmost>match[yes]then[mws-bag-pill-topmost]] +[join[ ]] }}}>
|
||||
<a class="mws-bag-pill-link" href=`/wiki/${ [{!!bag-name}encodeuricomponent[]] }$/bags/${ [{!!bag-name}encodeuricomponent[]] }$` rel="noopener noreferrer" target="_blank">
|
||||
<$image
|
||||
source="$:/plugins/multiwikiserver/images/missing-favicon.png"
|
||||
source=`/wiki/${ [{!!bag-name}encodeuricomponent[]] }$/bags/${ [{!!bag-name}encodeuricomponent[]] }$/tiddlers/%24%3A%2Ffavicon.ico`
|
||||
class="mws-favicon-small"
|
||||
/>
|
||||
</$image>
|
||||
<span class="mws-bag-pill-label">
|
||||
<$text text={{!!bag-name}}/>
|
||||
</span>
|
||||
</a>
|
||||
</$genesis>
|
||||
>
|
||||
<$image
|
||||
source="$:/plugins/multiwikiserver/images/missing-favicon.png"
|
||||
class="mws-favicon-small"
|
||||
/>
|
||||
</$image>
|
||||
<span class="mws-bag-pill-label">
|
||||
<$text text={{!!bag-name}}/>
|
||||
</span>
|
||||
</a>
|
||||
</$genesis>
|
||||
\end
|
||||
|
||||
<!-- Expects currentTiddler to be the title of a recipe entity state tiddler -->
|
||||
\procedure wikiCard()
|
||||
\whitespace trim
|
||||
<a class="mws-wiki-card" href=`/wiki/${ [{!!recipe-name}encodeuricomponent[]] }$` rel="noopener noreferrer" target="_blank">
|
||||
<div class="mws-wiki-card-image">
|
||||
<$image
|
||||
source=`/wiki/${ [{!!recipe-name}encodeuricomponent[]] }$/recipes/${ [{!!recipe-name}encodeuricomponent[]] }$/tiddlers/%24%3A%2Ffavicon.ico`
|
||||
class="mws-favicon"
|
||||
>
|
||||
\whitespace trim
|
||||
<a class="mws-wiki-card" href=`/wiki/${ [{!!recipe-name}encodeuricomponent[]] }$` rel="noopener noreferrer" target="_blank">
|
||||
<div class="mws-wiki-card-image">
|
||||
<$image
|
||||
source="$:/plugins/multiwikiserver/images/missing-favicon.png"
|
||||
source=`/wiki/${ [{!!recipe-name}encodeuricomponent[]] }$/recipes/${ [{!!recipe-name}encodeuricomponent[]] }$/tiddlers/%24%3A%2Ffavicon.ico`
|
||||
class="mws-favicon"
|
||||
/>
|
||||
</$image>
|
||||
</div>
|
||||
<div class="mws-wiki-card-content">
|
||||
<div class="mws-wiki-card-header">
|
||||
<$text text={{!!recipe-name}}/>
|
||||
>
|
||||
<$image
|
||||
source="$:/plugins/multiwikiserver/images/missing-favicon.png"
|
||||
class="mws-favicon"
|
||||
/>
|
||||
</$image>
|
||||
</div>
|
||||
<div class="mws-wiki-card-meta">
|
||||
<%if [list<currentTiddler>] %>
|
||||
<ol class="mws-horizontal-list">
|
||||
<$list filter="[list<currentTiddler>]" counter="counter">
|
||||
<$transclude $variable="bagPill" is-topmost={{{ [<counter-last>match[yes]] }}} element-tag="li"/>
|
||||
</$list>
|
||||
</ol>
|
||||
<%else%>
|
||||
(no bags defined)
|
||||
<%endif%>
|
||||
<div class="mws-wiki-card-content">
|
||||
<div class="mws-wiki-card-header">
|
||||
<$text text={{!!recipe-name}}/>
|
||||
</div>
|
||||
<div class="mws-wiki-card-meta">
|
||||
<%if [list<currentTiddler>] %>
|
||||
<ol class="mws-horizontal-list">
|
||||
<$list filter="[list<currentTiddler>]" counter="counter">
|
||||
<$transclude $variable="bagPill" is-topmost={{{ [<counter-last>match[yes]] }}} element-tag="li"/>
|
||||
</$list>
|
||||
</ol>
|
||||
<%else%>
|
||||
(no bags defined)
|
||||
<%endif%>
|
||||
</div>
|
||||
<div class="mws-wiki-card-description">
|
||||
<$text text={{!!text}}/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mws-wiki-card-description">
|
||||
<$text text={{!!text}}/>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</a>
|
||||
\end
|
||||
|
||||
<div class="mws-admin-container">
|
||||
@ -127,6 +189,7 @@ title: MultiWikiServer Administration
|
||||
<$list filter="[prefix[$:/state/MultiWikiServer/bags/]]">
|
||||
<li>
|
||||
<<bagPill>>
|
||||
<$text text={{!!text}}/>
|
||||
</li>
|
||||
</$list>
|
||||
</ul>
|
||||
|
@ -42,16 +42,16 @@ exports.startup = function() {
|
||||
databasePath: databasePath
|
||||
});
|
||||
// Create docs bag and recipe
|
||||
$tw.sqlTiddlerStore.createBag("docs");
|
||||
$tw.sqlTiddlerStore.createBag("docs","TiddlyWiki Documentation from https://tiddlywiki.com/");
|
||||
$tw.sqlTiddlerStore.createRecipe("docs",["docs"],"TiddlyWiki Documentation from https://tiddlywiki.com/");
|
||||
$tw.sqlTiddlerStore.saveTiddlersFromPath(path.resolve($tw.boot.corePath,$tw.config.editionsPath,"tw5.com/tiddlers"),"docs");
|
||||
$tw.sqlTiddlerStore.createBag("dev-docs");
|
||||
$tw.sqlTiddlerStore.createBag("dev-docs","TiddlyWiki Developer Documentation from https://tiddlywiki.com/dev/");
|
||||
$tw.sqlTiddlerStore.createRecipe("dev-docs",["dev-docs"],"TiddlyWiki Developer Documentation from https://tiddlywiki.com/dev/");
|
||||
$tw.sqlTiddlerStore.saveTiddlersFromPath(path.resolve($tw.boot.corePath,$tw.config.editionsPath,"dev/tiddlers"),"dev-docs");
|
||||
// Create bags and recipes
|
||||
$tw.sqlTiddlerStore.createBag("bag-alpha");
|
||||
$tw.sqlTiddlerStore.createBag("bag-beta");
|
||||
$tw.sqlTiddlerStore.createBag("bag-gamma");
|
||||
$tw.sqlTiddlerStore.createBag("bag-alpha","A test bag");
|
||||
$tw.sqlTiddlerStore.createBag("bag-beta","Another test bag");
|
||||
$tw.sqlTiddlerStore.createBag("bag-gamma","A further test bag");
|
||||
$tw.sqlTiddlerStore.createRecipe("recipe-rho",["bag-alpha","bag-beta"],"First wiki");
|
||||
$tw.sqlTiddlerStore.createRecipe("recipe-sigma",["bag-alpha","bag-gamma"],"Second Wiki");
|
||||
$tw.sqlTiddlerStore.createRecipe("recipe-tau",["bag-alpha"],"Third Wiki");
|
||||
|
@ -21,12 +21,21 @@ exports.path = /^\/wiki\/([^\/]+)\/bags\/([^\/]+)$/;
|
||||
exports.handler = function(request,response,state) {
|
||||
// Get the parameters
|
||||
var bag_name = $tw.utils.decodeURIComponentSafe(state.params[0]),
|
||||
bag_name_2 = $tw.utils.decodeURIComponentSafe(state.params[1]);
|
||||
if(bag_name === bag_name_2) {
|
||||
$tw.sqlTiddlerStore.createBag(bag_name);
|
||||
state.sendResponse(204,{
|
||||
"Content-Type": "text/plain"
|
||||
});
|
||||
bag_name_2 = $tw.utils.decodeURIComponentSafe(state.params[1]),
|
||||
data = $tw.utils.parseJSONSafe(state.data);
|
||||
if(bag_name === bag_name_2 && data) {
|
||||
const result = $tw.sqlTiddlerStore.createBag(bag_name,data.description);
|
||||
if(!result) {
|
||||
state.sendResponse(204,{
|
||||
"Content-Type": "text/plain"
|
||||
});
|
||||
} else {
|
||||
state.sendResponse(400,{
|
||||
"Content-Type": "text/plain"
|
||||
},
|
||||
result.message,
|
||||
"utf8");
|
||||
}
|
||||
} else {
|
||||
response.writeHead(404);
|
||||
response.end();
|
||||
|
@ -21,12 +21,22 @@ exports.path = /^\/wiki\/([^\/]+)\/recipes\/([^\/]+)$/;
|
||||
exports.handler = function(request,response,state) {
|
||||
// Get the parameters
|
||||
var recipe_name = $tw.utils.decodeURIComponentSafe(state.params[0]),
|
||||
recipe_name_2 = $tw.utils.decodeURIComponentSafe(state.params[1]);
|
||||
if(recipe_name === recipe_name_2) {
|
||||
$tw.sqlTiddlerStore.createRecipe(recipe_name);
|
||||
state.sendResponse(204,{
|
||||
"Content-Type": "text/plain"
|
||||
});
|
||||
recipe_name_2 = $tw.utils.decodeURIComponentSafe(state.params[1]),
|
||||
data = $tw.utils.parseJSONSafe(state.data);
|
||||
if(recipe_name === recipe_name_2 && data) {
|
||||
const result = $tw.sqlTiddlerStore.createRecipe(recipe_name,data.bag_names,data.description);
|
||||
console.log(`create recipe route handler for ${recipe_name} with ${JSON.stringify(data)} got result ${JSON.stringify(result)}`)
|
||||
if(!result) {
|
||||
state.sendResponse(204,{
|
||||
"Content-Type": "text/plain"
|
||||
});
|
||||
} else {
|
||||
state.sendResponse(400,{
|
||||
"Content-Type": "text/plain"
|
||||
},
|
||||
result.message,
|
||||
"utf8");
|
||||
}
|
||||
} else {
|
||||
response.writeHead(404);
|
||||
response.end();
|
||||
|
@ -6,6 +6,7 @@ module-type: library
|
||||
Low level SQL functions to store and retrieve tiddlers in a SQLite database.
|
||||
|
||||
This class is intended to encapsulate all the SQL queries used to access the database.
|
||||
Validation is for the most part left to the caller
|
||||
|
||||
\*/
|
||||
|
||||
@ -58,7 +59,8 @@ SqlTiddlerDatabase.prototype.createTables = function() {
|
||||
CREATE TABLE IF NOT EXISTS bags (
|
||||
bag_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
bag_name TEXT UNIQUE,
|
||||
accesscontrol TEXT
|
||||
accesscontrol TEXT,
|
||||
description TEXT
|
||||
)
|
||||
`,`
|
||||
-- Recipes have names...
|
||||
@ -115,28 +117,30 @@ SqlTiddlerDatabase.prototype.logTables = function() {
|
||||
|
||||
SqlTiddlerDatabase.prototype.listBags = function() {
|
||||
const rows = this.runStatementGetAll(`
|
||||
SELECT bag_name, accesscontrol
|
||||
SELECT bag_name, accesscontrol, description
|
||||
FROM bags
|
||||
ORDER BY bag_name
|
||||
`);
|
||||
return rows;
|
||||
};
|
||||
|
||||
SqlTiddlerDatabase.prototype.createBag = function(bagname) {
|
||||
SqlTiddlerDatabase.prototype.createBag = function(bagname,description) {
|
||||
// Run the queries
|
||||
this.runStatement(`
|
||||
INSERT OR IGNORE INTO bags (bag_name, accesscontrol)
|
||||
VALUES ($bag_name, '')
|
||||
INSERT OR IGNORE INTO bags (bag_name, accesscontrol, description)
|
||||
VALUES ($bag_name, '', '')
|
||||
`,{
|
||||
bag_name: bagname
|
||||
});
|
||||
this.runStatement(`
|
||||
UPDATE bags
|
||||
SET accesscontrol = $accesscontrol
|
||||
SET accesscontrol = $accesscontrol,
|
||||
description = $description
|
||||
WHERE bag_name = $bag_name
|
||||
`,{
|
||||
bag_name: bagname,
|
||||
accesscontrol: "[some access control stuff]"
|
||||
accesscontrol: "[some access control stuff]",
|
||||
description: description
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -7,6 +7,7 @@ Higher level functions to perform basic tiddler operations with a sqlite3 databa
|
||||
|
||||
This class is largely a wrapper for the sql-tiddler-database.js class, adding the following functionality:
|
||||
|
||||
* Validating requests (eg bag and recipe name constraints)
|
||||
* Synchronising bag and recipe names to the admin wiki
|
||||
* Handling _canonical_uri tiddlers
|
||||
|
||||
@ -34,6 +35,43 @@ function SqlTiddlerStore(options) {
|
||||
this.updateAdminWiki();
|
||||
}
|
||||
|
||||
/*
|
||||
Returns null if a bag/recipe name is valid, or a string error message if not
|
||||
*/
|
||||
SqlTiddlerStore.prototype.validateItemName = function(name) {
|
||||
if(typeof name !== "string") {
|
||||
return "Not a valid string";
|
||||
}
|
||||
if(name.length > 256) {
|
||||
return "Too long";
|
||||
}
|
||||
if(!(/^[^\s\u00A0\x00-\x1F\x7F~`!@#$%^&*()+={}\[\];:\'\"<>.,\/\\\?]+$/g.test(name))) {
|
||||
return "Invalid character(s)";
|
||||
}
|
||||
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) {
|
||||
if(!$tw.utils.isArray(names)) {
|
||||
return "Not a valid array";
|
||||
}
|
||||
var errors = [];
|
||||
for(const name of names) {
|
||||
const result = this.validateItemName(name);
|
||||
if(result) {
|
||||
errors.push(result);
|
||||
}
|
||||
}
|
||||
if(errors.length === 0) {
|
||||
return null;
|
||||
} else {
|
||||
return errors.join("\n");
|
||||
}
|
||||
};
|
||||
|
||||
SqlTiddlerStore.prototype.close = function() {
|
||||
this.sqlTiddlerDatabase.close();
|
||||
this.sqlTiddlerDatabase = undefined;
|
||||
@ -49,7 +87,7 @@ SqlTiddlerStore.prototype.updateAdminWiki = function() {
|
||||
this.saveEntityStateTiddler({
|
||||
title: "bags/" + bagInfo.bag_name,
|
||||
"bag-name": bagInfo.bag_name,
|
||||
text: ""
|
||||
text: bagInfo.description
|
||||
});
|
||||
}
|
||||
// Update recipes
|
||||
@ -112,22 +150,42 @@ SqlTiddlerStore.prototype.listBags = function() {
|
||||
return this.sqlTiddlerDatabase.listBags();
|
||||
};
|
||||
|
||||
SqlTiddlerStore.prototype.createBag = function(bagname) {
|
||||
this.sqlTiddlerDatabase.createBag(bagname);
|
||||
SqlTiddlerStore.prototype.createBag = function(bagname,description) {
|
||||
console.log(`create bag method for ${bagname} with ${description}`)
|
||||
console.log(`validation results are ${this.validateItemName(bagname)}`)
|
||||
const validationBagName = this.validateItemName(bagname);
|
||||
if(validationBagName) {
|
||||
return {message: validationBagName};
|
||||
}
|
||||
this.sqlTiddlerDatabase.createBag(bagname,description);
|
||||
this.saveEntityStateTiddler({
|
||||
title: "bags/" + bagname,
|
||||
"bag-name": bagname,
|
||||
text: ""
|
||||
text: description
|
||||
});
|
||||
return null;
|
||||
};
|
||||
|
||||
SqlTiddlerStore.prototype.listRecipes = function() {
|
||||
return this.sqlTiddlerDatabase.listRecipes();
|
||||
};
|
||||
|
||||
/*
|
||||
Returns null on success, or {message:} on error
|
||||
*/
|
||||
SqlTiddlerStore.prototype.createRecipe = function(recipename,bagnames,description) {
|
||||
console.log(`create recipe method for ${recipename} with ${JSON.stringify(bagnames)}`)
|
||||
console.log(`validation results are ${this.validateItemName(recipename)} and ${this.validateItemNames(bagnames)}`)
|
||||
bagnames = bagnames || [];
|
||||
description = description || "";
|
||||
const validationRecipeName = this.validateItemName(recipename);
|
||||
if(validationRecipeName) {
|
||||
return {message: validationRecipeName};
|
||||
}
|
||||
const validationBagNames = this.validateItemNames(bagnames);
|
||||
if(validationBagNames) {
|
||||
return {message: validationBagNames};
|
||||
}
|
||||
this.sqlTiddlerDatabase.createRecipe(recipename,bagnames,description);
|
||||
this.saveEntityStateTiddler({
|
||||
title: "recipes/" + recipename,
|
||||
@ -137,6 +195,7 @@ SqlTiddlerStore.prototype.createRecipe = function(recipename,bagnames,descriptio
|
||||
return this.entityStateTiddlerPrefix + "bags/" + bag_name;
|
||||
}))
|
||||
});
|
||||
return null;
|
||||
};
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user