[enh] There should be a patch method. Also, DOM events should work...

This commit is contained in:
alban 2020-05-24 23:02:56 +02:00
parent b0c6043741
commit 77ccaef87d
3 changed files with 154 additions and 54 deletions

View File

@ -38,6 +38,7 @@ app.use(express.static('public'));
const bodyParser = require('body-parser'); const bodyParser = require('body-parser');
app.use(bodyParser.json()); app.use(bodyParser.json());
app.use(bodyParser.raw()); app.use(bodyParser.raw());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.text({ type : "text/*" })); app.use(bodyParser.text({ type : "text/*" }));
app.disable('x-powered-by'); app.disable('x-powered-by');
@ -62,12 +63,13 @@ function requireAuthentication( req, res, next ){
app.all('*', requireAuthentication); app.all('*', requireAuthentication);
const routes = require( "./routes"); const routes = require( "./routes");
app.get('/get/:id', routes.get);
app.get('/log/:id', routes.log); app.get('/log/:id', routes.log);
app.get('/health', routes.health); app.get('/health', routes.health);
app.get('/search', routes.search); app.get('/search', routes.search);
app.post('/*', routes.add);
app.get('/*', routes.main); app.get('/*', routes.main);
app.patch('/*', routes.main); app.post('/*', routes.add);
app.patch('/patch/:id', routes.patch);
app.put('/*', routes.main); app.put('/*', routes.main);
app.delete('/delete/:id', routes.delete); app.delete('/delete/:id', routes.delete);

View File

@ -1,7 +1,100 @@
/* global initData, authorizationToken */ /* global initData, authorizationToken */
$(function(){ $(function(){
const actionToggle = function(e){
var el=e.target;
$(el).parent().siblings('.actions').show();
$(el).hide();
};
const deleteButton = function(e){
const el = $(e.target);
const url = el.attr('href');
$.ajax(url,{
method: "DELETE",
beforeSend: function(request) {
request.setRequestHeader("authorizationToken", authorizationToken);
}
})
.done(function(data) {
$(el).parents('.log').remove();
})
.fail(function() {
alert( "error" );
});
return false;
};
const editButton = function(e){
const el = $(e.target);
const id = el.attr("rel");
const pre = el.parents(".log").find("pre");
$.ajax(`/get/${id}`,{
beforeSend: function(request) {
request.setRequestHeader("authorizationToken", authorizationToken);
}
})
.done(function(data) {
pre
.text(data._source.content)
.attr('rel',id)
.css("background","#ccc")
.attr("contenteditable",true)
.focus();
$('body pre[contenteditable]').on('focusout', contentEdited );
})
.fail(function(data,err) {
console.log(data,err);
alert( "error" );
});
return false;
};
const contentEdited = function(e) {
const el = $(e.target);
const id = el.attr('rel');
const content = el.text();
$.ajax(`/patch/${id}`,{
method: "PATCH",
data: {content:content},
beforeSend: function(request) {
request.setRequestHeader("authorizationToken", authorizationToken);
}
})
.done(function(data) {
el
.css("background","")
.html( formatContent(content) );
})
.fail(function(data,err) {
console.log(data,err);
alert( "error" );
});
};
const search = function(e){
const el = $(e.target);
const val = el.val();
if( val.length < 3 ){ return; }
$.ajax("/search",{
beforeSend: function(request) {
request.setRequestHeader("authorizationToken", authorizationToken);
},
data: {
q:val
}
})
.done(function(data) {
updatePage(data);
})
.fail(function() {
alert( "error" );
});
};
// List of HTML entities for escaping. // List of HTML entities for escaping.
var htmlEscapes = { var htmlEscapes = {
'&': '&amp;', '&': '&amp;',
@ -16,31 +109,37 @@ $(function(){
var htmlEscaper = /[&<>"'\/]/g; var htmlEscaper = /[&<>"'\/]/g;
// Escape a string for HTML interpolation. // Escape a string for HTML interpolation.
escape = function(string) { const escape = function(string) {
return ('' + string).replace(htmlEscaper, function(match) { return ('' + string).replace(htmlEscaper, function(match) {
return htmlEscapes[match]; return htmlEscapes[match];
}); });
}; };
var urlRegex = /(\S+): (https?:&#x2F;&#x2F;[^\s]+)/g; const urlRegex = /(\S+): (https?:&#x2F;&#x2F;[^\s]+)/g;
url = function(string){ const url = function(string){
return ''+string.replace(urlRegex, '<a target="_blank" href="$2">$1</a>'); return ''+string.replace(urlRegex, '<a target="_blank" href="$2">$1</a>');
}; };
var titleRegex = /^(.*\n)/; var titleRegex = /^(.*\n)/;
title = function(string){ const title = function(string){
return ''+string.replace(titleRegex, '<b>$1</b>'); return ''+string.replace(titleRegex, '<b>$1</b>');
}; };
var cmdRegex = /```([^`]*?)```/g; var cmdRegex = /```([^`]*?)```/g;
cmd = function(string) { const cmd = function(string) {
return ''+string.replace(cmdRegex, '<span class="cmd">$1</span>'); return ''+string.replace(cmdRegex, '<span class="cmd">$1</span>');
}; };
date = function(string){ const date = function(string){
var D = new Date(string); var D = new Date(string);
return D.toLocaleDateString()+" "+D.toLocaleTimeString(); return D.toLocaleDateString()+" "+D.toLocaleTimeString();
}; };
mailRegexp = /(.*) &lt;(.+@.+)&gt;/; const mailRegexp = /(.*) &lt;(.+@.+)&gt;/;
mail = function( string ){ const mail = function( string ){
return ''+string.replace(mailRegexp, `<a href="mailto:${string}">$1</a>`); return ''+string.replace(mailRegexp, `<a href="mailto:${string}">$1</a>`);
}; };
const formatContent = function(string){
return cmd(title(url(escape(string))));
};
function updatePage(data){ function updatePage(data){
var content = ""; var content = "";
@ -68,61 +167,29 @@ $(function(){
<a class="actions-toggle btn-link btn-sm">Actions</a> <a class="actions-toggle btn-link btn-sm">Actions</a>
</p> </p>
<div class="actions btn-group btn-group-sm" role="group" aria-label="log actions"> <div class="actions btn-group btn-group-sm" role="group" aria-label="log actions">
<a class="delete btn btn btn-outline-secondary" href="/delete/${id}">Remove</a> <a class="delete btn btn btn-outline-secondary" rel="${id}" href="/delete/${id}">Remove</a>
<a class="edit btn btn btn-outline-secondary" href="/edit/${id}">Edit</a> <a class="edit btn btn btn-outline-secondary" rel="${id}" href="/edit/${id}">Edit</a>
</div> </div>
</div> </div>
</div> </div>
<div class="col-lg"> <div class="col-lg data">
<pre> ${cmd(title(url(escape(item.content))))}</pre> <pre> ${formatContent(item.content)}</pre>
</div> </div>
</div> </div>
`; `;
}); });
$("#content").html(content); $("#content").html(content);
// attache events
$(".actions-toggle").on("click",actionToggle );
$('.delete').on('click', deleteButton);
$('.edit').on('click', editButton );
} }
$("input").on("keyup",function(e){ $("input").on("keyup",search );
const el = $(e.target);
const val = el.val();
if( val.length < 3 ){ return; }
$.ajax("/search",{
beforeSend: function(request) {
request.setRequestHeader("authorizationToken", authorizationToken);
},
data: {
q:val,
}
})
.done(function(data) {
updatePage(data);
})
.fail(function() {
alert( "error" );
});
});
updatePage( initData ); updatePage( initData );
$(".actions-toggle").on("click",(e) => { var el=e.target; $(el).parent().siblings('.actions').show(); $(el).hide(); } )
$('.delete').on('click', (e) => {
const el = $(e.target);
const url = el.attr('href');
$.ajax(url,{
method: "DELETE",
beforeSend: function(request) {
request.setRequestHeader("authorizationToken", authorizationToken);
}
})
.done(function(data) {
$(el).parents('.log').remove();
})
.fail(function() {
alert( "error" );
});
return false;
});
}); });

View File

@ -116,12 +116,43 @@ const routes = {
res.end("error"); res.end("error");
}); });
} , } ,
get: (req, res) => {
const id= req.params.id;
var log = client.get({
index: 'changelog',
id: id
}).then( (results, err) => {
res.json(results);
}, (e) => {
res.status(400);
res.json({msg:"Failed to get record"});
});
},
patch: (req,res) => {
const id= req.params.id;
const content= req.body.content;
var log = client.update({
index: 'changelog',
id: id,
body:{
doc:{
content:content
}
}
}).then( (results, err) => {
res.json(results);
}, (e) => {
res.status(400);
res.json({msg:"Failed to get record"});
}); },
log: (req, res) => { log: (req, res) => {
const id= req.params.id; const id= req.params.id;
var log = client.get({ var log = client.get({
index: 'changelog', index: 'changelog',
id: id id: id
}).then( (results, err) => { }).then( (results, err) => {
res.render('index', { res.render('index', {
title: 'changelog', title: 'changelog',