diff --git a/config/demo-staging.json b/config/demo-staging.json index 6853960a..0ee26330 100644 --- a/config/demo-staging.json +++ b/config/demo-staging.json @@ -1,6 +1,6 @@ { "useStrict" : "use strict", - "apiUrl" : "http://api.demo.staging.ottemo.io", - "mediaPath" : "http://demo.staging.ottemo.io/media/", + "apiUrl" : "https://api.demo.staging.ottemo.io", + "mediaPath" : "https://demo.staging.ottemo.io/media/", "itemsPerPage" : "15" } \ No newline at end of file diff --git a/config/dev.json b/config/dev.json index dbec0791..bea8df88 100644 --- a/config/dev.json +++ b/config/dev.json @@ -1,6 +1,6 @@ { "useStrict" : "use strict", - "apiUrl" : "http://api.dev.ottemo.io", - "mediaPath" : "http://dev.ottemo.io/media/", + "apiUrl" : "https://api.dev.ottemo.io", + "mediaPath" : "https://dev.ottemo.io/media/", "itemsPerPage" : "15" } \ No newline at end of file diff --git a/config/kg-staging.json b/config/kg-staging.json index 9f683d98..7032393b 100644 --- a/config/kg-staging.json +++ b/config/kg-staging.json @@ -1,6 +1,6 @@ { "useStrict" : "use strict", - "apiUrl" : "http://api.kg.staging.ottemo.io", - "mediaPath" : "http://kg.staging.ottemo.io/media/", + "apiUrl" : "https://api.kg.staging.ottemo.io", + "mediaPath" : "https://kg.staging.ottemo.io/media/", "itemsPerPage" : "15" } diff --git a/config/mp-staging.json b/config/mp-staging.json index 28418235..de9169bd 100644 --- a/config/mp-staging.json +++ b/config/mp-staging.json @@ -1,6 +1,6 @@ { "useStrict" : "use strict", - "apiUrl" : "http://api.mp.staging.ottemo.io", - "mediaPath" : "http://mp.staging.ottemo.io/media/", + "apiUrl" : "https://api.mp.staging.ottemo.io", + "mediaPath" : "https://mp.staging.ottemo.io/media/", "itemsPerPage" : "15" -} \ No newline at end of file +} diff --git a/config/rk-staging.json b/config/rk-staging.json index 66113338..e1f41d4b 100644 --- a/config/rk-staging.json +++ b/config/rk-staging.json @@ -1,7 +1,7 @@ { "useStrict" : "use strict", - "apiUrl" : "http://api.rk.staging.ottemo.io", - "mediaPath" : "http://rk.staging.ottemo.io/media/", + "apiUrl" : "https://api.rk.staging.ottemo.io", + "mediaPath" : "https://rk.staging.ottemo.io/media/", "itemsPerPage" : "15" } diff --git a/config/sb-prod.json b/config/sb-prod.json new file mode 100644 index 00000000..abb3d13b --- /dev/null +++ b/config/sb-prod.json @@ -0,0 +1,6 @@ +{ + "useStrict" : "use strict", + "apiUrl" : "https://api.mystembox.com", + "mediaPath" : "https://mystembox.com/media/", + "itemsPerPage" : "15" +} \ No newline at end of file diff --git a/config/sb-staging.json b/config/sb-staging.json new file mode 100644 index 00000000..a126c26d --- /dev/null +++ b/config/sb-staging.json @@ -0,0 +1,6 @@ +{ + "useStrict" : "use strict", + "apiUrl" : "https://api.sb.staging.ottemo.io", + "mediaPath" : "https://sb.staging.ottemo.io/media/", + "itemsPerPage" : "15" +} \ No newline at end of file diff --git a/config/scs-prod.json b/config/scs-prod.json new file mode 100644 index 00000000..886eb592 --- /dev/null +++ b/config/scs-prod.json @@ -0,0 +1,6 @@ +{ + "useStrict" : "use strict", + "apiUrl" : "https://api.southcoastswords.com", + "mediaPath" : "https://southcoastswords.com/media/", + "itemsPerPage" : "15" +} \ No newline at end of file diff --git a/config/scs-staging.json b/config/scs-staging.json new file mode 100644 index 00000000..8860294c --- /dev/null +++ b/config/scs-staging.json @@ -0,0 +1,6 @@ +{ + "useStrict" : "use strict", + "apiUrl" : "https://api.scs.staging.ottemo.io", + "mediaPath" : "https://scs.staging.ottemo.io/media/", + "itemsPerPage" : "15" +} \ No newline at end of file diff --git a/deploy.sh b/deploy.sh index 5038cdd0..1e460135 100644 --- a/deploy.sh +++ b/deploy.sh @@ -23,7 +23,11 @@ if [ "$BRANCH" == 'develop' ]; then elif [ "$REMOTE_HOST" == 'demo.staging.ottemo.io' ]; then HOST=demo-staging elif [ "$REMOTE_HOST" == 'mp.staging.ottemo.io' ]; then - HOST=mp-staging + HOST=mp-staging + elif [ "$REMOTE_HOST" == 'sb.staging.ottemo.io' ]; then + HOST=sb-staging + elif [ "$REMOTE_HOST" == 'scs.staging.ottemo.io' ]; then + HOST=scs-staging fi # gulp build on remote host ssh ottemo@$REMOTE_HOST "cd $SRCDIR && npm install && gulp build --env=staging --config=${HOST}" diff --git a/package.json b/package.json index 02005906..9eb4e81e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Dashboard", - "version": "1.1.16", + "version": "1.1.22", "description": "Ottemo Administration Tool", "main": "gulpfile.js", "repository": { diff --git a/shippable.yml b/shippable.yml index a54f28fc..6e46c45b 100644 --- a/shippable.yml +++ b/shippable.yml @@ -25,6 +25,8 @@ after_success: - REMOTE_HOST=rk.staging.ottemo.io bash deploy.sh - REMOTE_HOST=demo.staging.ottemo.io bash deploy.sh - REMOTE_HOST=mp.staging.ottemo.io bash deploy.sh + - REMOTE_HOST=sb.staging.ottemo.io bash deploy.sh + - REMOTE_HOST=scs.staging.ottemo.io bash deploy.sh - python slack_notifier.py --org $SLACK_ORG --project $PROJECT --token $SLACK_TOKEN -s notifications: diff --git a/src/app/_styles/bootstrap/_variables.scss b/src/app/_styles/bootstrap/_variables.scss index 86322bc5..fc2f5162 100755 --- a/src/app/_styles/bootstrap/_variables.scss +++ b/src/app/_styles/bootstrap/_variables.scss @@ -353,7 +353,7 @@ $container-lg: $container-large-desktop !default; //## // Basics of a navbar -$navbar-height: 60px !default; +$navbar-height: 47px !default; $navbar-margin-bottom: $line-height-computed !default; $navbar-border-radius: $border-radius-base !default; $navbar-padding-horizontal: floor(($grid-gutter-width / 2)) !default; diff --git a/src/app/_styles/components/navigation.scss b/src/app/_styles/components/navigation.scss index 5553ffae..e99b4d9f 100644 --- a/src/app/_styles/components/navigation.scss +++ b/src/app/_styles/components/navigation.scss @@ -23,24 +23,30 @@ body { width: 100%; } +// xs navbar +.navbar-default .navbar-nav { + float: right; + margin: 4px -15px; + @media (min-width: $screen-sm-min) { + margin: 0; + } +} .navbar-brand { font-size: 22px; > img { display: inline-block; - height: 20px; - vertical-align: top; - position: relative; - top: -2px; - margin-right: 10px; + margin: -2px 2px 0 0; + width: 21px; } } +// real menu, in sidebar .nav-menu { position: fixed; right: -$nav-width; top: 0; - + z-index: 1001; width: $nav-width; height: 100%; @@ -62,7 +68,6 @@ body { } &.nav-menu--active { - z-index: 20; right:0; -webkit-transition: all 0.4s ease; transition: all 0.4s ease; @@ -73,16 +78,6 @@ body { left:0; right: auto; } - - @media (min-width: $nav-break) and (min-height: 570px) { - .navbar-user { - position: absolute; - bottom: 0; - width: 100%; - border-bottom: 0; - border-top: 1px #343438 solid; - } - } } .nav-menu { @@ -91,7 +86,7 @@ body { padding: 0; } - a { + .menu-link { display: block; line-height: 1; font-size: 16px; @@ -101,32 +96,14 @@ body { padding: 15px 0px 15px 15px; border-bottom: 1px #343438 solid; position: relative; - transition: all 0.4s ease; &:hover { background: $navbar-default-link-hover-bg; color: $navbar-default-link-hover-color; - transition: all 0.4s ease; } &.active { background: $navbar-default-link-active-bg; color: $navbar-default-link-active-color; - transition: all 0.4s ease; - } - } - - - .navbar-branding { - height: 59px; - line-height: 59px; - padding: 1px 0 0 15px; - font-size: 22px; - color: #fff; - - img { - width: 20px; - margin-right: 10px; - vertical-align: baseline; } } @@ -139,6 +116,49 @@ body { right: 0; } } +.menu-item__user { + .fa { + margin-top: -5px; + margin-right: 2px; + } + .branding { + font-size: 22px; + color: #fff; + } + .fa-angle-down { + font-size: 14px; + margin-left: 3px; + color: #98978B; + } + .user-name { + margin-top: 5px; + font-size: 14px; + } +} +.user-menu-dropdown { + z-index: 1002; + margin-left: 12px; + margin-top: -10px; + border-color: #343438; + overflow: hidden; // prevent :hover bg from ruining border-radius + width: 250px; + + .menu-header { + padding: 3px 20px; + img { + float: left; + margin: 0 12px 0 0; + } + div { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + } + .divider { + margin: 3px 0; + } +} .nav-menu { .sub-menu { @@ -147,16 +167,11 @@ body { overflow: hidden; transition: max-height .5s; - a { + .menu-link { padding-left: 55px; } } - .open { - a { - background: $navbar-default-link-active-bg; - } - .sub-menu { - max-height: 400px; - } + .open .sub-menu { + max-height: 400px; // 8 submenu items, hopefully pretty safe } -} \ No newline at end of file +} diff --git a/src/app/_styles/components/tables.scss b/src/app/_styles/components/tables.scss index 0267d516..4afb6966 100644 --- a/src/app/_styles/components/tables.scss +++ b/src/app/_styles/components/tables.scss @@ -11,3 +11,25 @@ .th-clickable { cursor: pointer; } + +// Shadow hinting for responsive tables +// https://github.com/iKristjan/bootstrap-responsive-table-scrolling-shadows/blob/master/bootstrap-responsive-table-scrolling-shadows.css +.table-responsive { + background: + radial-gradient(farthest-side at 0% 50%, rgba(0,0,0,.2), rgba(0,0,0,0)), + radial-gradient(farthest-side at 100% 50%, rgba(0,0,0,.2), rgba(0,0,0,0)) 100% 0; + background-color: white; + background-repeat: no-repeat; + background-size: 10px 100%; + margin-bottom: 15px; +} + +.table-responsive > .table { + background: + linear-gradient(to right, white 30%, rgba(255,255,255,0)), + linear-gradient(to left, white 30%, rgba(255,255,255,0)) 100% 0; + background-size: 50px 100%; + background-repeat: no-repeat; + max-width: none; + margin-bottom: 0; +} \ No newline at end of file diff --git a/src/app/config/directives/ot-config-editor-form.directive.js b/src/app/config/directives/ot-config-editor-form.directive.js index ef32564a..15562793 100644 --- a/src/app/config/directives/ot-config-editor-form.directive.js +++ b/src/app/config/directives/ot-config-editor-form.directive.js @@ -1,94 +1,83 @@ -angular.module("coreModule") +angular.module('coreModule') -/** -* Directive used for automatic attributes editor form creation -*/ -.directive("otConfigEditorForm", [function () { +.directive('otConfigEditorForm', [function () { return { - restrict: "E", + restrict: 'E', scope: { - "parent": "=object", - "item": "=item", - "attributes": "=attributesList" + 'parent': '=object', + 'item': '=item', + 'attributes': '=attributesList' }, - templateUrl: "/views/config/directives/ot-config-editor-form.html", - controller: function ($scope) { - var updateAttributes, addTab, addFields, sortFieldsInGroups; + templateUrl: '/views/config/directives/ot-config-editor-form.html', + controller: function ($scope, _) { - $scope.tabs = {}; - $scope.click = function (id) { - if (typeof $scope.parent.selectTab === "function") { - $scope.parent.selectTab(id); - } else { - return false; - } - }; + $scope.tabs = []; + $scope.attributeGroups = {}; + $scope.click = click; - addTab = function (attr) { - if (attr.Type === "group") { - if (typeof $scope.tabs[attr.Group] === "undefined") { - $scope.tabs[attr.Group] = []; - } - $scope.tabs[attr.Group].push(attr); - } - }; + activate(); - addFields = function (attr) { - if (typeof $scope.attributeGroups[attr.Group] === "undefined") { - $scope.attributeGroups[attr.Group] = []; - } - $scope.attributeGroups[attr.Group].push(attr); - }; + /////////////////////// - sortFieldsInGroups = function () { - // var sortByLabel, tab; - // sortByLabel = function (a, b) { - // if (a.Label.toString() < b.Label.toString()) { - // return -1; - // } - // if (a.Label.toString() > b.Label.toString()) { - // return 1; - // } + function activate() { + $scope.$watchCollection('attributes', updateAttributes); + $scope.$watchCollection('item', updateAttributes); + } - // return 0; - // }; - // for (tab in $scope.attributeGroups) { - // if ($scope.attributeGroups.hasOwnProperty(tab)) { - // $scope.attributeGroups[tab].sort(sortByLabel); - // } - // } - }; + function click(id) { + if (typeof $scope.parent.selectTab === 'function') { + $scope.parent.selectTab(id); + } else { + return false; + } + } - updateAttributes = function () { - if ($scope.item === "undefined" || + function updateAttributes() { + if ($scope.item === 'undefined' || JSON.stringify({}) === JSON.stringify($scope.item)) { return true; } - var i, attr, setAttrValue; - $scope.attributeGroups = {}; - setAttrValue = function (attr) { - if (typeof $scope.item !== "undefined") { - attr.Value = $scope.item[attr.Attribute] || ""; + $scope.attributeGroups = {}; + if (typeof $scope.attributes !== 'undefined') { + for (var i = 0; i < $scope.attributes.length; i += 1) { + var attr = setAttrValue($scope.attributes[i]); + addFields(attr); } - return attr; - }; - - if (typeof $scope.attributes !== "undefined") { - for (i = 0; i < $scope.attributes.length; i += 1) { - attr = setAttrValue($scope.attributes[i]); + // only write tabs out once + if ($scope.tabs.length === 0) { + $scope.attributes.forEach(function(a){ + if (a.Type === 'group') { + addTab(a.Label, a.Group); + } + }); - addFields(attr); - addTab(attr); + // activate the first tab + $scope.click($scope.tabs[0].key); } } + } - sortFieldsInGroups(); - }; + function addTab(label, key) { + $scope.tabs.push({label:label, key:key}); + $scope.tabs = _.sortBy($scope.tabs, 'label'); + } + + function addFields(attr) { + if (typeof $scope.attributeGroups[attr.Group] === 'undefined') { + $scope.attributeGroups[attr.Group] = []; + } + $scope.attributeGroups[attr.Group].push(attr); + } + + function setAttrValue(attr) { + if (typeof $scope.item !== 'undefined') { + attr.Value = $scope.item[attr.Attribute] || ''; + } - $scope.$watchCollection("attributes", updateAttributes); - $scope.$watchCollection("item", updateAttributes); + return attr; + } } }; }]); diff --git a/src/app/config/directives/ot-config-editor-form.html b/src/app/config/directives/ot-config-editor-form.html index 9f371602..cafd2e5f 100644 --- a/src/app/config/directives/ot-config-editor-form.html +++ b/src/app/config/directives/ot-config-editor-form.html @@ -1,26 +1,47 @@ -
+ -
- -
+
+ -
+
+ +
+
+ + +
+ + +
+
-
-
- -
-
-
-
-
Save
- diff --git a/src/app/core/directives/editor/ot-multiline-text.html b/src/app/core/directives/editor/ot-multiline-text.html index 880f933d..8136f15e 100644 --- a/src/app/core/directives/editor/ot-multiline-text.html +++ b/src/app/core/directives/editor/ot-multiline-text.html @@ -1,4 +1,4 @@ + ng-model="item[attribute.Attribute]" ot-prettify> diff --git a/src/app/core/directives/editor/ot-product-selector.directive.js b/src/app/core/directives/editor/ot-product-selector.directive.js index a492b519..c035dfb7 100644 --- a/src/app/core/directives/editor/ot-product-selector.directive.js +++ b/src/app/core/directives/editor/ot-product-selector.directive.js @@ -16,7 +16,7 @@ function ($location, $routeParams, DashboardListService, productApiService, core 'name' : {'type' : 'select-link', 'label' : 'Name'}, 'enabled' : {}, 'sku' : {}, - 'price' : {} + 'price' : {'type': 'price', 'label': 'Price'} }; return { @@ -80,14 +80,7 @@ function ($location, $routeParams, DashboardListService, productApiService, core }; loadData = function () { - $scope.fields = [ - { - "attribute": "Image", - "type": "image", - "label": "", - "visible": true - } - ]; + $scope.fields = []; if (typeof $scope.search === "undefined") { $scope.search = {}; $scope.search.limit = "0," + COUNT_ITEMS_PER_PAGE; @@ -141,7 +134,12 @@ function ($location, $routeParams, DashboardListService, productApiService, core serviceList.init('products'); $scope.attributes = result; serviceList.setAttributes($scope.attributes); - $scope.fields = $scope.fields.concat(serviceList.getFields(showColumns)); + + $scope.fields = $scope.fields.concat(serviceList.getFields(showColumns)) + .filter(function(obj){ + return ['name', 'enabled', 'sku', 'price'].indexOf(obj.attribute) >= 0 + }); + getProductsList(); }); }; diff --git a/src/app/core/directives/editor/ot-product-selector.html b/src/app/core/directives/editor/ot-product-selector.html index 449a22a8..b7feb6df 100644 --- a/src/app/core/directives/editor/ot-product-selector.html +++ b/src/app/core/directives/editor/ot-product-selector.html @@ -9,7 +9,7 @@
diff --git a/src/app/core/directives/ot-attributes-editor-form-tabs.html b/src/app/core/directives/ot-attributes-editor-form-tabs.html index 802c49d6..b1db2cb4 100644 --- a/src/app/core/directives/ot-attributes-editor-form-tabs.html +++ b/src/app/core/directives/ot-attributes-editor-form-tabs.html @@ -14,7 +14,7 @@ -
+
diff --git a/src/app/core/directives/ot-form-builder.html b/src/app/core/directives/ot-form-builder.html index dd59c01f..2412d2ed 100644 --- a/src/app/core/directives/ot-form-builder.html +++ b/src/app/core/directives/ot-form-builder.html @@ -252,8 +252,15 @@ ng-class="{ 'has-error' : (parent.form.submitted && parent.form.{{attribute.Attribute}}.$invalid) || (parent.form.{{attribute.Attribute}}.$invalid && !parent.form.{{attribute.Attribute}}.$pristine) }"> - +

-

  • +
  • {{item[map.name]}} @@ -52,7 +52,7 @@

    + ng-repeat="item in items | filter:searchText track by item.ID"> {{item[map.name]}}
    diff --git a/src/app/core/directives/ot-table-manager-popup.directive.js b/src/app/core/directives/ot-table-manager-popup.directive.js index cdd3bd7b..0382b1d2 100644 --- a/src/app/core/directives/ot-table-manager-popup.directive.js +++ b/src/app/core/directives/ot-table-manager-popup.directive.js @@ -100,7 +100,7 @@ angular.module("coreModule") possibleButtons = ["new", "delete", "checkbox"]; if (typeof $scope.buttons === "undefined") { $scope.buttons = {}; - for (i = 0; i < possibleButtons.length; i += 1) { + for (i = 0; i < possibleButtons.length; i++) { if (typeof $scope.buttonData !== "undefined") { if (typeof $scope.buttonData[possibleButtons[i]] !== "undefined") { $scope.buttons[possibleButtons[i]] = $scope.buttonData[possibleButtons[i]]; @@ -123,7 +123,7 @@ angular.module("coreModule") } catch (e) { var parts = opt.replace(/[{}]/g, "").split(","); - for (var i = 0; i < parts.length; i += 1) { + for (var i = 0; i < parts.length; i++) { options[parts[i]] = parts[i]; } } @@ -172,7 +172,8 @@ angular.module("coreModule") return details; }; - for (i = 0; i < $scope.parent.fields.length; i += 1) { + + for (i = 0; i < $scope.parent.fields.length; i++) { if (typeof $scope.parent.fields[i].filter === "undefined") { $scope.filters.push({}); @@ -295,7 +296,7 @@ angular.module("coreModule") search = {}; removeEmpty = function (arr) { - for (var i = 0; i < arr.length; i += 1) { + for (var i = 0; i < arr.length; i++) { if ("" === arr[i].trim()) { arr.splice(i, 1); } @@ -344,7 +345,7 @@ angular.module("coreModule") $scope.selectAll = function () { isSelectedAll = isSelectedAll ? false : true; - for (var i = 0; i < $scope.items.length; i += 1) { + for (var i = 0; i < $scope.items.length; i++) { $scope.parent.selected[$scope.items[i][$scope.map.id]] = isSelectedAll; } }; @@ -377,7 +378,7 @@ angular.module("coreModule") } }; - for (i = 0; i < $scope.items.length; i += 1) { + for (i = 0; i < $scope.items.length; i++) { item = $scope.items[i]; if (item.Extra !== null) { splitExtraData(item); diff --git a/src/app/core/directives/ot-table-manager-popup.html b/src/app/core/directives/ot-table-manager-popup.html index 5333d465..e37bc5d2 100644 --- a/src/app/core/directives/ot-table-manager-popup.html +++ b/src/app/core/directives/ot-table-manager-popup.html @@ -15,7 +15,7 @@

  • - +
    @@ -38,10 +38,6 @@ -
    - -
    -
    @@ -63,14 +59,8 @@ + + + + +
    - - - {{item[map.name]}} - - - {{_item[field.attribute] | currency}} +
    {{_item[field.attribute] | currency}}
    {{_item[field.attribute] | currency}} diff --git a/src/app/core/directives/ot-table-manager.html b/src/app/core/directives/ot-table-manager.html index 42753037..af0effd4 100644 --- a/src/app/core/directives/ot-table-manager.html +++ b/src/app/core/directives/ot-table-manager.html @@ -41,26 +41,32 @@
    - +
    + - - + - diff --git a/src/app/dashboard/css-test.html b/src/app/dashboard/css-test.html new file mode 100644 index 00000000..4ead6496 --- /dev/null +++ b/src/app/dashboard/css-test.html @@ -0,0 +1,1167 @@ +
    +
    + + + + + +
    +
    +
    + + +
    + +
    + +
    + +
    + +
    +
    +
    + + + + + + +
    +
    +
    + +
    +
    + + + +
    +
    +
    +

    Heading 1

    +

    Heading 2

    +

    Heading 3

    +

    Heading 4

    +
    Heading 5
    +
    Heading 6
    +

    Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.

    +
    +
    +
    +
    +

    Example body text

    +

    Nullam quis risus eget urna mollis ornare vel eu leo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nullam id dolor id nibh ultricies vehicula.

    +

    This line of text is meant to be treated as fine print.

    +

    The following snippet of text is rendered as bold text.

    +

    The following snippet of text is rendered as italicized text.

    +

    An abbreviation of the word attribute is attr.

    +
    + +
    +
    +
    +

    Emphasis classes

    +

    + .text-muted
    + Fusce dapibus, tellus ac cursus commodo, tortor mauris nibh. +

    +

    + .text-primary
    + Nullam id dolor id nibh ultricies vehicula ut id elit. +

    +

    + .text-warning
    + Etiam porta sem malesuada magna mollis euismod. +

    +

    + .text-danger
    + Donec ullamcorper nulla non metus auctor fringilla. +

    +

    + .text-success
    + Duis mollis, est non commodo luctus, nisi erat porttitor ligula. +

    +

    + .text-info
    + Maecenas sed diam eget risus varius blandit sit amet non magna. +

    +
    + +
    +
    + + + +
    +
    +

    Blockquotes

    +
    +
    +
    +
    +
    +
    +

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.

    + Someone famous in Source Title +
    +
    +
    +
    +
    +
    +

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.

    + Someone famous in Source Title +
    +
    +
    +
    +
    + + +
    + +
    +
    + + +
    +
    - {{field.label}} + {{::field.label}}
      +
    @@ -84,39 +90,42 @@
    - + - + + - + - {{_item[field.attribute] | currency}} - {{_item[field.attribute] | currency}} + {{::_item[field.attribute] | currency}} + {{::_item[field.attribute] | currency}} + date="::_item[field.attribute]"> -
    {{_item[field.attribute]}}
    +
    {{::_item[field.attribute]}}
    - {{_item[field.attribute]}} + {{::_item[field.attribute]}}
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #Column headingColumn headingColumn heading
    1Column contentColumn contentColumn content
    2Column contentColumn contentColumn content
    3Column contentColumn contentColumn content
    4Column contentColumn contentColumn content
    5Column contentColumn contentColumn content
    6Column contentColumn contentColumn content
    7Column contentColumn contentColumn content
    +
    + + + + + +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    + Legend: form using rows & cols +
    + +
    + +
    +
    +
    + +
    + + A longer block of help text that breaks onto a new line and may extend beyond one line. +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    + +
    + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    + +
    +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + +
    + $ + + + + +
    +
    +
    + +
    +
    +
    + + +
    + +
    +
    + +
    +
    + +
    +
    + +
    + +
    +
    +

    Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth. Cosby sweater eu banh mi, qui irure terry richardson ex squid. Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui.

    +
    +
    +

    Food truck fixie locavore, accusamus mcsweeney's marfa nulla single-origin coffee squid. Exercitation +1 labore velit, blog sartorial PBR leggings next level wes anderson artisan four loko farm-to-table craft beer twee. Qui photo booth letterpress, commodo enim craft beer mlkshk aliquip jean shorts ullamco ad vinyl cillum PBR. Homo nostrud organic, assumenda labore aesthetic magna delectus mollit.

    +
    + + +
    +
    +
    + +
    + +
    + + + + + +
    + +
    +
    + + +
    +
    +

    Pagination

    +
    + + + + + +
    +
    +
    +

    Pager

    +
    + + + +
    +
    +
    + +
    +
    +
    + + +
    + +
    +
    + +
    +
    + +
    +
    +

    Alerts

    +
    +
    + +

    h4.alert-warning

    +

    Best check yo self, you're not looking too good. Nulla vitae elit libero, a pharetra augue. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.

    +
    +
    +
    +
    +
    +
    +
    +
    + + strong.danger a.alert-link and try submitting again. +
    +
    +
    +
    +
    +
    + + strong.success You successfully read a.alert-link. +
    +
    +
    +
    +
    +
    + + strong.alert-info This a.alert-link, but it's not super important. +
    +
    +
    +
    +
    +
    +

    Labels

    +
    + Default + Primary + Success + Warning + Danger + Info +
    +
    +
    +

    Badges

    + +
    +
    +
    + + +
    + +
    +
    + + +

    Basic

    +
    +
    +
    +
    +
    + +

    Contextual alternatives

    +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    + +

    Striped

    +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    + +

    Animated

    +
    +
    +
    +
    +
    + +

    Stacked

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + +
    + +
    +
    + +
    +
    +

    Jumbotron

    +

    This is a simple hero unit, a simple jumbotron-style component for calling extra attention to featured content or information.

    +

    Learn more

    +
    +
    +
    +
    + + +
    +
    +

    List groups

    +
    +
    + + + +
    +
    +

    Panels

    +
    +
    +
    +
    +
    +
    +
    + Panel content +
    +
    +
    +
    + Panel content +
    + +
    + +
    +
    +
    +
    +
    +
    .panel-default
    +
    + Panel content +
    +
    + +
    +
    +

    .panel-primary

    +
    +
    + Panel content +
    +
    + +
    +
    +

    .panel-success

    +
    +
    + Panel content +
    +
    + +
    +
    +
    +
    +
    +
    +

    .panel-warning

    +
    +
    + Panel content +
    +
    + +
    +
    +

    .panel-danger

    +
    +
    + Panel content +
    +
    + +
    +
    +

    .panel-info

    +
    +
    + Panel content +
    +
    +
    +
    +
    + +
    +
    +

    Wells

    +
    +
    +
    +
    +
    +
    + Look, I'm in a well! +
    +
    +
    +
    +
    +
    + Look, I'm in a small well! +
    +
    +
    +
    +
    +
    + Look, I'm in a large well! +
    +
    +
    +
    +
    + + +
    + +
    +
    + +
    +
    +
    +
    +

    Modals

    +
    + +
    +
    +
    +

    Popovers

    +
    + + + + + + + +
    +

    Tooltips

    +
    + + + + + + + +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/src/app/dashboard/dashboard-table.scss b/src/app/dashboard/dashboard-table.scss index 50bbd560..79cf4535 100644 --- a/src/app/dashboard/dashboard-table.scss +++ b/src/app/dashboard/dashboard-table.scss @@ -3,6 +3,7 @@ th { font-weight: normal; + white-space: nowrap } tbody th { white-space: nowrap; @@ -12,4 +13,8 @@ .table-dashboard__highlight { font-size: 20px; color: $brand-primary; + + td { + white-space: nowrap; + } } diff --git a/src/app/dashboard/init.js b/src/app/dashboard/init.js index f4e98d26..da655ede 100644 --- a/src/app/dashboard/init.js +++ b/src/app/dashboard/init.js @@ -57,8 +57,8 @@ angular.module('dashboardModule', [ templateUrl: '/views/dashboard/welcome.html', controller: 'dashboardController' }) - .when('/help', { - templateUrl: '/views/help.html' + .when('/css-test', { + templateUrl: '/views/dashboard/css-test.html' }) .otherwise({ redirectTo: '/' diff --git a/src/app/dashboard/menu/controller.js b/src/app/dashboard/menu/controller.js index bfb4b3dd..834e20e8 100644 --- a/src/app/dashboard/menu/controller.js +++ b/src/app/dashboard/menu/controller.js @@ -6,14 +6,15 @@ angular.module('dashboardModule') 'loginLoginService', '$rootScope', function($scope, menuService, loginLoginService, $rootScope) { - $scope.user = loginLoginService; + $scope.isMenuActive = false; $scope.items = menuService.items; $scope.closeAll = menuService.closeAll; $rootScope.$on('$locationChangeSuccess', function(){ menuService.update(); + $scope.isMenuActive = false; }); } ]); \ No newline at end of file diff --git a/src/app/dashboard/menu/service.js b/src/app/dashboard/menu/service.js index 7241afa2..5a3dba59 100644 --- a/src/app/dashboard/menu/service.js +++ b/src/app/dashboard/menu/service.js @@ -2,9 +2,9 @@ angular.module('dashboardModule') .factory('menuService', [ '$location', + 'loginLoginService', '_', - function($location, _) { - + function($location, loginLoginService, _) { // States: // - isActive (bool) // - isOpen (bool) diff --git a/src/app/dashboard/menu/view.html b/src/app/dashboard/menu/view.html index 3c0ce7a0..995dbfd5 100644 --- a/src/app/dashboard/menu/view.html +++ b/src/app/dashboard/menu/view.html @@ -1,78 +1,106 @@ - - - - + \ No newline at end of file diff --git a/src/app/dashboard/welcome.html b/src/app/dashboard/welcome.html index 1915df41..5cf66cec 100644 --- a/src/app/dashboard/welcome.html +++ b/src/app/dashboard/welcome.html @@ -13,42 +13,44 @@

    Sales

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Total SalesOrder CountSales Avg.
    Today$$
    Yesterday{{salesStats.sales.yesterday | currency}}{{salesStats.orders.yesterday}}{{salesStats.salesAvg.yesterday | currency}}
    Last 7 days{{salesStats.sales.week | currency}}{{salesStats.orders.week}}{{salesStats.salesAvg.week | currency}}
    Month to date{{salesStats.sales.monthToDate | currency}}{{salesStats.orders.monthToDate}}{{salesStats.salesAvg.monthToDate | currency}}
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Total SalesOrder CountSales Avg.
    Today$$
    Yesterday{{salesStats.sales.yesterday | currency}}{{salesStats.orders.yesterday}}{{salesStats.salesAvg.yesterday | currency}}
    Last 7 days{{salesStats.sales.week | currency}}{{salesStats.orders.week}}{{salesStats.salesAvg.week | currency}}
    Month to date{{salesStats.sales.monthToDate | currency}}{{salesStats.orders.monthToDate}}{{salesStats.salesAvg.monthToDate | currency}}
    +
    @@ -63,37 +65,39 @@

    Sales

    Visits

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Total Page ViewsUnique Visitors
    Today
    Yesterday{{visitStats.total.yesterday}}{{visitStats.unique.yesterday}}
    Last 7 days{{visitStats.total.week}}{{visitStats.unique.week}}
    Month to date{{visitStats.total.monthToDate}}{{visitStats.unique.monthToDate}}
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Total Page ViewsUnique Visitors
    Today
    Yesterday{{visitStats.total.yesterday}}{{visitStats.unique.yesterday}}
    Last 7 days{{visitStats.total.week}}{{visitStats.unique.week}}
    Month to date{{visitStats.total.monthToDate}}{{visitStats.unique.monthToDate}}
    +
    diff --git a/src/app/design/directives/ot-prettify.js b/src/app/design/directives/ot-prettify.js new file mode 100644 index 00000000..24843964 --- /dev/null +++ b/src/app/design/directives/ot-prettify.js @@ -0,0 +1,23 @@ +angular.module('coreModule') + +.directive('otPrettify', [ + function(){ + return { + require: '?ngModel', // Array = multiple requires, ? = optional, ^ = check parent elements + link: function(scope, elem, attr, ngModel) { + if (scope.attribute.Type == 'json'){ + + ngModel.$formatters.push(function(value){ + var parsed = {}; + if (typeof value == 'object' && value != null) { //if it is already parsed json + parsed = value; // then its ok + } else if (typeof value == 'string') { + parsed = JSON.parse(value) // need to parse + } + + return JSON.stringify(parsed ,null,' ') // 4 spaces indent + }) + } + } + }; +}]); diff --git a/src/app/discounts/list.html b/src/app/discounts/list.html index aaa19935..fcd81523 100644 --- a/src/app/discounts/list.html +++ b/src/app/discounts/list.html @@ -7,33 +7,33 @@

    - - - - - - - - - - - - - - - - - - -
    DetailsTotal Redemption LimitBegins / Ends
    - You don't have any discounts create a discount to get started. -
    -

    {{ discount.code }}

    -
    - {{ discount.times === -1 ? 'No limit' : discount.times }} - - Begins:
    - Ends: -
    - +
    + + + + + + + + + + + + + + + + + + + + +
    DetailsTotal Redemption LimitBeginsEnds
    + You don't have any discounts create a discount to get started. +
    + {{ discount.code }} + + {{ discount.times === -1 ? 'No limit' : discount.times }} +
    +
    diff --git a/src/app/index.html b/src/app/index.html index 725d4dd1..e94cecfa 100644 --- a/src/app/index.html +++ b/src/app/index.html @@ -26,15 +26,13 @@ - +
    - -
    diff --git a/src/app/login/login.service.js b/src/app/login/login.service.js index db2c061c..bc298e85 100644 --- a/src/app/login/login.service.js +++ b/src/app/login/login.service.js @@ -1,4 +1,4 @@ -angular.module("loginModule") +angular.module('loginModule') .service('loginLoginService', [ '$resource', @@ -10,7 +10,7 @@ angular.module("loginModule") var login, isAdmin, isLoggedIn, deferIsLoggedIn , mapFields, deferLogOut; /** Functions */ var init, getLogin, getLoginId, setLogin, cleanLogin, getLoginProperty, - getFullName, fIsLoggedIn, getDefaultLogin, logout, fillFields; + getFullName, fIsLoggedIn, getDefaultLogin, getLoginEmail, logout, fillFields; isLoggedIn = null; @@ -151,12 +151,17 @@ angular.module("loginModule") return isLoggedIn; }; + getLoginEmail = function(){ + return login.email; + }; + return { init: init, cleanLogin: cleanLogin, setLogin: setLogin, getLogin: getLogin, - getFullName: getFullName, + name: getFullName, + email: getLoginEmail, getLoginId: getLoginId, isLoggedIn: fIsLoggedIn, logout: logout diff --git a/src/app/order/edit.html b/src/app/order/edit.html index dd14fb9c..2d889f96 100644 --- a/src/app/order/edit.html +++ b/src/app/order/edit.html @@ -25,51 +25,53 @@

    Order Items
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameSKUOptions PriceQuantityTotals
    {{product.Name}}{{product.Sku}} -
    - {{ option.label }}: {{ option.value }} -
    -
    {{product.Price | currency}}{{product.Qty}}{{product.Qty * product.Price | currency}}
    -
    Subtotal:
    -
    Shipping:
    -
    Tax:
    -
    Discounts:
    -
    Order Total:
    -
    -
    {{order.subtotal | currency}}
    -
    {{order.shipping_amount | currency}}
    -
    {{order.tax_amount | currency}}
    -
    ({{order.discount | currency}})
    -
    {{order.grand_total | currency}}
    -
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameSKUOptions PriceQuantityTotals
    {{product.Name}}{{product.Sku}} +
    + {{ option.label }}: {{ option.value }} +
    +
    {{product.Price | currency}}{{product.Qty}}{{product.Qty * product.Price | currency}}
    +
    Subtotal:
    +
    Shipping:
    +
    Tax:
    +
    Discounts:
    +
    Order Total:
    +
    +
    {{order.subtotal | currency}}
    +
    {{order.shipping_amount | currency}}
    +
    {{order.tax_amount | currency}}
    +
    {{order.discount | currency}}
    +
    {{order.grand_total | currency}}
    +
    +
    diff --git a/src/app/order/print.controller.js b/src/app/order/print.controller.js index 687f62bc..00903a58 100644 --- a/src/app/order/print.controller.js +++ b/src/app/order/print.controller.js @@ -10,7 +10,7 @@ angular.module('orderModule') function($scope, $location, $q, $timeout, orderApiService, cmsApiService) { $scope.options = { - showPrice: 0 + showPrice: showPrice() }; $scope.orders = []; @@ -28,35 +28,31 @@ angular.module('orderModule') function activate() { var ids = $location.search().ids.split(','); - fetchOrders(ids); - fetchCmsHeader(); - showPrice(); + var o = fetchOrders(ids); + var c = fetchCmsHeader(); + $q.all([o,c]).then(function(){ + // introduce a delay so angular has time to render before we print + $timeout(window.print, 500); + }); + } // REFACTOR: We should just be making a single request to the server // http://api.ottemo.io/orders?_id=562125eb30dd91015200003d,5621252c30dd91015200001f // but right now the response from /orders is different than /order/:id function fetchOrders(ids) { - var allPromises = []; - angular.forEach(ids, function(id) { - var promise = orderApiService.getOrder({ - 'orderID': id - }).$promise - .then(function(resp) { - $scope.orders.push(resp.result); - }); - - allPromises.push(promise); + var allPromises = ids.map(function(id) { + var params = { 'orderID': id }; + return orderApiService.getOrder(params).$promise; }); // Wait for all requests to complete - $q.all(allPromises) - .then(function( /*results*/ ) { + return $q.all(allPromises).then(function(results) { + var orders = results.map(function(resp){ + return resp.result; + }); - // Trigger the print dialog once we've had time to render - $timeout(function() { - window.print(); - }, 1000); + $scope.orders = orders; }); } @@ -71,7 +67,7 @@ angular.module('orderModule') 'extra': 'content', }; - cmsApiService.blockList(params).$promise + return cmsApiService.blockList(params).$promise .then(function(resp) { // Normalize response if (resp.result) { @@ -98,7 +94,7 @@ angular.module('orderModule') showPrice = parseInt($location.search().price, 10); } - $scope.options.showPrice = showPrice; + return showPrice; } } ]); diff --git a/src/app/order/print.html b/src/app/order/print.html index fb3aec26..4e129b1b 100644 --- a/src/app/order/print.html +++ b/src/app/order/print.html @@ -1,5 +1,8 @@ +
    + loading... +
    + ng-repeat="order in orders track by order._id"> -
    +
    -
    -
    - -
    -
    - -
    -
    +
    +
    + +
    +
    + +
    +
    diff --git a/src/app/product/attribute/list.html b/src/app/product/attribute/list.html index 97e69ac5..74244d31 100644 --- a/src/app/product/attribute/list.html +++ b/src/app/product/attribute/list.html @@ -1,8 +1,8 @@ -
    - - -
    \ No newline at end of file + + diff --git a/src/app/product/list.controller.js b/src/app/product/list.controller.js index 85a12cf4..2451c862 100644 --- a/src/app/product/list.controller.js +++ b/src/app/product/list.controller.js @@ -82,7 +82,6 @@ function ($scope, $location, $routeParams, $q, DashboardListService, productApiS $scope.attributes = result; serviceList.setAttributes($scope.attributes); $scope.fields = $scope.fields.concat(serviceList.getFields(showColumns)); - getProductsList(); }); }; diff --git a/src/app/product/list.html b/src/app/product/list.html index dab44df9..1f6912e6 100644 --- a/src/app/product/list.html +++ b/src/app/product/list.html @@ -1,15 +1,12 @@ -
    + - - + - - -
    diff --git a/src/app/reports/customer-activity.html b/src/app/reports/customer-activity.html index 50e28bfd..70bb3650 100644 --- a/src/app/reports/customer-activity.html +++ b/src/app/reports/customer-activity.html @@ -23,47 +23,49 @@

    - - - - - - - - - - - - - - - - - - - - - - - - - - +
    +
    EmailNameTotal SalesTotal OrdersAvg Order AmountFirst Purchase DateMost Recent Purchase
    {{c.email}}{{c.name}}{{c.total_sales | currency}}{{c.total_orders}}{{c.avg_sales | currency}}
    - No results found for this timeframe. -
    + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - -
    EmailNameTotal SalesTotal OrdersAvg Order AmountFirst Purchase DateMost Recent Purchase
    {{c.email}}{{c.name}}{{c.total_sales | currency}}{{c.total_orders}}{{c.avg_sales | currency}}
    + No results found for this timeframe. +
    - - count: {{ report.meta.count }}, - limit: {{report.meta.limit}}, - perf: {{report.perf_ms.toFixed(2)}} ms, - frame: {{timeframe.frame}} - -
    + +

    + + count: {{ report.meta.count }}, + limit: {{report.meta.limit}}, + perf: {{report.perf_ms.toFixed(2)}} ms, + frame: {{timeframe.frame}} + +
    +
    diff --git a/src/app/reports/product.html b/src/app/reports/product.html index 347d87f1..0847e551 100644 --- a/src/app/reports/product.html +++ b/src/app/reports/product.html @@ -25,44 +25,46 @@

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameSkuUnits SoldGross Sales
    {{product.name}}{{product.sku}}{{product.units_sold}}{{product.gross_sales | currency}}
    - No results found for this timeframe. -
    - Totals - - - {{report.total_items}} items in -
    {{report.total_orders}} orders -
    - {{report.total_sales | currency}} -
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameSkuUnits SoldGross Sales
    {{product.name}}{{product.sku}}{{product.units_sold}}{{product.gross_sales | currency}}
    + No results found for this timeframe. +
    + Totals + + + {{report.total_items}} items in +
    {{report.total_orders}} orders +
    + {{report.total_sales | currency}} +
    +
    diff --git a/src/app/seo/edit.html b/src/app/seo/edit.html index 2f89d1bb..beab795a 100644 --- a/src/app/seo/edit.html +++ b/src/app/seo/edit.html @@ -9,11 +9,8 @@

    -
    + + - - - - - -
    + + diff --git a/src/app/subscriptions/edit.html b/src/app/subscriptions/edit.html index 3f81479a..3c603d7e 100644 --- a/src/app/subscriptions/edit.html +++ b/src/app/subscriptions/edit.html @@ -15,51 +15,53 @@

    Order Items
    - - - - - - - - - - - - - - - - - - - - - - -
    NameSKUOptionsPriceQuantityTotals
    {{ product.name }}{{ product.sku }} -
    - {{ label }}: {{ value }} -
    -
    {{ product.price | currency }}{{ product.qty }}{{ product.qty * product.price | currency }}
    +
    + + + + + + + + + + + + + + + + + + + + + + +
    NameSKUOptionsPriceQuantityTotals
    {{ product.name }}{{ product.sku }} +
    + {{ label }}: {{ value }} +
    +
    {{ product.price | currency }}{{ product.qty }}{{ product.qty * product.price | currency }}
    +
    diff --git a/src/app/visitor/attribute/edit.html b/src/app/visitor/attribute/edit.html index 89c0061a..3f230466 100644 --- a/src/app/visitor/attribute/edit.html +++ b/src/app/visitor/attribute/edit.html @@ -13,9 +13,7 @@

    -
    - - + diff --git a/src/app/visitor/attribute/list.html b/src/app/visitor/attribute/list.html index 8120b1c0..87bc0cd8 100644 --- a/src/app/visitor/attribute/list.html +++ b/src/app/visitor/attribute/list.html @@ -5,7 +5,7 @@

    -
    +
    \ No newline at end of file diff --git a/src/app/visitor/edit.html b/src/app/visitor/edit.html index b9d82b67..5c94e248 100644 --- a/src/app/visitor/edit.html +++ b/src/app/visitor/edit.html @@ -26,63 +26,61 @@

    ng-click="addressForm()">Addresses

    +

    +

    No orders to report

    - - - - - - - - - - - - - - - - + + + + +
    Order DateIDNotesTotalStatusActions
    {{ order.Extra._id }} -
    -
    - {{ note }} +
    + + + + + + + + + + + + + + + - - - - - -
    Order DateIDNotesTotalStatus
    {{ order.ID }} +
    +
    + {{ note }} +
    - -
    {{ order.Extra.grand_total | currency }}{{ order.Extra.status }} - View Order -
    +
    {{ order.Extra.grand_total | currency }}{{ order.Extra.status }}
    +

    No subscriptions to report

    - - - - - - - - - - - - - - - - - -
    Order DateIDStatusActions
    {{ subscription.Extra._id }}{{ subscription.Extra.status }} - View Subscription -
    +
    + + + + + + + + + + + + + + + +
    Order DateIDStatus
    {{ subscription.ID }}{{ subscription.Extra.status }}
    +
    diff --git a/src/app/visitor/email.html b/src/app/visitor/email.html index a1cf4897..17461b8a 100644 --- a/src/app/visitor/email.html +++ b/src/app/visitor/email.html @@ -5,15 +5,13 @@

    -
    +
    - -
    - - Send -
    \ No newline at end of file +
    +
    +Send \ No newline at end of file