diff --git a/app/assets/dash_v1.css b/app/assets/dash_v1.css index 83f355e..06c54b0 100644 --- a/app/assets/dash_v1.css +++ b/app/assets/dash_v1.css @@ -35,6 +35,7 @@ a { position: fixed; top: 0; left: 0; + z-index: 100; } .devbug-header { @@ -115,4 +116,15 @@ pre {outline: 1px solid #ccc; padding: 5px; margin: 5px; } .action-li { display: inline; margin-right: 15px; +} + +#editor { + position: relative; + top: 0; + right: 0; + bottom: 0; + left: 0; + height: 50%; + min-height: 500px; + z-index: 0; } \ No newline at end of file diff --git a/app/controllers/dash/v1.controller.js b/app/controllers/dash/v1.controller.js index dba814a..5371168 100644 --- a/app/controllers/dash/v1.controller.js +++ b/app/controllers/dash/v1.controller.js @@ -6,6 +6,7 @@ const Project = _flitter.model('v1:Project') const Out = _flitter.model('v1:Out') const Invite = _flitter.model('v1:Invite') +const Snippet = _flitter.model('v1:Snippet') class v1 { /* @@ -390,6 +391,43 @@ class v1 { req.session.invite_data = false return res.redirect('/dash/v1/project/view/'+project.id) } + + async project_snippet_new(req, res, next){ + const project = await Project.findById(req.params.id) + if ( !project ) return _flitter.error(res, 404, {reason: 'The specified project does not exist.'}) + + return _flitter.view(res, 'dash_v1:snippet', {project, user: req.session.auth.user, title: 'Create Snippet', show_back: true}); + } + + async project_snippet_new_do(req, res, next){ + const project = await Project.findById(req.params.id) + if ( !project ) return _flitter.error(res, 404, {reason: 'The specified project does not exist.'}) + + if ( !req.body.title || !req.body.data ){ + return _flitter.view(res, 'dash_v1:snippet', {project, user: req.session.auth.user, title: 'Create Snippet', show_back: true}); + } + + const snippet_data = { + title: req.body.title, + data: req.body.data, + user_id: req.session.auth.uuid, + }; + + const snippet = new Snippet(snippet_data); + await snippet.save(); + + return res.redirect('/dash/v1/project/snippet/'+req.params.id+'/view/'+snippet.uuid) + } + + async project_snippet_view(req, res, next){ + const project = await Project.findById(req.params.id) + if ( !project ) return _flitter.error(res, 404, {reason: 'The specified project does not exist.'}) + + const snippet = await Snippet.findOne({uuid: req.params.snippet}) + if ( !snippet ) return _flitter.error(res, 404, {reason: 'The specified snippet does not exist.'}) + + return _flitter.view(res, 'dash_v1:snippet', {snippet, project, user: req.session.auth.user, title: snippet.title, show_back: true, readonly: true}) + } } module.exports = exports = v1 diff --git a/app/models/v1/Snippet.model.js b/app/models/v1/Snippet.model.js new file mode 100644 index 0000000..b5681a0 --- /dev/null +++ b/app/models/v1/Snippet.model.js @@ -0,0 +1,18 @@ +/* + * Snippet Model + * ------------------------------------------------------------- + * Put some description here! + */ +const uuid = require('uuid/v4') +const Snippet = { + title: String, + user_id: String, + archived: { type: Boolean, default: false }, + data: String, + shared_user_ids: [String], + edit_user_ids: [String], + uuid: { type: String, default: uuid }, + public_share: String, +} + +module.exports = exports = Snippet \ No newline at end of file diff --git a/app/routing/routers/dash/v1.routes.js b/app/routing/routers/dash/v1.routes.js index 5eed586..3ee6b67 100644 --- a/app/routing/routers/dash/v1.routes.js +++ b/app/routing/routers/dash/v1.routes.js @@ -48,6 +48,8 @@ const v1 = { '/project/share/:id/revoke/:user/edit': [ _flitter.controller('dash:v1').project_share_revoke_edit ], '/project/share/:id/transfer/:user': [ _flitter.controller('dash:v1').project_share_transfer ], '/project/share/:id/invite': [ _flitter.controller('dash:v1').project_share_invite ], + '/project/snippet/:id/new': [ _flitter.controller('dash:v1').project_snippet_new ], + '/project/snippet/:id/view/:snippet': [ _flitter.controller('dash:v1').project_snippet_view ], '/out/view/:id': [ _flitter.controller('dash:v1').out_view ], '/out/delete/:id/:project': [ _flitter.controller('dash:v1').out_delete ], @@ -70,6 +72,7 @@ const v1 = { '/project/new': [ _flitter.controller('dash:v1').new_project_do ], '/project/delete/:id': [ _flitter.controller('dash:v1').project_delete_do ], '/project/edit/:id': [ _flitter.controller('dash:v1').project_edit_do ], + '/project/snippet/:id/new': [ _flitter.controller('dash:v1').project_snippet_new_do ], }, } diff --git a/app/views/dash_v1/snippet.pug b/app/views/dash_v1/snippet.pug new file mode 100644 index 0000000..81ffcb7 --- /dev/null +++ b/app/views/dash_v1/snippet.pug @@ -0,0 +1,36 @@ +extends ./template +block content + if errors + each error in errors + p(style='color: red; font-weight: bold;') #{error} + if (!readonly) + form#snippet_form(method='post' enctype='multipart/form-data') + label(for='snippet_name') Snippet Title: + input#snippet_name(type='text' name='title' autofocus required) + input#snippet_value(type='hidden' name='data' required) + pre#editor #{ snippet ? snippet.data : '' } + if (!readonly) + button(onclick='submitSnippet()') #{ snippet ? 'Update Snippet' : 'Create Snippet' } + +block scripts + script(src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.5/ace.js") + script. + const editor = ace.edit('editor'); + editor.setTheme('ace/theme/cobalt'); + //- editor.session.setMode('ace/mode/javascript'); + + function trim(s){ + return ( s || '' ).replace( /^\s+|\s+$/g, '' ); + } + + function submitSnippet(){ + const form = document.getElementById('snippet_form'); + const value = document.getElementById('snippet_value'); + const name = document.getElementById('snippet_name'); + value.value = editor.getValue(); + + if ( trim(value.value) && trim(name.value) ) form.submit(); + } + if readonly + script. + editor.setOption('readOnly', true) \ No newline at end of file diff --git a/app/views/dash_v1/template.pug b/app/views/dash_v1/template.pug index a22ebf9..4e3128a 100644 --- a/app/views/dash_v1/template.pug +++ b/app/views/dash_v1/template.pug @@ -3,6 +3,7 @@ html title #{(title ? title+' | DevBug' : 'DevBug Dashboard')} link(rel='stylesheet' href='/assets/dash_v1.css') script(src='/assets/dash_v1.js') + block head body .page-header .devbug-header DevBug | v#{devbug.version} #{(user ? " | User: "+user.username : "")} #{(project ? " | Project: "+project.name+" | API: "+project.uuid : "")} #{((_flitter.config('server.environment') === 'development') ? " | Development" : "" )} @@ -21,4 +22,7 @@ html li.navli a.nava(href='javascript:window.history.back()') Back .spacer - block content + .content + block content + block scripts + //- .spacer diff --git a/app/views/dash_v1/view.pug b/app/views/dash_v1/view.pug index aeeda74..4b4e5bd 100644 --- a/app/views/dash_v1/view.pug +++ b/app/views/dash_v1/view.pug @@ -1,6 +1,16 @@ extends ./template block content h3 Project API Key: #{project.uuid} + + h2 Code Snippets + a.btn(href='/dash/v1/project/snippet/'+project.id+'/new') + + table + thead + tr + th(scope='col' style='min-width: 250px') Title + th(scope='col') Actions + + h2 Development Outputs table thead tr