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 --- themes/okadmin/templates/partials/head.liquid | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'themes/okadmin/templates/partials') 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 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/partials') 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/partials') 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' %}
- + Add images +
- - - - + + + + -- 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/partials') 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/partials') 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' %} - - + +
+ {% 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/partials') 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' %}
- +
@@ -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/partials') 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/partials') 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/partials') 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/partials') 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/partials') 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/partials') 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/partials') 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/partials') 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: 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/partials') 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 %} +
  • + + + +
  • {% 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/partials') 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' %}