From c4d8ee7c431b3511bf26da68e952808b51d663c7 Mon Sep 17 00:00:00 2001 From: Sean Fridman Date: Thu, 9 Apr 2015 16:00:21 -0400 Subject: Add resource delete functionality to admin --- themes/okadmin/templates/resource.liquid | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'themes/okadmin/templates') diff --git a/themes/okadmin/templates/resource.liquid b/themes/okadmin/templates/resource.liquid index c0d348d..48e3ef2 100644 --- a/themes/okadmin/templates/resource.liquid +++ b/themes/okadmin/templates/resource.liquid @@ -14,6 +14,10 @@
+
+ + +
{% include 'partials/tail' %} -- cgit v1.2.3-70-g09d2 From c8eab703d468439a5b04dcfdeaf72db3eae4f966 Mon Sep 17 00:00:00 2001 From: Julie Lala Date: Thu, 9 Apr 2015 16:46:10 -0400 Subject: css and stuff --- install.sh | 2 +- themes/okadmin/public/css/main.css | 3 +++ themes/okadmin/public/js/app.js | 25 +++++++++++++++++-------- themes/okadmin/public/js/upload.js | 3 +-- themes/okadmin/templates/partials/head.liquid | 4 ++-- 5 files changed, 24 insertions(+), 13 deletions(-) (limited to 'themes/okadmin/templates') diff --git a/install.sh b/install.sh index e0a43c4..15893aa 100755 --- a/install.sh +++ b/install.sh @@ -1,5 +1,5 @@ cd app/node_modules ; for i in * ; do cd $i ; npm install; cd .. ; done ; cd ../.. npm install -cd examples +cd site node index diff --git a/themes/okadmin/public/css/main.css b/themes/okadmin/public/css/main.css index a1e20a0..a01a85c 100644 --- a/themes/okadmin/public/css/main.css +++ b/themes/okadmin/public/css/main.css @@ -46,6 +46,9 @@ a:visited { color: rgba(0, 0, 0, 0.25); line-height: 50px; } +.admin-header .breadcrumb b { + color: #333; +} .admin-header .site-link { float: right; diff --git a/themes/okadmin/public/js/app.js b/themes/okadmin/public/js/app.js index 4b8d98f..170b2ab 100644 --- a/themes/okadmin/public/js/app.js +++ b/themes/okadmin/public/js/app.js @@ -1,10 +1,20 @@ var OKAdmin = function(){ - OKUpload.bind() + // initialize our (single) ajax image uploader with an element and a template + OKUpload.bind( document.getElementById("file") ) OKUpload.add = function(data){ var url = data[0].extra.Location add_image(url) } + + // also handle straight image urls + $("#add-image-url").keydown(pressEnter(function(e){ + var url = $(this).val() + $(this).val("") + add_image(url) + })}) + + // clone and populate template function add_image(url){ var imageTemplate = $("#captioned-image-template").html() var $el = $(imageTemplate) @@ -12,21 +22,19 @@ var OKAdmin = function(){ $el.find("img").attr("src", url) $(".captioned-image-list ol").append($el) } + + // make the region sortable with drag-and-drop $(".captioned-image-list ol").sortable() $(".captioned-image-list ol").disableSelection() - - $("#add-image-url").keydown(pressEnter(function(e){ - var url = $(this).val() - $(this).val("") - add_image(url) - })}) - + + // delete image $(document).on("click", ".remove-image", function(){ if (confirm("Delete this image?")) { $(this).parent().remove() } }) + // populate a video field with info from our url parser $(".video .url").keydown(pressEnter(function(){ var $el = $(this) var url = $el.val() @@ -40,6 +48,7 @@ var OKAdmin = function(){ }) }})) + // fix post indexing in list-driven inputs $("form").submit(function(){ $(".image-element").each(function(index){ $(this).find("input,textarea").each(function(){ diff --git a/themes/okadmin/public/js/upload.js b/themes/okadmin/public/js/upload.js index d9fd5ed..1c9094c 100644 --- a/themes/okadmin/public/js/upload.js +++ b/themes/okadmin/public/js/upload.js @@ -2,8 +2,7 @@ var OKUpload = { action: "/_services/image", - bind: function(){ - var el = document.getElementById("file") + bind: function(el){ if (! el) return el.addEventListener("change", OKUpload.handleFileSelect) }, diff --git a/themes/okadmin/templates/partials/head.liquid b/themes/okadmin/templates/partials/head.liquid index 3af59fd..c423584 100644 --- a/themes/okadmin/templates/partials/head.liquid +++ b/themes/okadmin/templates/partials/head.liquid @@ -2,12 +2,12 @@ - {{meta.title}} + TwoHustlers Admin {{meta.title}}
- {{meta.title}} Admin + TwoHustlers{{meta.title}} Admin View Site
-- cgit v1.2.3-70-g09d2 From 7b7ac014579bafdb16e91a98f995f4fa7f55b4f1 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Thu, 9 Apr 2015 17:17:00 -0400 Subject: alert when deleting posts --- site/db.json | 20 ++++++++++++++++++++ themes/okadmin/public/css/main.css | 5 +++++ themes/okadmin/public/js/app.js | 9 +++++++++ themes/okadmin/templates/resource.liquid | 2 +- 4 files changed, 35 insertions(+), 1 deletion(-) (limited to 'themes/okadmin/templates') diff --git a/site/db.json b/site/db.json index 8107c6d..07085d4 100644 --- a/site/db.json +++ b/site/db.json @@ -28,6 +28,26 @@ "caption": "CURABITUR BLANDIT TEMPUS PORTTITOR 4" } ] + }, + { + "id": "TEST", + "title": "", + "shortname": "", + "description": "", + "video": { + "url": "", + "type": "", + "token": "", + "title": "", + "thumb": "" + }, + "category": "retail", + "images": [ + { + "uri": "https://ltho.s3.amazonaws.com/cb2698ea-9927-4ca9-972b-f227d46d25f3.png", + "caption": "" + } + ] } ], "advertising": [], diff --git a/themes/okadmin/public/css/main.css b/themes/okadmin/public/css/main.css index d2a4418..ad940e8 100644 --- a/themes/okadmin/public/css/main.css +++ b/themes/okadmin/public/css/main.css @@ -248,10 +248,15 @@ label { li.image-element:hover .remove-image { display: block; } +li.image-element .remove-image:hover { + color: red; +} .remove-image { display: none; } +#delete_form button:hover { color: red } + .template { display: none; } diff --git a/themes/okadmin/public/js/app.js b/themes/okadmin/public/js/app.js index 8c85663..441172f 100644 --- a/themes/okadmin/public/js/app.js +++ b/themes/okadmin/public/js/app.js @@ -59,6 +59,15 @@ var OKAdmin = function(){ }) }) + $("#delete_form").submit(function(e){ + if (confirm("Are you sure you want to delete this record?")) { + return + } + else { + e.preventDefault() + } + }) + function pressEnter(fn){ return function(e){ if (e.keyCode && e.keyCode !== 13) return diff --git a/themes/okadmin/templates/resource.liquid b/themes/okadmin/templates/resource.liquid index 48e3ef2..c321e8a 100644 --- a/themes/okadmin/templates/resource.liquid +++ b/themes/okadmin/templates/resource.liquid @@ -14,7 +14,7 @@
-
+
-- cgit v1.2.3-70-g09d2 From 669d6aec9f812e4151bffbaa4f8830cf5764ee1e Mon Sep 17 00:00:00 2001 From: Sean Fridman Date: Thu, 9 Apr 2015 20:05:14 -0400 Subject: Set inital array indices in templates --- themes/okadmin/public/js/app.js | 2 +- themes/okadmin/templates/partials/inputs.liquid | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'themes/okadmin/templates') diff --git a/themes/okadmin/public/js/app.js b/themes/okadmin/public/js/app.js index 441172f..4d13bb2 100644 --- a/themes/okadmin/public/js/app.js +++ b/themes/okadmin/public/js/app.js @@ -53,7 +53,7 @@ var OKAdmin = function(){ $("form").submit(function(){ $(".image-element").each(function(index){ $(this).find("input,textarea").each(function(){ - var field = $(this).attr("name").replace(/\[\]/, "[" + index + "]") + var field = $(this).attr("name").replace(/\[[0-9]*\]/, "[" + index + "]") $(this).attr("name", field) }) }) diff --git a/themes/okadmin/templates/partials/inputs.liquid b/themes/okadmin/templates/partials/inputs.liquid index 7d23c9e..7cede76 100644 --- a/themes/okadmin/templates/partials/inputs.liquid +++ b/themes/okadmin/templates/partials/inputs.liquid @@ -43,8 +43,8 @@
    {% for image in spec.value %}
  1. - - + + {{image.caption}}
  2. -- cgit v1.2.3-70-g09d2 From 00fd19b33ead56842daeb6f6a24735a8687f7744 Mon Sep 17 00:00:00 2001 From: Sean Fridman Date: Thu, 9 Apr 2015 20:58:32 -0400 Subject: Implement flash messaging for admin success/error stuff --- app/node_modules/okadminview/index.js | 25 +++++++++++++++++++++++-- app/node_modules/okadminview/package.json | 2 ++ themes/okadmin/templates/index.liquid | 2 ++ themes/okadmin/templates/partials/errors.liquid | 10 ---------- themes/okadmin/templates/partials/flash.liquid | 14 ++++++++++++++ themes/okadmin/templates/resource.liquid | 2 +- themes/okadmin/templates/resource_new.liquid | 2 +- 7 files changed, 43 insertions(+), 14 deletions(-) delete mode 100644 themes/okadmin/templates/partials/errors.liquid create mode 100644 themes/okadmin/templates/partials/flash.liquid (limited to 'themes/okadmin/templates') diff --git a/app/node_modules/okadminview/index.js b/app/node_modules/okadminview/index.js index 05e2251..9e9aacf 100644 --- a/app/node_modules/okadminview/index.js +++ b/app/node_modules/okadminview/index.js @@ -2,6 +2,8 @@ var assign = require('object-assign'); var cloneDeep = require('lodash.clonedeep'); var bodyParser = require('body-parser'); var methodOverride = require('method-override'); +var session = require('express-session'); +var flash = require('connect-flash'); var Q = require('q'); var pluralize = require('pluralize'); var OKQuery = require('okquery'); @@ -75,6 +77,14 @@ function OKAdminView(options) { strict: app.get('strict routing') }); + // Enable basic sessions for flash messages + router.use(session({ + secret: 'okadmin', + resave: false, + saveUninitialized: false + })); + // Enable flash messaging + router.use(flash()); // Parse form data router.use(bodyParser.urlencoded({extended: true})); // HTML forms only support POST and GET methods @@ -91,7 +101,10 @@ function OKAdminView(options) { router.get('/', function readIndex(req, res, next) { fetchIndexTemplateData(meta, indexQueries).then(function(data) { - view.renderIndex(req, res, data); + view.renderIndex(req, res, assign(data, { + success: req.flash('success'), + errors: req.flash('errors') + })); }).fail(errorHandler(req, res)); }); @@ -103,6 +116,8 @@ function OKAdminView(options) { } else { meta.get().then(function(metadata) { view.renderResourceNew(req, res, { + success: req.flash('success'), + errors: req.flash('errors'), meta: metadata, resource: { type: resource.type, @@ -129,7 +144,10 @@ function OKAdminView(options) { if (!data) { resourceMissingHandler(req, res)() } else { - view.renderResource(req, res, data); + view.renderResource(req, res, assign(data, { + success: req.flash('success'), + errors: req.flash('errors') + })); } }).fail(errorHandler(req, res)); } @@ -147,6 +165,7 @@ function OKAdminView(options) { try { resource.assertValid(data); resource.create(data).then(function(created) { + req.flash('success', 'Created ' + type); res.redirect(303, data[resource.idField]); }).fail(errorHandler(req, res)); } catch (errors) { @@ -170,6 +189,7 @@ function OKAdminView(options) { try { resource.assertValid(data); resource.update(id, data).then(function(updated) { + req.flash('success', 'Updated ' + type); res.redirect(303, '../' + updated[resource.idField]); }).fail(errorHandler(req, res)); } catch (errors) { @@ -189,6 +209,7 @@ function OKAdminView(options) { } else { meta.get().then(function(metadata) { resource.destroy(id).then(function() { + req.flash('success', 'Deleted ' + type); res.redirect(303, '../..'); }).fail(errorHandler(req, res)); }).fail(errorHandler(req, res)); diff --git a/app/node_modules/okadminview/package.json b/app/node_modules/okadminview/package.json index c428645..4c6d11c 100644 --- a/app/node_modules/okadminview/package.json +++ b/app/node_modules/okadminview/package.json @@ -10,6 +10,8 @@ "license": "None", "dependencies": { "body-parser": "^1.12.2", + "connect-flash": "^0.1.1", + "express-session": "^1.11.1", "lodash.clonedeep": "^3.0.0", "method-override": "^2.3.2", "object-assign": "^2.0.0", diff --git a/themes/okadmin/templates/index.liquid b/themes/okadmin/templates/index.liquid index 95c64dd..a5b27e5 100644 --- a/themes/okadmin/templates/index.liquid +++ b/themes/okadmin/templates/index.liquid @@ -1,5 +1,7 @@ {% include 'partials/head' %} +{% include 'partials/flash' %} +
    {% for pair in resources %} {% assign name = pair[0] %} diff --git a/themes/okadmin/templates/partials/errors.liquid b/themes/okadmin/templates/partials/errors.liquid deleted file mode 100644 index cdb0b25..0000000 --- a/themes/okadmin/templates/partials/errors.liquid +++ /dev/null @@ -1,10 +0,0 @@ -
    - {% for error in errors %} -
    -
    {{error.message}}
    -
    - Expected {{error.expected}} but got {{error.actual}} -
    -
    - {% endfor %} -
    diff --git a/themes/okadmin/templates/partials/flash.liquid b/themes/okadmin/templates/partials/flash.liquid new file mode 100644 index 0000000..33b621b --- /dev/null +++ b/themes/okadmin/templates/partials/flash.liquid @@ -0,0 +1,14 @@ +{% if success %} +
    + {{success}} +
    +{% elsif errors %} +
    + {% for error in errors %} +
    +
    {{error.message}}
    +
    + {% endfor %} +
    +{% endif %} + diff --git a/themes/okadmin/templates/resource.liquid b/themes/okadmin/templates/resource.liquid index c321e8a..53cd83e 100644 --- a/themes/okadmin/templates/resource.liquid +++ b/themes/okadmin/templates/resource.liquid @@ -1,6 +1,6 @@ {% include 'partials/head' %} -{% include 'partials/errors' %} +{% include 'partials/flash' %}
diff --git a/themes/okadmin/templates/resource.liquid b/themes/okadmin/templates/resource.liquid index 53cd83e..8078778 100644 --- a/themes/okadmin/templates/resource.liquid +++ b/themes/okadmin/templates/resource.liquid @@ -2,7 +2,7 @@ {% include 'partials/flash' %} - -- cgit v1.2.3-70-g09d2 From 29ee500db3cb317404cb2f050ee9bc75777e91ca Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 13 Apr 2015 17:57:24 -0400 Subject: delete button --- themes/okadmin/templates/partials/inputs.liquid | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'themes/okadmin/templates') diff --git a/themes/okadmin/templates/partials/inputs.liquid b/themes/okadmin/templates/partials/inputs.liquid index b9cf7a3..4d6372d 100644 --- a/themes/okadmin/templates/partials/inputs.liquid +++ b/themes/okadmin/templates/partials/inputs.liquid @@ -50,7 +50,7 @@ {{image.caption}} - + {% endfor %} @@ -64,7 +64,7 @@ {{image.caption}} - +
-- cgit v1.2.3-70-g09d2 From d45f617dc74a07beb352d04537d47a77193f487f Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 13 Apr 2015 18:19:41 -0400 Subject: hide id field --- site/index.js | 4 ++-- themes/okadmin/public/js/app.js | 16 ++++++++++++---- themes/okadmin/templates/partials/inputs.liquid | 19 +++---------------- 3 files changed, 17 insertions(+), 22 deletions(-) (limited to 'themes/okadmin/templates') diff --git a/site/index.js b/site/index.js index 8eec697..d4f5cb4 100644 --- a/site/index.js +++ b/site/index.js @@ -1,7 +1,7 @@ var okcms = require('..'); var projectSchema = { - id: {type: 'string', id: true}, + id: {type: 'string', id: true, hidden: true}, title: {type: 'string'}, shortname: {type: 'string'}, description: {type: 'text'}, @@ -15,7 +15,7 @@ var app = okcms.createApp({ schemas: { page: { - id: {type: 'string'}, + id: {type: 'string', hidden: true}, title: {type: 'string'}, body: {type: 'text'}, image: {type: 'string'} diff --git a/themes/okadmin/public/js/app.js b/themes/okadmin/public/js/app.js index 91a8e1a..009fe4c 100644 --- a/themes/okadmin/public/js/app.js +++ b/themes/okadmin/public/js/app.js @@ -51,13 +51,18 @@ var OKAdmin = function(){ // fix post indexing in list-driven inputs $(".main.resource form").submit(function(e){ - var $id = $("[name=id]") - if ($id.length && ! $id.val()) { - alert("Please enter an ID") - $id.focus() + var $id = $("[name=id]"), $title = $("[name=title]") + + if ($title.length && ! $title.val()) { + alert("Please enter a title") + $title.focus() e.preventDefault() return } + + var slug = slugify( $title.val() ) + $id.val( slug ) + $(".image-element").each(function(index){ $(this).find("input,textarea").each(function(){ var field = $(this).attr("name").replace(/\[[0-9]*\]/, "[" + index + "]") @@ -129,3 +134,6 @@ var OKAdmin = function(){ $(function(){ window.app = new OKAdmin () }) + + +function slugify (s){ return (s || "").toLowerCase().replace(/\s/g,"-").replace(/[^-_a-zA-Z0-9]/g, '-').replace(/-+/g,"-") } diff --git a/themes/okadmin/templates/partials/inputs.liquid b/themes/okadmin/templates/partials/inputs.liquid index 4d6372d..253b275 100644 --- a/themes/okadmin/templates/partials/inputs.liquid +++ b/themes/okadmin/templates/partials/inputs.liquid @@ -3,30 +3,17 @@ {% assign spec = pair[1] %} {% assign type = spec.type %} -
- +
+ {% if type == 'string' %} + name="{{name}}" type="text" value="{{spec.value}}"> {% elsif type == 'text' %} {% elsif type == 'enum' %} {% endfor %} diff --git a/themes/okadmin/templates/resource.liquid b/themes/okadmin/templates/resource.liquid index abc59e9..aa3efe0 100644 --- a/themes/okadmin/templates/resource.liquid +++ b/themes/okadmin/templates/resource.liquid @@ -6,8 +6,8 @@ Back -
-

EDIT {{ resource.type }} '{{ resource.id }}'

+
+

EDIT {{ resource.type }} '{{ resource.spec.title.value }}'

{% include 'partials/inputs' %} -- cgit v1.2.3-70-g09d2 From db3775794623ebbc63efb44e545b66f2accfd728 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 13 Apr 2015 19:28:42 -0400 Subject: testing stuff --- site/db.json | 37 ++++++++++++++++++++++++++++++-- site/index.js | 1 + site/templates/project.liquid | 2 +- themes/okadmin/public/js/app.js | 1 - themes/okadmin/templates/resource.liquid | 4 +++- 5 files changed, 40 insertions(+), 5 deletions(-) (limited to 'themes/okadmin/templates') diff --git a/site/db.json b/site/db.json index eb0265d..7681fd8 100644 --- a/site/db.json +++ b/site/db.json @@ -46,7 +46,40 @@ "__index": "0" } ], - "advertising": [], "experiential": [], - "content": [] + "content": [ + { + "id": "stuff", + "title": "Stuff", + "menu": "Stuff", + "description": "Blablhablhalbhab", + "video": { + "url": "http://vimeo.com/112498725", + "type": "vimeo", + "token": "112498725", + "title": "FW14-2H-VIDEO-V4 2", + "thumb": "http://i.vimeocdn.com/video/497493142_640.jpg" + }, + "images": [ + { + "uri": "https://ltho.s3.amazonaws.com/aa5ab62c-a7f4-433e-8957-c059199de924.png", + "caption": "WHO" + }, + { + "uri": "https://ltho.s3.amazonaws.com/888c06f0-32f4-4f7b-938f-fb9bf178a1dc.png", + "caption": "DARK" + }, + { + "uri": "https://ltho.s3.amazonaws.com/525cd121-a436-472f-b201-7b2baffa804a.png", + "caption": "STUFF" + }, + { + "uri": "https://ltho.s3.amazonaws.com/b2a607e6-1c60-42cd-8449-55737501ff9e.png", + "caption": "BLAH" + } + ], + "__index": "0" + } + ], + "advertising": [] } \ No newline at end of file diff --git a/site/index.js b/site/index.js index 189dfc4..b6dea48 100644 --- a/site/index.js +++ b/site/index.js @@ -81,6 +81,7 @@ var app = okcms.createApp({ '/advertising/:id': { data: { type: 'advertising', + as: 'project', query: { id: ':id' } diff --git a/site/templates/project.liquid b/site/templates/project.liquid index d21fed2..e087049 100644 --- a/site/templates/project.liquid +++ b/site/templates/project.liquid @@ -3,7 +3,7 @@ {{project.title}} +
ABOUT
CONTACT
diff --git a/themes/okadmin/public/css/main.css b/themes/okadmin/public/css/main.css index ec426f9..685e368 100644 --- a/themes/okadmin/public/css/main.css +++ b/themes/okadmin/public/css/main.css @@ -228,7 +228,9 @@ button, input[type=submit] { border: 0; display: none; } -.main.resource form .group.loaded input:first-child, +.main.resource form .group.image input, +.main.resource form .group.video input:first-child, +.main.resource form .group.loaded.video input[type=text], .main.resource form .group input:first-child { display: block; width: 25em; @@ -238,17 +240,24 @@ button, input[type=submit] { } .main.resource form .group.loaded input { display: block; - width: 20.05em; } -.main.resource form .group input { - display: none; +.main.resource form .group input[type=text] { + width: 20.05em; margin-bottom: 0.1em; } +.main.resource form .group.image .image-element, +.main.resource form .group.video input[type=text], .main.resource form .group.loaded input[hidden], +.main.resource form .group.image.loaded .fields, .main.resource form input[hidden] { display: none; } - +.main.resource form .group.image.loaded .image-element { + display: block; +} +.main.resource form .fields { + height: 3em; +} .main.resource form textarea { padding: 0.5em; height: 15em; @@ -280,6 +289,8 @@ button, input[type=submit] { width: 10em; max-height: 10em; border: 0; +} +.main.resource form .images img { cursor: -webkit-grab; cursor: grab; } @@ -313,10 +324,10 @@ button, input[type=submit] { margin: 0; padding: 0; cursor: pointer; } -li.image-element:hover .remove-image { +.image-element:hover .remove-image { display: block; } -li.image-element .remove-image:hover { +.image-element .remove-image:hover { color: red; } .remove-image { diff --git a/themes/okadmin/public/js/app.js b/themes/okadmin/public/js/app.js index 22317f3..baa4873 100644 --- a/themes/okadmin/public/js/app.js +++ b/themes/okadmin/public/js/app.js @@ -1,38 +1,75 @@ var OKAdmin = function(){ - // initialize our (single) ajax image uploader with an element and a template - OKUpload.bind( document.getElementById("file") ) - OKUpload.add = function(data){ - var url = data[0].extra.Location - add_image(url) - } - - // also handle straight image urls - $("#add-image-url").keydown(pressEnter(function(e){ - var url = $(this).val() - $(this).val("") - add_image(url) - })) + // initialize our multi-image uploader with an element and a template + $(".image-list").each(function(){ + var uploader = new OKUpload () + uploader.bind( $(".add-image-button input", this) ) + uploader.add = function(data){ + var url = data[0].extra.Location + add_image(url) + } + // also handle straight image urls + $(".add-image-url", this).keydown(pressEnter(function(e){ + var url = $(this).val() + $(this).val("") + add_image(url) + })) + + // clone and populate template + function add_image(url){ + var imageTemplate = $("#captioned-image-template").html() + var $el = $(imageTemplate) + $el.find(".uri").val(url) + $el.find("img").attr("src", url) + $(".captioned-image-list ol").append($el) + } + }) + // delete image from gallery + $(document).on("mousedown", ".image-list .remove-image", function(){ + if (confirm("Delete this image?")) { + $(this).parent().remove() + } + }) - // clone and populate template - function add_image(url){ - var imageTemplate = $("#captioned-image-template").html() - var $el = $(imageTemplate) - $el.find(".uri").val(url) - $el.find("img").attr("src", url) - $(".captioned-image-list ol").append($el) - } + // initialize our single image uploader with existing DOM + $(".image").each(function(){ + var $el = $(this) + + var uploader = new OKUpload () + uploader.bind( $(".add-image-button input", this) ) + uploader.add = function(data){ + var url = data[0].extra.Location + add_image(url) + } + // also handle straight image urls + $(".add-image-url", this).keydown(pressEnter(function(e){ + var url = $(this).val() + $(this).val("") + add_image(url) + })) + + // clone and populate template + function add_image(url){ + $el.find(".uri").val(url) + $el.find(".caption").val("") + $el.find("img").attr("src", url) + $el.addClass("loaded") + } + }) + // delete image from single image entry + $(document).on("mousedown", ".image .remove-image", function(){ + if (confirm("Delete this image?")) { + var $el = $(this).closest(".image") + $el.removeClass('loaded') + $el.find(".uri").val("") + $el.find(".caption").val("") + $el.find("img").attr("src", "") + } + }) // make the region sortable with drag-and-drop $(".captioned-image-list ol").sortable() $(".captioned-image-list ol").disableSelection() - - // delete image - $(document).on("mousedown", ".remove-image", function(){ - if (confirm("Delete this image?")) { - $(this).parent().remove() - } - }) // populate a video field with info from our url parser var last_url diff --git a/themes/okadmin/public/js/upload.js b/themes/okadmin/public/js/upload.js index 1c9094c..39f7427 100644 --- a/themes/okadmin/public/js/upload.js +++ b/themes/okadmin/public/js/upload.js @@ -1,55 +1,48 @@ -var OKUpload = { - action: "/_services/image", - - bind: function(el){ - if (! el) return - el.addEventListener("change", OKUpload.handleFileSelect) - }, - - handleFileSelect: function(e) { - e.stopPropagation(); - e.preventDefault(); - - var files = e.dataTransfer ? e.dataTransfer.files : e.target.files; - - for (var i = 0, f; f = files[i]; i++) { - if ( ! f.type.match('image.*')) { - continue; - } - OKUpload.upload(f) - } - }, +var OKUpload = function(){ + this.action = "/_services/image" +} +OKUpload.prototype.bind = function(el){ + if (el.length) el = el[0] + el.addEventListener("change", this.handleFileSelect.bind(this)) +} +OKUpload.prototype.handleFileSelect = function(e) { + e.stopPropagation(); + e.preventDefault(); - upload: function(f){ - var fd = new FormData() - fd.append('image', f) + var files = e.dataTransfer ? e.dataTransfer.files : e.target.files; - var request = $.ajax({ - url: OKUpload.action, - type: "post", - data: fd, - dataType: "json", - processData: false, - contentType: false, - }) - request.done(OKUpload.success) - }, - - success: function(media){ - if (media.error) { - console.log(media.error) - return + for (var i = 0, f; f = files[i]; i++) { + if ( ! f.type.match('image.*')) { + continue; } - OKUpload.add(media) - }, - - add: function(media){ - console.log(media) - }, - - error: function(error){ - throw error - }, + this.upload(f) + } +} +OKUpload.prototype.upload = function(f){ + var fd = new FormData() + fd.append('image', f) + var request = $.ajax({ + url: this.action, + type: "post", + data: fd, + dataType: "json", + processData: false, + contentType: false, + }) + request.done(this.success.bind(this)) +} +OKUpload.prototype.success = function(media){ + if (media.error) { + console.log(media.error) + return + } + this.add(media) +} +OKUpload.prototype.add = function(media){ + console.log(media) +} +OKUpload.prototype.error = function(error){ + throw error } diff --git a/themes/okadmin/templates/partials/inputs.liquid b/themes/okadmin/templates/partials/inputs.liquid index 253b275..c9a4d92 100644 --- a/themes/okadmin/templates/partials/inputs.liquid +++ b/themes/okadmin/templates/partials/inputs.liquid @@ -22,15 +22,48 @@ {% elsif type == 'video' %}
- - + +
+ {% elsif type == 'image' %} +
+
+
+ + +
+ +
+
+ + + {{spec.value.caption}} + +
+
{% elsif type == 'captioned-image-list' %} -
+
+
+
+ + +
+ +
+ + +
    {% for image in spec.value %}
  1. @@ -41,19 +74,6 @@
  2. {% endfor %}
-
- - -
- -
{% elsif type == 'meta' %} -- cgit v1.2.3-70-g09d2 From 43063c3242ccaf95e39fff240d501de38131f7c5 Mon Sep 17 00:00:00 2001 From: Sean Fridman Date: Thu, 16 Apr 2015 23:38:16 -0400 Subject: Add number type support --- app/node_modules/okschema/index.js | 12 +++++++++++- themes/okadmin/templates/partials/inputs.liquid | 4 ++++ 2 files changed, 15 insertions(+), 1 deletion(-) (limited to 'themes/okadmin/templates') diff --git a/app/node_modules/okschema/index.js b/app/node_modules/okschema/index.js index d53ed7b..c5a56c4 100644 --- a/app/node_modules/okschema/index.js +++ b/app/node_modules/okschema/index.js @@ -68,6 +68,9 @@ var types = { * OKSchema! * Meant as a thin wrapper around some existing schema validation * module, mostly to allow for the extension of types. + * + * NOTE: Currently just assumes spec is valid. If you give a bad spec + * strange things may or may not happen */ function OKSchema(spec) { if (!(this instanceof OKSchema)) return new OKSchema(spec); @@ -138,11 +141,18 @@ OKSchema.prototype.assertValid = function(data) { var type = spec[prop].type; if (types[type]) { types[type].assertValid(spec[prop], data[prop]); + // Also check if it's a number type and try to cast it + // otherwise pass and let mschema handle + } else if (type === 'number') { + try { + data[prop] = parseFloat(data[prop]); + } catch (err) {} } }); var result = mschema.validate(data, this.toMschema()); - if (!result.valid) + if (!result.valid) { throw result.errors; + } }; /** diff --git a/themes/okadmin/templates/partials/inputs.liquid b/themes/okadmin/templates/partials/inputs.liquid index c9a4d92..4d31413 100644 --- a/themes/okadmin/templates/partials/inputs.liquid +++ b/themes/okadmin/templates/partials/inputs.liquid @@ -12,6 +12,10 @@ {% elsif type == 'text' %} + {% elsif type == 'number' %} + {% elsif type == 'enum' %} + {% endfor %} -- cgit v1.2.3-70-g09d2 From 3e2d7e98230990ad954b33203e0611358c1fa915 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 27 Apr 2015 14:24:20 -0400 Subject: stubbing in videos --- app/node_modules/okadminview/index.js | 1 + site/index.js | 3 +- site/templates/project.liquid | 5 ++- themes/okadmin/public/css/main.css | 17 +++++--- themes/okadmin/public/js/app.js | 58 ++++++++++++++++++++----- themes/okadmin/public/js/upload.js | 15 ++++++- themes/okadmin/templates/partials/inputs.liquid | 55 +++++++++++++++++++++-- 7 files changed, 130 insertions(+), 24 deletions(-) (limited to 'themes/okadmin/templates') diff --git a/app/node_modules/okadminview/index.js b/app/node_modules/okadminview/index.js index 82f364d..2a0fcd5 100644 --- a/app/node_modules/okadminview/index.js +++ b/app/node_modules/okadminview/index.js @@ -157,6 +157,7 @@ function OKAdminView(options) { resourceMissingHandler(req, res)() } else { view.renderResource(req, res, assign(data, { + JSON: JSON, success: req.flash('success'), errors: req.flash('errors') })); diff --git a/site/index.js b/site/index.js index 8bb4b4d..a7b207a 100644 --- a/site/index.js +++ b/site/index.js @@ -5,8 +5,7 @@ var projectSchema = { title: {type: 'string'}, menu: {type: 'string'}, description: {type: 'text'}, - video: {type: 'video'}, - images: {type: 'captioned-image-list'}, + images: {type: 'media-list'}, thumbnail: {type: 'image'}, } diff --git a/site/templates/project.liquid b/site/templates/project.liquid index b54722d..3d32c0d 100644 --- a/site/templates/project.liquid +++ b/site/templates/project.liquid @@ -1,7 +1,10 @@
{{project.title}} - +
+ PREVIOUS ASSET + NEXT ASSET +
- +
@@ -49,6 +49,55 @@
+ {% elsif type == 'media-list' %} +
+
+
+ + +
+ +
+ + + + + +
    + {% for image in spec.value %} + {% if image.token %} +
  1. + {{ JSON.stringify(spec.value) }} +
  2. + {% else %} +
  3. + + + {{image.caption}} + +
  4. + {% endif %} + {% endfor %} +
+
{% elsif type == 'captioned-image-list' %}
@@ -56,10 +105,10 @@
- +
- @@ -123,7 +134,7 @@ {{image.caption}} - + {% endfor %} -- cgit v1.2.3-70-g09d2 From e75bc9e99c672d774e1e935b37c73970d7b6d2c8 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Fri, 1 May 2015 19:10:17 -0400 Subject: edits --- site/index.js | 1 + site/public/assets/images/next.png | Bin 563 -> 1063 bytes site/public/assets/images/prev.png | Bin 0 -> 1069 bytes site/public/assets/javascripts/_env.js | 33 +++++++++++++++++++--- site/public/assets/style.css | 35 ++++++++++++++++++++---- site/templates/page.liquid | 4 --- site/templates/project.liquid | 6 ++-- themes/okadmin/templates/partials/inputs.liquid | 1 + 8 files changed, 63 insertions(+), 17 deletions(-) create mode 100644 site/public/assets/images/prev.png (limited to 'themes/okadmin/templates') diff --git a/site/index.js b/site/index.js index 3434742..50bd870 100644 --- a/site/index.js +++ b/site/index.js @@ -41,6 +41,7 @@ var app = okcms.createApp({ { type: 'page', static: {id: 'about'}}, { type: 'page', static: {id: 'contact'}}, { type: 'shape', static: {id: 'shape-images'}}, + { type: 'shape', static: {id: 'about-images'}}, { type: 'advertising' }, { type: 'content' }, { type: 'experiential' }, diff --git a/site/public/assets/images/next.png b/site/public/assets/images/next.png index 7997259..b5782ed 100644 Binary files a/site/public/assets/images/next.png and b/site/public/assets/images/next.png differ diff --git a/site/public/assets/images/prev.png b/site/public/assets/images/prev.png new file mode 100644 index 0000000..82050a4 Binary files /dev/null and b/site/public/assets/images/prev.png differ diff --git a/site/public/assets/javascripts/_env.js b/site/public/assets/javascripts/_env.js index 45d5231..3a72e13 100644 --- a/site/public/assets/javascripts/_env.js +++ b/site/public/assets/javascripts/_env.js @@ -286,6 +286,21 @@ function build_scene () { offset: 200, }) ) + var wasPrev = false, navWidth + function resize_for_prev_next(){ + navWidth = $("nav").width() + } + resize_for_prev_next() + $(window).resize(resize_for_prev_next) + $(window).mousemove(function(e){ + if (! gallery) return + prev = ((e.pageX - navWidth) / window.innerWidth) < 0.39 + if (prev !== wasPrev) { + wasPrev = prev + $("#okgallery").toggleClass("prev", prev) + } + }) + strips.forEach(function(strip){ strip.update(0) }) scene.update() @@ -416,9 +431,15 @@ function build_gallery () { }) $("#okgallery .video").each(function(){ - var $play = $('
') var $el = $(this) + if (! is_mobile) { + var $underlay = $('
') + $underlay.css("background-image", $el.css("background-image")) + $el.css("background-image", 'none') + } + var $play = $('
') $el.append($play) + $el.append($underlay) if (is_desktop) { $play.on("click", function(e){ e.stopPropagation() @@ -454,7 +475,11 @@ function build_gallery () { // load_video($el) } else { - gallery.next() + if ($("#okgallery").hasClass("prev")) { + gallery.previous() + } else { + gallery.next() + } } }) gallery.loader.on("progress", function(imagesLoaded, loadingImage){ @@ -484,8 +509,8 @@ function load_video ($el) { var $embed = $('') $el.append($embed) if (! is_mobile) { - var $mask = $('
') - $el.append($mask) +// var $mask = $('
') +// $el.append($mask) } var player = $f( $el.find("iframe")[0] ) $el.data('player', player) diff --git a/site/public/assets/style.css b/site/public/assets/style.css index 543a34a..6316159 100644 --- a/site/public/assets/style.css +++ b/site/public/assets/style.css @@ -337,7 +337,7 @@ nav .sub { nav .sub.active { display: inline-block; - max-height:180px; + max-height: 450px; } nav .sub a { @@ -519,12 +519,14 @@ nav .sub.active a { -webkit-column-count: 3; -moz-column-count: 3; column-count: 3; + min-height: 130px; } .entry span div.content.noline { border-top: 0; padding-top: 0; } .entry span div.content div { + min-height: 130px; width:50%; -webkit-column-count: 3; -moz-column-count: 3; @@ -573,6 +575,10 @@ nav .sub.active a { height:100%; cursor: url(images/next.png), auto!important; } +.gallery.prev, +.gallery.prev .cell { + cursor: url(images/prev.png), auto!important; +} .cell.video { width: 80%; background-size: cover; @@ -613,12 +619,24 @@ nav .sub.active a { -webkit-transition:0.4s opacity ease-in; transition:0.4s opacity ease-in; pointer-events: none; -} -.cell iframe { height: 200%; -webkit-transform: translateY(-25%); transform: translateY(-25%); } +.cell .underlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height:100%; + opacity:0.2; + -webkit-transition:0.4s opacity ease-in; + transition:0.4s opacity ease-in; + pointer-events: none; + background-size: cover; + background-position: center center; +} + .fullscreen { text-align: right; } @@ -679,22 +697,27 @@ nav .sub.active a { opacity:0.0; transition:0.4s opacity ease-in; } + .cell img.loaded { opacity: 0.2; } -.cell.is-selected img, .cell.is-selected iframe { +.cell.is-selected .underlay, .cell.is-selected img, .cell.is-selected iframe { opacity:1; pointer-events: auto; } -.cell .mask { +.cell .underlay { z-index: 2; width: 100%; height: 100%; position: absolute; top: 0; left: 0; } -.cell.playing .mask { +.cell.loaded .underlay { + background-image: none !important; +} +.cell.playing .underlay { pointer-events: none; + opacity: 0; } .logo { position: fixed; diff --git a/site/templates/page.liquid b/site/templates/page.liquid index 5c3cabe..63f71f2 100644 --- a/site/templates/page.liquid +++ b/site/templates/page.liquid @@ -2,10 +2,6 @@ {% if page.image %} {{page.title}} -
- PREVIOUS ASSET - NEXT ASSET -
{{page.body | newline_to_br}} diff --git a/site/templates/project.liquid b/site/templates/project.liquid index 0dc828c..8c9a26e 100644 --- a/site/templates/project.liquid +++ b/site/templates/project.liquid @@ -2,13 +2,13 @@ {{project.title}}
- PREVIOUS ASSET - NEXT ASSET + PREVIOUS + NEXT
+ {% elsif type == 'meta' %} {% else %} -- cgit v1.2.3-70-g09d2 From 22d12686d920414098394f0305e12a942807c150 Mon Sep 17 00:00:00 2001 From: Julie Lala Date: Sun, 17 May 2015 13:54:46 +0200 Subject: about page --- site/db.json | 104 ++++++++++++++++-------- site/index.js | 3 +- site/public/assets/javascripts/app.js | 6 ++ site/public/assets/style.css | 70 ++++++++++++++-- site/templates/about.liquid | 10 +-- themes/okadmin/public/css/main.css | 3 + themes/okadmin/templates/partials/inputs.liquid | 31 +++++++ 7 files changed, 182 insertions(+), 45 deletions(-) (limited to 'themes/okadmin/templates') diff --git a/site/db.json b/site/db.json index 9f6498a..ab95019 100644 --- a/site/db.json +++ b/site/db.json @@ -1251,9 +1251,11 @@ { "id": "about", "title": "WHO WE ARE", - "body": "TWO HUSTLERS IS A CREATIVE COLLECTIVE OF RADICAL THINKERS, DESIGNERS AND STORYTELLERS.\r\n\r\nWE BUILD TRANSFORMATIVE EXPERIENCES FOR PASSIONATE BRANDS. \r\n\r\nWE ARE PLAYFUL. WE ARE REBELLIOUS. WE ARE OBSESSED. \r\n\r\n\r\n\r\nFOR BRANDS WHO WANT TO PLAY WITH US, SAY HELLO!\r\n\r\nFOR ANYONE WHO WANTS TO JOIN OUR FAMILY, SHOW US WHAT YOU ARE MADE OF!\r\n\r\nWEBSITE BY OKFOCUS", + "body": "TWO HUSTLERS IS A CREATIVE COLLECTIVE OF RADICAL THINKERS, DESIGNERS AND STORYTELLERS.\r\n\r\nWE BUILD TRANSFORMATIVE EXPERIENCES FOR PASSIONATE BRANDS. \r\n\r\nWE ARE PLAYFUL. WE ARE REBELLIOUS. WE ARE OBSESSED. ", "image": "http://www.lansdowneresort.com/meetings/assets/images/masthead/meetings-team-building.jpg", - "__index": "1" + "__index": "1", + "contact": "FOR BRANDS WHO WANT TO PLAY WITH US, SAY HELLO!\r\n\r\nFOR ANYONE WHO WANTS TO JOIN OUR FAMILY, SHOW US WHAT YOU ARE MADE OF!\r\n\r\nWEBSITE BY OKFOCUS", + "dateCreated": "" }, { "id": "contact", @@ -1337,66 +1339,102 @@ "__index": "1", "images": [ { - "uri": "https://ltho.s3.amazonaws.com/twohustlers%2Fc9b7ab94-a319-48b4-871b-6d1f0a91c55b.gif", - "caption": "Sara@nicopanda.com" + "uri": "https://ltho.s3.amazonaws.com/twohustlers%2F3031754c-9295-4690-bb38-d1b21249f542.gif", + "caption": "", + "label": "Nicola Formichetti" + }, + { + "uri": "https://ltho.s3.amazonaws.com/twohustlers%2F06a6a4c3-10ad-4b75-8351-85ffc0e74c98.gif", + "caption": "", + "label": "Kevin Kollenda" + }, + { + "uri": "https://ltho.s3.amazonaws.com/twohustlers%2F5bece78f-bf0b-4422-abc6-d306f8fae700.gif", + "caption": "propersavage@gmail.com", + "label": "Devin Savage" }, { - "uri": "https://ltho.s3.amazonaws.com/twohustlers%2F9303920a-07a1-457f-a33d-8959f0acc240.gif", - "caption": "propersavage@gmail.com" + "uri": "https://ltho.s3.amazonaws.com/twohustlers%2F71c71033-d36f-4375-bdd1-271db3b9e75c.gif", + "caption": "", + "label": "Zak Krevitt" }, { - "uri": "https://ltho.s3.amazonaws.com/twohustlers%2F085bc32f-f3fa-485f-8411-4b0e33c87c34.gif", - "caption": "Tracy@Twohustlers.com" + "uri": "https://ltho.s3.amazonaws.com/twohustlers%2F742c60d2-9f3f-44bb-a445-71871ca28439.gif", + "caption": "", + "label": "Tyler Rose" }, { - "uri": "https://ltho.s3.amazonaws.com/twohustlers%2F3199e264-13d0-4331-9b3a-9f453e723d4e.gif", - "caption": "Kei@twohustlers.com" + "uri": "https://ltho.s3.amazonaws.com/twohustlers%2F7eca88a2-94e1-4d41-ae77-af01a947ad44.gif", + "caption": "", + "label": "Tracy le Marquand" }, { - "uri": "https://ltho.s3.amazonaws.com/twohustlers%2Fbe142c51-d613-41a9-9432-f96ce4493f01.gif", - "caption": "Steve@twohustlers.com" + "uri": "https://ltho.s3.amazonaws.com/twohustlers%2Fe85e3d1f-6191-496f-acca-f370687c69fe.gif", + "caption": "", + "label": "Max de Castro" }, { - "uri": "https://ltho.s3.amazonaws.com/twohustlers%2Fc91b507a-9a1d-41d6-a500-138c14b8bed2.gif", - "caption": "Max@twohustlers.com" + "uri": "https://ltho.s3.amazonaws.com/twohustlers%2F2b71ee1e-3de9-4a3d-9b39-a96065ae4ec1.gif", + "caption": "", + "label": "Ian Milan" }, { - "uri": "https://ltho.s3.amazonaws.com/twohustlers%2Fb40d3a6d-1348-4861-a0ab-1280480d1c20.gif", - "caption": "tomorrowistheendoftheworld@gmail.com" + "uri": "https://ltho.s3.amazonaws.com/twohustlers%2F17b0d9b9-cd22-43ac-9055-f8bc8cb54700.gif", + "caption": "Sara@nicopanda.com", + "label": "Sarah Kim" }, { - "uri": "https://ltho.s3.amazonaws.com/twohustlers%2F2306f2f9-e41b-46bb-9458-6d0624b8f6ba.gif", - "caption": "Tiffanie@twohustlers.com" + "uri": "https://ltho.s3.amazonaws.com/twohustlers%2F343ae47e-8669-4c57-9975-e4c3fc5a02d4.gif", + "caption": "", + "label": "Steve Gershman" }, { - "uri": "https://ltho.s3.amazonaws.com/twohustlers%2Fe4ee44a3-0b21-4767-8584-397425abb291.gif", - "caption": "kevin@twohustlers.com" + "uri": "https://ltho.s3.amazonaws.com/twohustlers%2F55f0fef9-bc7c-4dbe-baa8-c0d74c9c9ab0.gif", + "caption": "", + "label": "Latif Newab" }, { - "uri": "https://ltho.s3.amazonaws.com/twohustlers%2Fff60aa79-d4ad-43d2-915e-d8e253330ca4.gif", - "caption": "Latif@nicopanda.com" + "uri": "https://ltho.s3.amazonaws.com/twohustlers%2F724e1ff5-7683-43cb-a637-9dae58214185.gif", + "caption": "", + "label": "Kei Furuichi" }, { - "uri": "https://ltho.s3.amazonaws.com/twohustlers%2Fc8e8276c-3b7c-48e1-8e1f-de902ca1054d.gif", - "caption": "Ian@studioformichetti.com" + "uri": "https://ltho.s3.amazonaws.com/twohustlers%2F70fffb9c-7fc9-4dd1-af65-e39ebd99e930.gif", + "caption": "dereklmurdock@gmail.com", + "label": "Derrick Murdock" }, { - "uri": "https://ltho.s3.amazonaws.com/twohustlers%2F4369b27f-095e-4e05-b7b8-3dc88f0a652f.gif", - "caption": "dereklmurdock@gmail.com" + "uri": "https://ltho.s3.amazonaws.com/twohustlers%2F7655a0ec-e56c-4383-a22a-7e987949f52e.gif", + "caption": "Juan@nicopanda.com", + "label": "Juan Quiceno" }, { - "uri": "https://ltho.s3.amazonaws.com/twohustlers%2Fa0eed5ee-1c19-41f4-be2e-d0655874be71.gif", - "caption": "Tyler@nicopanda.com" + "uri": "https://ltho.s3.amazonaws.com/twohustlers%2F04b3e31f-b9ac-48c8-9c0c-7c88abe771b5.gif", + "caption": "", + "label": "Andreas Aresti" }, { - "uri": "https://ltho.s3.amazonaws.com/twohustlers%2F959c8f09-9562-4d43-8bfb-4f73b9f71dcc.gif", - "caption": "Daniel@studioformichetti.com" + "uri": "https://ltho.s3.amazonaws.com/twohustlers%2Fa547b434-b48d-43ff-986b-ed9c217b9257.gif", + "caption": "", + "label": "Tiffanie Baine" }, { - "uri": "https://ltho.s3.amazonaws.com/twohustlers%2Fe9743a0f-7c5e-411a-b59e-683e6ff9d407.gif", - "caption": "Juan@nicopanda.com" + "uri": "https://ltho.s3.amazonaws.com/twohustlers%2F97c09ed8-27d7-4a38-8877-c8712640cbd5.gif", + "caption": "", + "label": "Frankie The Pug" + }, + { + "uri": "https://ltho.s3.amazonaws.com/twohustlers%2F4bd5a1e5-38b1-4dba-af04-48ce3f4bc74d.gif", + "caption": "", + "label": "Daniel Cingari" + }, + { + "uri": "https://ltho.s3.amazonaws.com/twohustlers%2F7ee0e3d4-4312-41dc-8fff-943b68ae6171.gif", + "caption": "", + "label": "Angelo Balassone" } - ] + ], + "dateCreated": "" } ] } \ No newline at end of file diff --git a/site/index.js b/site/index.js index 4c5c2ca..04d2455 100644 --- a/site/index.js +++ b/site/index.js @@ -24,6 +24,7 @@ var app = okcms.createApp({ id: {type: 'string', hidden: true}, title: {type: 'string'}, body: {type: 'text'}, + contact: {type: 'text'}, image: {type: 'string'} }, advertising: projectSchema, @@ -33,7 +34,7 @@ var app = okcms.createApp({ shape: { id: {type: 'string', id: true, hidden: true}, title: {type: 'string'}, - images: {type: 'captioned-image-list'}, + images: {type: 'double-captioned-image-list'}, } }, diff --git a/site/public/assets/javascripts/app.js b/site/public/assets/javascripts/app.js index 0d51a3f..4e00f30 100644 --- a/site/public/assets/javascripts/app.js +++ b/site/public/assets/javascripts/app.js @@ -19,6 +19,12 @@ app.init = function () { app.launch = function () { // if ($.browser.msie || ! has3d()) { return app.fallback() } + if ($.browser.msie) { + $("html").addClass("msie") + } + else { + $("html").addClass("notmsie") + } scene = new MX.Scene().addTo('#scene') diff --git a/site/public/assets/style.css b/site/public/assets/style.css index fe08fed..2d0bd5a 100644 --- a/site/public/assets/style.css +++ b/site/public/assets/style.css @@ -713,6 +713,9 @@ nav .sub.active a { opacity: 1.0; cursor:pointer; } +.msie .entry .caption { + display: none; +} .desktop .caption:hover { background:#222; color:#222; @@ -824,16 +827,36 @@ nav .sub.active a { top:0; } +.entry .brady { + width: 72vw; +} .brady { display: block; - max-width: 1001px; } -.brady a, .brady img { - width: 200px; height: 200px; +.brady > a { + width: 18vw; height: 18vw; + background-size: cover; + background-position: center center; + position: relative; + display: block; + float: left; +} +.brady div { + width: 17vw; + height: 16w; position: relative; - display: inline-block; + display: block; + float: left; + padding: 1vw; + font-size: 0.8vw; + line-height: 1.4vw; + border: 1px solid black; + margin: 0.5vw 0.5vw 0 0.5vw; } -.desktop .brady a:hover:after { +.brady > a:nth-child(3) { + margin-right: 1vw; +} +.desktop .brady > a:hover:after { content: 'SAY HELLO!'; position: absolute; top: 40%; @@ -843,6 +866,25 @@ nav .sub.active a { font-size: 22px; width: 100%; } +.brady span { + position: absolute; + bottom: 0; + left: 0; + background: white; + opacity: 0; + color: black; + margin-top: -4px; + font-size: 1vw; + padding: 2px 0 1px 2px; + + transition: 0.1s opacity ease-in; + display: block; + text-overflow: ellipsis; + text-transform: uppercase; +} +.desktop .brady > a:hover span { + opacity: 1; +} .project { float: left; @@ -860,6 +902,9 @@ nav .sub.active a { .desktop .ready .project:hover { opacity: 1.0; } +.msie .project { + opacity: 1.0 !important; +} .entry.hover .project { opacity: 0.5 } .entry.hover .project.hover { opacity: 1.0 } @@ -884,7 +929,8 @@ nav .sub.active a { text-transform: uppercase; } .mobile .project span, -.desktop .project:hover span { +.desktop .project:hover span, +.msie .project span { opacity: 1; } .undone .project:nth-child(1) { transition-delay:0.05s; } @@ -1044,6 +1090,18 @@ nav .sub.active a { font-size: 0.6em; width: 120px; } + nav .bottom { + height: 27%; + } + nav .sub.active a { + padding: 2px 0 4px 20px; + } + nav .cat { + padding: 2px 0 2px 10px; + } + .contact { + margin-top: 6px; + } .menuActive #entry_container .entry.all { width:65%; } diff --git a/site/templates/about.liquid b/site/templates/about.liquid index 6c762b2..c693b61 100644 --- a/site/templates/about.liquid +++ b/site/templates/about.liquid @@ -1,9 +1,9 @@
- {{page.title}} - {% for image in shape.images %}{% endfor %} -
- {{page.body | newline_to_br}} -
+ +
{{page.body | newline_to_br}}
+ {% for image in shape.images %}{{ image.label }}{% endfor %} +
{{page.contact | newline_to_br}}
+
diff --git a/themes/okadmin/public/css/main.css b/themes/okadmin/public/css/main.css index 5dbd910..e5af10c 100644 --- a/themes/okadmin/public/css/main.css +++ b/themes/okadmin/public/css/main.css @@ -335,9 +335,12 @@ button, input[type=submit] { .image-element .remove:hover { color: red; } + +/* .remove { display: none; } + */ #delete_form button:hover { color: red } diff --git a/themes/okadmin/templates/partials/inputs.liquid b/themes/okadmin/templates/partials/inputs.liquid index b29a289..1ddbffd 100644 --- a/themes/okadmin/templates/partials/inputs.liquid +++ b/themes/okadmin/templates/partials/inputs.liquid @@ -139,7 +139,38 @@ {% endfor %}
+ {% elsif type == 'double-captioned-image-list' %} +
+
+
+ + +
+ +
+ + +
    + {% for image in spec.value %} +
  1. + + + + {{image.caption}} + +
  2. + {% endfor %} +
+
{% elsif type == 'meta' %} {% else %} -- cgit v1.2.3-70-g09d2 From d595b5447a40245d33ac2263f01123b7ea835119 Mon Sep 17 00:00:00 2001 From: Julie Lala Date: Sun, 17 May 2015 14:08:58 +0200 Subject: blah --- themes/okadmin/templates/partials/inputs.liquid | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'themes/okadmin/templates') diff --git a/themes/okadmin/templates/partials/inputs.liquid b/themes/okadmin/templates/partials/inputs.liquid index 1ddbffd..deaf260 100644 --- a/themes/okadmin/templates/partials/inputs.liquid +++ b/themes/okadmin/templates/partials/inputs.liquid @@ -151,22 +151,22 @@
    {% for image in spec.value %}
  1. - - - {{image.caption}} + + +
  2. {% endfor %}
-- cgit v1.2.3-70-g09d2 From fdb5ca9b53d640bacced7ce9f1c5cb2043fabd75 Mon Sep 17 00:00:00 2001 From: Julie Lala Date: Sun, 17 May 2015 14:09:45 +0200 Subject: being very nice --- themes/okadmin/templates/partials/inputs.liquid | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'themes/okadmin/templates') diff --git a/themes/okadmin/templates/partials/inputs.liquid b/themes/okadmin/templates/partials/inputs.liquid index deaf260..6eb1e43 100644 --- a/themes/okadmin/templates/partials/inputs.liquid +++ b/themes/okadmin/templates/partials/inputs.liquid @@ -154,8 +154,8 @@ {{image.caption}} - - + + @@ -165,8 +165,8 @@ {{image.caption}} - - + + {% endfor %} -- cgit v1.2.3-70-g09d2 From 7e40774959e67f48035da8653b666dd05f35c497 Mon Sep 17 00:00:00 2001 From: Sean Fridman Date: Tue, 26 May 2015 17:11:45 -0400 Subject: Add tag-list input type --- app/node_modules/okschema/index.js | 4 ++++ themes/okadmin/templates/partials/inputs.liquid | 5 +++++ 2 files changed, 9 insertions(+) (limited to 'themes/okadmin/templates') diff --git a/app/node_modules/okschema/index.js b/app/node_modules/okschema/index.js index c5a56c4..0079f51 100644 --- a/app/node_modules/okschema/index.js +++ b/app/node_modules/okschema/index.js @@ -61,6 +61,10 @@ var types = { 'meta': { parent: 'string', assertValid: function(spec, value) {} + }, + 'tag-list': { + parent: 'string', + assertValid: function(spec, value) {} } } diff --git a/themes/okadmin/templates/partials/inputs.liquid b/themes/okadmin/templates/partials/inputs.liquid index 6eb1e43..25ad197 100644 --- a/themes/okadmin/templates/partials/inputs.liquid +++ b/themes/okadmin/templates/partials/inputs.liquid @@ -49,6 +49,11 @@
+ {% elsif type == 'tag-list' %} +
+ +
{% elsif type == 'media-list' %}
-- cgit v1.2.3-70-g09d2 From e923cb0e5e1efac4fba534aba87f6b6e9d95d3f0 Mon Sep 17 00:00:00 2001 From: Sean Fridman Date: Tue, 2 Jun 2015 15:55:45 -0400 Subject: Add link-list field type --- themes/okadmin/public/css/main.css | 6 ++++ themes/okadmin/public/js/app.js | 39 ++++++++++++++++++++++++- themes/okadmin/templates/partials/inputs.liquid | 25 +++++++++++++++- 3 files changed, 68 insertions(+), 2 deletions(-) (limited to 'themes/okadmin/templates') diff --git a/themes/okadmin/public/css/main.css b/themes/okadmin/public/css/main.css index e5af10c..094e66b 100644 --- a/themes/okadmin/public/css/main.css +++ b/themes/okadmin/public/css/main.css @@ -301,6 +301,12 @@ button, input[type=submit] { .main.resource form .video-element input[type=text] { width: 15em; } +.main .link-list .add-link-btn, +.main .link-list .remove-link-btn { + margin: 0; + height: 2em; + line-height: 1em; +} .add-image-button { background: #ddd; clear: left; diff --git a/themes/okadmin/public/js/app.js b/themes/okadmin/public/js/app.js index 2667ce6..f989c7b 100644 --- a/themes/okadmin/public/js/app.js +++ b/themes/okadmin/public/js/app.js @@ -99,7 +99,44 @@ var OKAdmin = function(){ $el.parent().find(".video-thumb").val( media.thumbnail ) }) })) - + + // Add a new link to the list + $('.link-list').on('click', '.add-link-btn', function(e) { + e.preventDefault() + e.stopPropagation() + var $delegate = $(e.delegateTarget) + var $list = $delegate.find('.links') + var length = $list.find('input').length + var name = $delegate.parent('.property').data('name') + var $new = $delegate.find('.link-input-new') + var input = document.createElement('input') + var delBtn = document.createElement('button') + var inputName = name + '[' + length + ']' + $(input).attr({ + name: inputName, + type: 'text', + value: $new.val() + }) + $list.append(input) + $(delBtn).addClass('remove-link-btn') + $(delBtn).data('for', inputName) + delBtn.innerHTML = '-' + $list.append(delBtn) + $new.val('') + }) + + // Remove a link from the list + $('.link-list').on('click', '.remove-link-btn', function(e) { + e.preventDefault() + e.stopPropagation() + var $delegate = $(e.delegateTarget) + var $target = $(e.target) + var inputName = $target.data('for') + var $input = $delegate.find('[name="' + inputName + '"]') + $input.remove() + $target.remove() + }) + // fix post indexing in list-driven inputs $(".main.resource form").submit(function(e){ var $id = $("[name=id]"), $title = $("[name=title]"), $menu = $("[name=menu]"), $section = $(".resource.main") diff --git a/themes/okadmin/templates/partials/inputs.liquid b/themes/okadmin/templates/partials/inputs.liquid index 25ad197..0d5321b 100644 --- a/themes/okadmin/templates/partials/inputs.liquid +++ b/themes/okadmin/templates/partials/inputs.liquid @@ -3,7 +3,8 @@ {% assign spec = pair[1] %} {% assign type = spec.type %} -
+
{% if type == 'string' %} @@ -54,6 +55,28 @@
+ {% elsif type == 'link-list' %} + + + {% elsif type == 'media-list' %}
-- cgit v1.2.3-70-g09d2 From bcca89ebfd9ea93356d934edd5218335430746b6 Mon Sep 17 00:00:00 2001 From: Sean Fridman Date: Tue, 2 Jun 2015 17:29:57 -0400 Subject: Add 'date' field type --- app/node_modules/okschema/index.js | 4 ++++ themes/okadmin/public/css/main.css | 4 ++++ themes/okadmin/public/js/app.js | 19 +++++++++++++++++++ themes/okadmin/templates/partials/inputs.liquid | 17 +++++++++++++++-- 4 files changed, 42 insertions(+), 2 deletions(-) (limited to 'themes/okadmin/templates') diff --git a/app/node_modules/okschema/index.js b/app/node_modules/okschema/index.js index 0079f51..67f6e42 100644 --- a/app/node_modules/okschema/index.js +++ b/app/node_modules/okschema/index.js @@ -65,6 +65,10 @@ var types = { 'tag-list': { parent: 'string', assertValid: function(spec, value) {} + }, + 'date': { + parent: 'string', + assertValid: function(spec, value) {} } } diff --git a/themes/okadmin/public/css/main.css b/themes/okadmin/public/css/main.css index 094e66b..a5fbdeb 100644 --- a/themes/okadmin/public/css/main.css +++ b/themes/okadmin/public/css/main.css @@ -211,6 +211,10 @@ label { button, input[type=submit] { cursor: pointer; } +.main.resource .date input { + /* date inputs need font family override */ + font-family: "Helvetica", sans-serif; +} .main.resource form .group { display: block; float: left; diff --git a/themes/okadmin/public/js/app.js b/themes/okadmin/public/js/app.js index f989c7b..d58cb2a 100644 --- a/themes/okadmin/public/js/app.js +++ b/themes/okadmin/public/js/app.js @@ -162,6 +162,25 @@ var OKAdmin = function(){ $id.val( slug ) } + // Parse date input + $('.property .date').each(function(i, el) { + var name = $(el).parent('.property').data('name') + var $input = $(el).find('input') + var date = new Date($input.val()) + // Set to middle of day so it is the same date + // for all locales + date.setUTCHours(12) + var dateString = date.toUTCString() + var normalizedInput = document.createElement('input') + $(normalizedInput).attr({ + name: name, + type: 'text', + value: dateString + }) + $input.remove() + $(el).append(normalizedInput) + }) + $("ol").each(function(){ $("li", this).each(function(index){ $(this).find("input,textarea").each(function(){ diff --git a/themes/okadmin/templates/partials/inputs.liquid b/themes/okadmin/templates/partials/inputs.liquid index 0d5321b..e766558 100644 --- a/themes/okadmin/templates/partials/inputs.liquid +++ b/themes/okadmin/templates/partials/inputs.liquid @@ -50,10 +50,23 @@
+ + {% elsif type =='date' %} + +
+ +
+ {% elsif type == 'tag-list' %}
- +
{% elsif type == 'link-list' %} -- cgit v1.2.3-70-g09d2 From 27abfdd15714895894565124bcc660b9d6774494 Mon Sep 17 00:00:00 2001 From: Sean Fridman Date: Fri, 19 Jun 2015 15:29:19 -0400 Subject: Add 'flag' data type --- app/node_modules/okschema/index.js | 4 ++++ package.json | 2 +- themes/okadmin/public/js/app.js | 11 +++++++++++ themes/okadmin/templates/partials/inputs.liquid | 13 ++++++++++++- 4 files changed, 28 insertions(+), 2 deletions(-) (limited to 'themes/okadmin/templates') diff --git a/app/node_modules/okschema/index.js b/app/node_modules/okschema/index.js index 67f6e42..89b59cc 100644 --- a/app/node_modules/okschema/index.js +++ b/app/node_modules/okschema/index.js @@ -69,6 +69,10 @@ var types = { 'date': { parent: 'string', assertValid: function(spec, value) {} + }, + 'flag': { + parent: 'string', + assertValid: function(spec, value) {} } } diff --git a/package.json b/package.json index a8a602f..50ec3e6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "okcms", - "version": "0.1.0", + "version": "0.1.10", "description": "great", "main": "app/index.js", "scripts": { diff --git a/themes/okadmin/public/js/app.js b/themes/okadmin/public/js/app.js index d58cb2a..4be0afc 100644 --- a/themes/okadmin/public/js/app.js +++ b/themes/okadmin/public/js/app.js @@ -181,6 +181,17 @@ var OKAdmin = function(){ $(el).append(normalizedInput) }) + // Modify flags checkboxes such that unchecked ones return "false" + // instead of nothing + $('.property .flag').each(function(i, el) { + var input = el.querySelector('input') + var checked = !!input.checked + if (!checked) { + $(input).attr('value', 'false') + input.checked = true + } + }) + $("ol").each(function(){ $("li", this).each(function(index){ $(this).find("input,textarea").each(function(){ diff --git a/themes/okadmin/templates/partials/inputs.liquid b/themes/okadmin/templates/partials/inputs.liquid index e766558..9c1a26b 100644 --- a/themes/okadmin/templates/partials/inputs.liquid +++ b/themes/okadmin/templates/partials/inputs.liquid @@ -51,7 +51,7 @@
- {% elsif type =='date' %} + {% elsif type == 'date' %}
+ {% elsif type == 'flag' %} + +
+ +
+ {% elsif type == 'tag-list' %}
Date: Thu, 9 Jul 2015 16:58:02 -0400 Subject: Implement groupBy queries + admin interface --- app/index.js | 14 ++++--- app/node_modules/okadminview/index.js | 42 +++++++++------------ app/node_modules/okquery/index.js | 43 ++++++++++++++++++++- app/node_modules/okview/index.js | 26 +++++++------ themes/okadmin/public/js/app.js | 12 +++--- themes/okadmin/templates/index.liquid | 71 +++++++++++++++++++++++++---------- 6 files changed, 140 insertions(+), 68 deletions(-) (limited to 'themes/okadmin/templates') diff --git a/app/index.js b/app/index.js index 1c77728..d514f10 100644 --- a/app/index.js +++ b/app/index.js @@ -60,6 +60,7 @@ function OKCMS(options) { '/': { template: 'index' } }; var serviceConfig = options.services || {}; + var adminConfig = options.admin || {} var templateProvider = this._templateProvider = new OKTemplate({ root: templateRoot, @@ -84,7 +85,7 @@ function OKCMS(options) { this._createViews(viewConfig, db, meta, resourceCache, templateProvider, errorHandler); var adminViews = this._adminViews = - this._createAdminViews(adminPath, app, express, resourceConfig, + this._createAdminViews(adminConfig, adminPath, app, express, resourceConfig, resourceCache, adminTemplateProvider, adminMeta, errorHandler); @@ -194,9 +195,8 @@ OKCMS.prototype._createViews = function(viewConfig, db, } }; -OKCMS.prototype._createAdminViews = function(path, app, express, - resourceConfig, resourceCache, templateProvider, meta, - errorHandler) { +OKCMS.prototype._createAdminViews = function(adminConfig, path, app, express, + resourceConfig, resourceCache, templateProvider, meta, errorHandler) { var views = {}; var withTrail = withTrailingSlash(path); var withoutTrail = withoutTrailingSlash(path); @@ -221,7 +221,8 @@ OKCMS.prototype._createAdminViews = function(path, app, express, resourceCache: resourceCache, templateProvider: templateProvider, meta: meta, - errorHandler: errorHandler + errorHandler: errorHandler, + dashboardConfig: adminConfig.dashboard || {} }); return views; }; @@ -243,7 +244,8 @@ OKCMS.prototype._createQueries = function(queryConfig, resourceCache) { query: query, as: config.as, sortBy: config.sortBy, - descending: config.descending + descending: config.descending, + groupBy: config.groupBy }); }); }; diff --git a/app/node_modules/okadminview/index.js b/app/node_modules/okadminview/index.js index f6a7cdb..924f5a5 100644 --- a/app/node_modules/okadminview/index.js +++ b/app/node_modules/okadminview/index.js @@ -40,6 +40,8 @@ function OKAdminView(options) { if (!options.errorHandler) throw new Error('No error handler provided to OKAdminView'); + var dashboardConfig = options.dashboardConfig || {} + var dashboardResourceConfig = dashboardConfig.resources || {} var app = options.app; var express = options.express; var meta = options.meta; @@ -79,10 +81,12 @@ function OKAdminView(options) { var id = resource.getID(staticData); // Check to see if there's a more specific instance resource = resourceCache.get(type, id) || resource; + var resourceOptions = dashboardResourceConfig[type] || {} + var groupBy = resourceOptions.groupBy if (resource.bound) { - return OKQuery({resource: resource});; + return OKQuery({resource: resource, groupBy: groupBy}) } else { - return OKQuery({resource: resource, query: config.query}) + return OKQuery({resource: resource, query: config.query, groupBy: groupBy}) } }); @@ -123,7 +127,7 @@ function OKAdminView(options) { })); router.get('/', function readIndex(req, res, next) { - fetchIndexTemplateData(meta, indexQueries).then(function(data) { + fetchIndexTemplateData(meta, indexQueries, dashboardConfig).then(function(data) { view.renderIndex(req, res, assign(data, { success: req.flash('success'), errors: req.flash('errors') @@ -316,7 +320,9 @@ OKAdminView.prototype.renderResourceNew = function(req, res, data) { /** * Annotate template data with schema info */ -function fetchIndexTemplateData(meta, queries) { +function fetchIndexTemplateData(meta, queries, dashboardConfig) { + var resourceConfig = dashboardConfig.resources + return Q.promise(function(resolve, reject) { Q.all(queries.map(function(query) { return query.get(); @@ -327,27 +333,15 @@ function fetchIndexTemplateData(meta, queries) { var resource = queries[i].resource; // We want the raw object spec var spec = resource.spec; - var key = pluralize(resource.type); - if (!cache[key]) { - cache[key] = { - type: resource.type, - spec: spec, - data: [] - }; - } - - if (result.length) { - result.forEach(addData) - } else { - addData(result); + var dashConf = resourceConfig[resource.type] || {} + var groupBy = dashConf.groupBy + var key = pluralize(resource.type) + cache[key] = { + type: resource.type, + spec: spec, + data: result, + groupBy: groupBy } - - function addData(data) { - // Report id to template under standard name - data.id = resource.getID(data); - cache[key].data.push(data); - } - return cache; }, {}); diff --git a/app/node_modules/okquery/index.js b/app/node_modules/okquery/index.js index 4051f95..09d867d 100644 --- a/app/node_modules/okquery/index.js +++ b/app/node_modules/okquery/index.js @@ -43,10 +43,17 @@ function OKQuery(options) { enumerable: true }); + Object.defineProperty(this, 'groupBy', { + value: options.groupBy, + writable: false, + enumerable: true + }) + this.get = createQuery(resource, query, { default: options.default, sortField: sortField, - descending : descending + descending : descending, + groupBy: options.groupBy }); } @@ -66,6 +73,9 @@ function createQuery(resource, query, options) { if (options.default) { query = withDefault(query, options.default); } + if (options.groupBy) { + query = withGrouping(query, options.groupBy) + } return query; } @@ -124,6 +134,37 @@ function queryBound(resource) { }; } +/** + * Transform the query such that the results are grouped by the + * given field + */ +function withGrouping(queryFn, groupField) { + return function() { + return Q.Promise(function(resolve, reject) { + queryFn().then(function(data) { + data = data || [] + if (typeof data.length === 'undefined') { + data = [data] + } + var result = {} + result[groupField] = data.reduce(reduceToGroups, {}) + resolve(result) + }, reject) + }) + } + + function reduceToGroups(acc, data) { + var groupName = data[groupField] + if (groupName) { + if (!acc[groupName]) { + acc[groupName] = [] + } + acc[groupName].push(data) + } + return acc + } +} + function withDefault(queryFn, resultDefault) { return function() { return Q.Promise(function(resolve, reject) { diff --git a/app/node_modules/okview/index.js b/app/node_modules/okview/index.js index fba1c18..5f99d59 100644 --- a/app/node_modules/okview/index.js +++ b/app/node_modules/okview/index.js @@ -135,25 +135,28 @@ function fetchTemplateData(meta, queries, id) { if (!result) { return cache; } - var resource = queries[i].resource; - var type = queries[i].as || queries[i].type; + var query = queries[i] + var resource = query.resource; + var type = query.as || query.type; var manyResult = isarray(result); - // Inform template of ID in generic field - if (manyResult) { - result = result.map(function(data) { - return assign({}, data, {id: resource.getID(data)}) - }); - } else { - result = assign({}, result, {id: resource.getID(result)}); - } + var groupBy = query.groupBy // If we have a lot of results for a certain type, // we pluralize the key and yield an array of results - if (cache[type] || manyResult) { + if (cache[type] || manyResult || groupBy) { var plural = pluralize(type); delete cache[type]; cache[plural] = []; + // Pluralize grouped field + if (query.groupBy) { + result = Object.keys(result).reduce(function(acc, key) { + acc[pluralize(key)] = result[key] + return acc + }, {}) + } if (manyResult) { cache[plural] = cache[plural].concat(result); + } else if (groupBy) { + cache[plural] = result } else { cache[plural].push(result); } @@ -162,7 +165,6 @@ function fetchTemplateData(meta, queries, id) { } return cache; }, {meta: meta}); - resolve(normalized); } }).fail(reject); diff --git a/themes/okadmin/public/js/app.js b/themes/okadmin/public/js/app.js index 4be0afc..8a827ff 100644 --- a/themes/okadmin/public/js/app.js +++ b/themes/okadmin/public/js/app.js @@ -1,5 +1,5 @@ var OKAdmin = function(){ - + // initialize our multi-image uploader with an element and a template $(".group.image-list").each(function(){ var parent = this @@ -79,7 +79,7 @@ var OKAdmin = function(){ // make the region sortable with drag-and-drop $(".media-list ol, .image-list ol").sortable() $(".media-list ol, .image-list ol").disableSelection() - + // populate a video field with info from our url parser var last_url $(".video .url").on("focus", function(){ @@ -201,7 +201,7 @@ var OKAdmin = function(){ }) }) }) - + // delete individual records $("#delete_form").submit(function(e){ if (confirm("Are you sure you want to delete this record?")) { @@ -213,9 +213,9 @@ var OKAdmin = function(){ }) // reorder items in categories - $(".resource-category").on("click", ".edit-btn", function(e) { + $(".resource-category:not(.grouped)").on("click", ".edit-btn", function(e) { e.preventDefault(); - var $parent = $(e.delegateTarget); + var $parent = $(e.delegateTarget) var $editBtn = $parent.find(".edit-btn"); var $cancelBtn = $parent.find(".cancel-btn"); var $saveBtn = $parent.find(".save-btn"); @@ -245,7 +245,7 @@ var OKAdmin = function(){ }); // save new category order - $(".resource-category").on("submit", "form", function(e) { + $(".resource-category.root").on("submit", "form", function(e) { var $parent = $(e.delegateTarget); $parent.find(".resource-input").each(function(index) { var $input = $(this); diff --git a/themes/okadmin/templates/index.liquid b/themes/okadmin/templates/index.liquid index e9ad538..7af84b6 100644 --- a/themes/okadmin/templates/index.liquid +++ b/themes/okadmin/templates/index.liquid @@ -7,33 +7,66 @@ {% assign name = pair[0] %} {% assign resource = pair[1] %} -
+

{{name | capitalize}}

- -
    - {% for data in resource.data %} -
  1. - {{data.title}} - -
  2. + + {% if resource.groupBy %} + {% assign i = 0 %} + {% for pair in resource.data[resource.groupBy] %} + {% assign group = pair[0] %} + {% assign members = pair[1] %} +
    +
    +

    {{group | capitalize}}

    +
    +
      + {% for data in members %} +
    1. + {{data.title}} + +
    2. + {% assign i = i | plus: 1 %} + {% endfor %} +
    + +
    {% endfor %} + {% else %} +
      + {% for data in resource.data %} +
    1. + {{data.title}} + +
    2. + {% endfor %}
    - + + {% endif %}
- {% endfor %}
-- cgit v1.2.3-70-g09d2 From fb5605bdee9f527ffeefd0b59af01534b4d3b8ac Mon Sep 17 00:00:00 2001 From: Sean Fridman Date: Fri, 10 Jul 2015 15:20:03 -0400 Subject: Strikethrough disabled resources on admin index --- themes/okadmin/templates/index.liquid | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'themes/okadmin/templates') diff --git a/themes/okadmin/templates/index.liquid b/themes/okadmin/templates/index.liquid index 7af84b6..ae30bc8 100644 --- a/themes/okadmin/templates/index.liquid +++ b/themes/okadmin/templates/index.liquid @@ -27,7 +27,9 @@
    {% for data in members %}
  1. - {{data.title}} + {% if data.disabled == 'true' %} {% endif %} + {{data.title}} + {% if data.disabled == 'true' %} {% endif %}
  2. @@ -49,7 +51,9 @@
      {% for data in resource.data %}
    1. - {{data.title}} + {% if data.disabled == 'true' %} {% endif %} + {{data.title}} + {% if data.disabled == 'true' %} {% endif %}
    2. -- cgit v1.2.3-70-g09d2 From 7249dc10568091194a77990513fa2b77fdbd088a Mon Sep 17 00:00:00 2001 From: Sean Fridman Date: Fri, 10 Jul 2015 17:31:40 -0400 Subject: Implement basic foreign key support --- app/index.js | 23 ++++++ app/node_modules/okadminview/index.js | 100 ++++++++++++++++++------ app/node_modules/okquery/index.js | 1 + app/node_modules/okresource/index.js | 66 ++++++++++++++++ app/node_modules/okschema/index.js | 4 + themes/okadmin/templates/partials/inputs.liquid | 2 +- 6 files changed, 169 insertions(+), 27 deletions(-) (limited to 'themes/okadmin/templates') diff --git a/app/index.js b/app/index.js index d514f10..2507dd2 100644 --- a/app/index.js +++ b/app/index.js @@ -78,6 +78,7 @@ function OKCMS(options) { }); var resourceCache = this._resourceCache = this._createResources(resourceConfig, db, schemas); + this._resolveForeignKeys(resourceCache) var errorHandler = createErrorHandlerProducer( templateProvider, adminTemplateProvider, debug); // Create view instances from config @@ -154,6 +155,21 @@ OKCMS.prototype._createResources = function(resourceConfig, db, schemaCache) { return ResourceCache(resources); }; +OKCMS.prototype._resolveForeignKeys = function(resourceCache) { + resourceCache.forEach(function(resource) { + Object.keys(resource.foreignKeys).forEach(function(field) { + var foreignKeyType = resource.foreignKeys[field] + var keyedResource = resourceCache.get(foreignKeyType) + if (!keyedResource) { + throw new Error(format( + "Foreign key field '%s' in '%s' resource references unknown" + + "resource of type '%s'", field, resource.type, foreignKeyType)) + } + resource._linkForeignKey(field, resourceCache.get(foreignKeyType)) + }) + }) +} + OKCMS.prototype._createViews = function(viewConfig, db, meta, resourceCache, templateProvider, errorHandler) { viewConfig = viewConfig || {}; @@ -279,6 +295,13 @@ ResourceCache.prototype.get = function(type, id) { } }; +ResourceCache.prototype.forEach = function(cb) { + cb = cb || function() {} + Object.keys(this._cache).forEach(function(key) { + cb(this._cache[key]) + }.bind(this)) +} + /** * Higher order function implementing customizable error handling */ diff --git a/app/node_modules/okadminview/index.js b/app/node_modules/okadminview/index.js index 273d541..06656dc 100644 --- a/app/node_modules/okadminview/index.js +++ b/app/node_modules/okadminview/index.js @@ -154,11 +154,12 @@ function OKAdminView(options) { if (!resource) { error(req, res, 404)(new Error('No such resource ' + type)); } else { - var templateData = transformData(meta, resource, {}); - view.renderResourceNew(req, res, assign(templateData, { - success: req.flash('success'), - errors: req.flash('errors'), - })); + fetchNewTemplateData(meta, resource, transformData).then(function(data) { + view.renderResourceNew(req, res, assign(data, { + success: req.flash('success'), + errors: req.flash('errors'), + })) + }).fail(error(req, res, 500)) } }); @@ -280,11 +281,11 @@ function OKAdminView(options) { /** * Yields formatted template data for a single resource */ -function transformData(meta, resource, data) { +function transformData(meta, spec, resource, data) { meta = meta || {}; resource = resource || {}; data = data || {}; - var spec = Object.keys(resource.spec).reduce(function(cache, prop) { + var spec = Object.keys(spec).reduce(function(cache, prop) { var value = data[prop]; var propSpec = cache[prop]; // Decorate spec with actual resource values @@ -294,7 +295,7 @@ function transformData(meta, resource, data) { propSpec.hidden = true; } return cache; - }, resource.spec); + }, spec); return { meta: meta, resource: { @@ -340,47 +341,94 @@ function fetchIndexTemplateData(meta, queries, dashboardConfig) { Q.all(queries.map(function(query) { return query.get(); })).then(function(results) { - var resources = results.reduce(function(cache, result, i) { - if (!result) - return cache; + var templateData = results.reduce(function(acc, result, i) { var resource = queries[i].resource; // We want the raw object spec var spec = resource.spec; var dashConf = resourceConfig[resource.type] || {} var groupBy = dashConf.groupBy var key = pluralize(resource.type) - cache[key] = { + acc[key] = { type: resource.type, spec: spec, data: result, groupBy: groupBy } - return cache; - }, {}); - + return acc + }, {}) resolve({ meta: meta, - resources: resources - }); - }).fail(reject); + resources: templateData + }) + }).fail(reject) }); } +function fetchNewTemplateData(meta, resource, transformFn) { + return Q.promise(function(resolve, reject) { + if (!resource.hasForeignKey) { + done({spec: resource.spec, resource: resource}) + } else { + fetchForeignKeyOptions(resource).then(done).fail(reject) + } + + function done(results) { + resolve(transformFn(meta, results.spec, results.resource, {})) + } + }) +} + /** * Annotate template data with schema info */ -function fetchResourceTemplateData(meta, query, fn) { - fn = fn || function(m, r, d) { return {meta: m, resource: d}; }; +function fetchResourceTemplateData(meta, query, transformFn) { return Q.promise(function(resolve, reject) { query.get().then(function(data) { - if (!data) { - reject(new Error('No resource data')); + if (!data) + return reject(new Error('No resource data')) + + var resource = query.resource + + if (resource.hasForeignKey) { + fetchForeignKeyOptions(resource).then(done).fail(reject) } else { - var resource = query.resource; - resolve(fn(meta, resource, data)); + done({spec: resource.spec, resource: resource}) } - }).fail(reject); - }); + + function done(results) { + resolve(transformFn(meta, results.spec, results.resource, data)) + } + }).fail(reject) + }) +} + +function fetchForeignKeyOptions(resource) { + var promises = Object.keys(resource.foreignKeys) + .map(fetchOptionsForKey) + var spec = resource.spec + + return Q.all(promises).then(done) + + function done() { + return Q.promise(function(resolve, reject) { + resolve({spec: spec, resource: resource}) + }) + } + + function fetchOptionsForKey(field) { + var relatedResourceType = resource.foreignKeys[field] + return resource.related(relatedResourceType).then(fillOptions) + + function fillOptions(results) { + return Q.promise(function(resolve, reject) { + spec[field].options = results.map(function(result) { + return result.id + }) + resolve() + }) + } + } } + module.exports = OKAdminView; diff --git a/app/node_modules/okquery/index.js b/app/node_modules/okquery/index.js index 09d867d..d4cb905 100644 --- a/app/node_modules/okquery/index.js +++ b/app/node_modules/okquery/index.js @@ -23,6 +23,7 @@ function OKQuery(options) { // Queries are ordered by index by default var sortField = options.sortBy || '__index'; + // TODO Make descending by default var descending = options.descending || false; Object.defineProperty(this, 'resource', { diff --git a/app/node_modules/okresource/index.js b/app/node_modules/okresource/index.js index c3f9adb..c1f2509 100644 --- a/app/node_modules/okresource/index.js +++ b/app/node_modules/okresource/index.js @@ -1,3 +1,4 @@ +var format = require('util').format var assign = require('object-assign'); var cloneDeep = require('lodash.clonedeep'); var Q = require('q'); @@ -22,10 +23,36 @@ function OKResource(options) { var spec = schema.spec; var type = options.type; + var hasForeignKey = false this._db = options.db; this._schema = schema; + var foreignKeys = Object.keys(spec).reduce(function(acc, field) { + var fieldSpec = spec[field] + if (fieldSpec.type === 'foreign-key') { + hasForeignKey = true + acc[field] = fieldSpec.key + } + return acc + }, {}) + + // Will store references to other resources referenced via foreign keys + this._foreignKeyedResources = {} + // Define properties which are part of the API + + // Should be treated as read-only + Object.defineProperty(this, 'foreignKeys', { + get: function() { + return foreignKeys + } + }) + + Object.defineProperty(this, 'hasForeignKey', { + get: function() { + return hasForeignKey + } + }) Object.defineProperty(this, 'spec', { get: function() { @@ -49,6 +76,30 @@ function OKResource(options) { }); } +OKResource.prototype._linkForeignKey = function(field, resource) { + this._foreignKeyedResources[field] = resource +} + +/** + * Fetch all related resources for the given field + */ +OKResource.prototype.related = function(field) { + var resource = this._foreignKeyedResources[field] + return Q.promise(function(resolve, reject) { + if (!resource) { + return error(reject, new Error(format( + "No related resource for field '%s'", field))) + } + resource.all().then(resolve).fail(reject) + }) + + function error(reject, err) { + setTimeout(function() { + reject(err) + }, 0) + } +} + /** * Throws an error if data does not conform to schema */ @@ -180,6 +231,9 @@ OKResource.prototype.instance = function(options) { }); }; +/** + * TODO This class is such bullshit. Refactor out + */ function OKResourceInstance(resource, options) { if (!(this instanceof OKResourceInstance)) return new OKResourceInstance(options); // Only support static data instances for now @@ -279,6 +333,18 @@ function OKResourceInstance(resource, options) { resource.assertValid(data); }; + Object.defineProperty(this, 'foreignKeys', { + get: function() { + return [] + } + }) + + Object.defineProperty(this, 'hasForeignKey', { + get: function() { + return false + } + }) + Object.defineProperty(this, 'parent', { value: resource, writable: false, diff --git a/app/node_modules/okschema/index.js b/app/node_modules/okschema/index.js index 89b59cc..330ad6b 100644 --- a/app/node_modules/okschema/index.js +++ b/app/node_modules/okschema/index.js @@ -73,6 +73,10 @@ var types = { 'flag': { parent: 'string', assertValid: function(spec, value) {} + }, + 'foreign-key': { + parent: 'enum', + assertValid: function(spec, value) {} } } diff --git a/themes/okadmin/templates/partials/inputs.liquid b/themes/okadmin/templates/partials/inputs.liquid index 9c1a26b..c6efc68 100644 --- a/themes/okadmin/templates/partials/inputs.liquid +++ b/themes/okadmin/templates/partials/inputs.liquid @@ -17,7 +17,7 @@ - {% elsif type == 'enum' %} + {% elsif type == 'enum' or type == 'foreign-key' %} - + {% for link in spec.value %} +
    3. + + + +
    4. {% endfor %}
+ + + +
{% elsif type == 'media-list' %} -- cgit v1.2.3-70-g09d2 From 49fe25c8e884c14ab3258d22240a62f0b57da490 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 28 Mar 2016 16:15:46 -0400 Subject: make links sortable --- examples/db.json | 33 ++++++++++++------------- themes/okadmin/public/css/main.css | 9 ++++++- themes/okadmin/public/js/app.js | 19 ++++++++++---- themes/okadmin/templates/partials/inputs.liquid | 19 ++++++++------ 4 files changed, 49 insertions(+), 31 deletions(-) (limited to 'themes/okadmin/templates') diff --git a/examples/db.json b/examples/db.json index 5e10d60..9ab7233 100644 --- a/examples/db.json +++ b/examples/db.json @@ -92,22 +92,6 @@ }, "__index": 3, "id": "croissant" - }, - { - "type": "Test", - "title": "Testing", - "description": "", - "color": "red", - "video": { - "url": "", - "type": "", - "token": "", - "title": "", - "thumb": "" - }, - "__index": "5", - "dateCreated": "Mon, 28 Mar 2016 18:49:32 GMT", - "images": [] } ], "page": [ @@ -123,7 +107,22 @@ "title": "ok...", "body": "2406 Old Rd, San Juan Bautista", "id": "contact", - "__index": 0 + "__index": "0", + "links": [ + { + "text": "US Bread Board", + "uri": "http://bread.com/" + }, + { + "text": "National Council on Grain", + "uri": "http://grain.org/" + }, + { + "text": "USDA", + "uri": "http://usda.gov/" + } + ], + "dateCreated": "" } ] } \ No newline at end of file diff --git a/themes/okadmin/public/css/main.css b/themes/okadmin/public/css/main.css index 9289fdf..df0ca43 100644 --- a/themes/okadmin/public/css/main.css +++ b/themes/okadmin/public/css/main.css @@ -310,8 +310,15 @@ button, input[type=submit] { width: 13.05em; padding: 0 0 0 0.5em; } +.handle { + display: block; + width: 1em; + height: 2em; + background: #ddd; + float: left; +} .main.resource form .links li { - height: auto; + height: 2em; } .main .link-list .add-link-btn, .main .link-list .remove-link-btn { diff --git a/themes/okadmin/public/js/app.js b/themes/okadmin/public/js/app.js index 17b35d0..da398eb 100644 --- a/themes/okadmin/public/js/app.js +++ b/themes/okadmin/public/js/app.js @@ -91,7 +91,7 @@ var OKAdmin = function(){ }) // make the region sortable with drag-and-drop - $(".media-list ol, .image-list ol").sortable() + $(".media-list ol, .image-list ol, .link-list .links").sortable() $(".media-list ol, .image-list ol").disableSelection() // populate a video field with info from our url parser @@ -115,20 +115,22 @@ var OKAdmin = function(){ })) // Add a new link to the list - $('.link-list').on('click', '.add-link-btn', function(e) { - e.preventDefault() - e.stopPropagation() + $('.link-list').on('click', '.add-link-btn', function addNewLink (e) { + e.preventDefault && e.preventDefault() + e.stopPropagation && e.stopPropagation() var $delegate = $(e.delegateTarget) var $list = $delegate.find('.links') + var linkCount = $list.find("li").length + var $linkText = $delegate.find(".link-input-new.link-text") var $linkURI = $delegate.find(".link-input-new.link-uri") var template = $delegate.find(".link-template").html() + template = template.replace(/\[\]/g, "[" + linkCount + "]") var $el = $(template) $el.find(".link-text").val( $linkText.val() ) $el.find(".link-uri").val( $linkURI.val() ) $list.append($el) - console.log($list, template) $linkText.val("") $linkURI.val("") }) @@ -195,6 +197,13 @@ var OKAdmin = function(){ input.checked = true } }) + + $(".link-list").each(function(){ + var $inputs = $(this).find(".link-input-new") + if ($inputs.eq(0).val() && $inputs.eq(1).val()) { + $(this).find(".add-link-btn").trigger("click") + } + }) $("ol").each(function(){ $("li", this).each(function(index){ diff --git a/themes/okadmin/templates/partials/inputs.liquid b/themes/okadmin/templates/partials/inputs.liquid index 55d5fb8..4acb435 100644 --- a/themes/okadmin/templates/partials/inputs.liquid +++ b/themes/okadmin/templates/partials/inputs.liquid @@ -82,17 +82,18 @@ {% elsif type == 'link-list' %}