Dan Brown

Updated popup design and started integrating link selector

Extracted design and base styles from image manager into generic popup
classes that can be used by other app components such as the new
popup Book/Chapter/Page link selector
...@@ -69,7 +69,7 @@ module.exports = function (ngApp, events) { ...@@ -69,7 +69,7 @@ module.exports = function (ngApp, events) {
69 */ 69 */
70 function callbackAndHide(returnData) { 70 function callbackAndHide(returnData) {
71 if (callback) callback(returnData); 71 if (callback) callback(returnData);
72 - $scope.showing = false; 72 + $scope.hide();
73 } 73 }
74 74
75 /** 75 /**
...@@ -109,6 +109,7 @@ module.exports = function (ngApp, events) { ...@@ -109,6 +109,7 @@ module.exports = function (ngApp, events) {
109 function show(doneCallback) { 109 function show(doneCallback) {
110 callback = doneCallback; 110 callback = doneCallback;
111 $scope.showing = true; 111 $scope.showing = true;
112 + $('#image-manager').find('.overlay').css('display', 'flex').hide().fadeIn(240);
112 // Get initial images if they have not yet been loaded in. 113 // Get initial images if they have not yet been loaded in.
113 if (!dataLoaded) { 114 if (!dataLoaded) {
114 fetchData(); 115 fetchData();
...@@ -131,6 +132,7 @@ module.exports = function (ngApp, events) { ...@@ -131,6 +132,7 @@ module.exports = function (ngApp, events) {
131 */ 132 */
132 $scope.hide = function () { 133 $scope.hide = function () {
133 $scope.showing = false; 134 $scope.showing = false;
135 + $('#image-manager').find('.overlay').fadeOut(240);
134 }; 136 };
135 137
136 var baseUrl = window.baseUrl('/images/' + $scope.imageType + '/all/'); 138 var baseUrl = window.baseUrl('/images/' + $scope.imageType + '/all/');
......
...@@ -18,7 +18,7 @@ window.baseUrl = function(path) { ...@@ -18,7 +18,7 @@ window.baseUrl = function(path) {
18 var ngApp = angular.module('bookStack', ['ngResource', 'ngAnimate', 'ngSanitize', 'ui.sortable']); 18 var ngApp = angular.module('bookStack', ['ngResource', 'ngAnimate', 'ngSanitize', 'ui.sortable']);
19 19
20 // Global Event System 20 // Global Event System
21 -class Events { 21 +class EventManager {
22 constructor() { 22 constructor() {
23 this.listeners = {}; 23 this.listeners = {};
24 } 24 }
...@@ -39,12 +39,12 @@ class Events { ...@@ -39,12 +39,12 @@ class Events {
39 return this; 39 return this;
40 } 40 }
41 }; 41 };
42 -window.Events = new Events(); 42 +window.Events = new EventManager();
43 43
44 44
45 -var services = require('./services')(ngApp, Events); 45 +var services = require('./services')(ngApp, window.Events);
46 -var directives = require('./directives')(ngApp, Events); 46 +var directives = require('./directives')(ngApp, window.Events);
47 -var controllers = require('./controllers')(ngApp, Events); 47 +var controllers = require('./controllers')(ngApp, window.Events);
48 48
49 //Global jQuery Config & Extensions 49 //Global jQuery Config & Extensions
50 50
...@@ -130,6 +130,10 @@ $(function () { ...@@ -130,6 +130,10 @@ $(function () {
130 $('.entity-list.compact').find('p').not('.empty-text').slideToggle(240); 130 $('.entity-list.compact').find('p').not('.empty-text').slideToggle(240);
131 }); 131 });
132 132
133 + // Popup close
134 + $('.popup-close').click(function() {
135 + $(this).closest('.overlay').fadeOut(240);
136 + });
133 137
134 }); 138 });
135 139
......
...@@ -95,7 +95,12 @@ var mceOptions = module.exports = { ...@@ -95,7 +95,12 @@ var mceOptions = module.exports = {
95 alignright: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img', classes: 'align-right'}, 95 alignright: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img', classes: 'align-right'},
96 }, 96 },
97 file_browser_callback: function (field_name, url, type, win) { 97 file_browser_callback: function (field_name, url, type, win) {
98 +
99 + // Show image manager
98 window.ImageManager.showExternal(function (image) { 100 window.ImageManager.showExternal(function (image) {
101 +
102 + // Set popover link input to image url then fire change event
103 + // to ensure the new value sticks
99 win.document.getElementById(field_name).value = image.url; 104 win.document.getElementById(field_name).value = image.url;
100 if ("createEvent" in document) { 105 if ("createEvent" in document) {
101 var evt = document.createEvent("HTMLEvents"); 106 var evt = document.createEvent("HTMLEvents");
...@@ -104,6 +109,8 @@ var mceOptions = module.exports = { ...@@ -104,6 +109,8 @@ var mceOptions = module.exports = {
104 } else { 109 } else {
105 win.document.getElementById(field_name).fireEvent("onchange"); 110 win.document.getElementById(field_name).fireEvent("onchange");
106 } 111 }
112 +
113 + // Replace the actively selected content with the linked image
107 var html = '<a href="' + image.url + '" target="_blank">'; 114 var html = '<a href="' + image.url + '" target="_blank">';
108 html += '<img src="' + image.thumbs.display + '" alt="' + image.name + '">'; 115 html += '<img src="' + image.thumbs.display + '" alt="' + image.name + '">';
109 html += '</a>'; 116 html += '</a>';
...@@ -119,6 +126,8 @@ var mceOptions = module.exports = { ...@@ -119,6 +126,8 @@ var mceOptions = module.exports = {
119 extraSetups: [], 126 extraSetups: [],
120 setup: function (editor) { 127 setup: function (editor) {
121 128
129 + // Run additional setup actions
130 + // Used by the angular side of things
122 for (var i = 0; i < mceOptions.extraSetups.length; i++) { 131 for (var i = 0; i < mceOptions.extraSetups.length; i++) {
123 mceOptions.extraSetups[i](editor); 132 mceOptions.extraSetups[i](editor);
124 } 133 }
......
1 .overlay { 1 .overlay {
2 - background-color: rgba(0, 0, 0, 0.2); 2 + background-color: rgba(0, 0, 0, 0.333);
3 position: fixed; 3 position: fixed;
4 z-index: 95536; 4 z-index: 95536;
5 width: 100%; 5 width: 100%;
...@@ -10,37 +10,61 @@ ...@@ -10,37 +10,61 @@
10 left: 0; 10 left: 0;
11 right: 0; 11 right: 0;
12 bottom: 0; 12 bottom: 0;
13 + display: flex;
14 + align-items: center;
15 + justify-content: center;
16 + display: none;
13 } 17 }
14 18
15 -.image-manager-body { 19 +.popup-body {
16 background-color: #FFF; 20 background-color: #FFF;
17 max-height: 90%; 21 max-height: 90%;
18 - width: 90%; 22 + width: 1200px;
19 - height: 90%; 23 + height: auto;
20 margin: 2% 5%; 24 margin: 2% 5%;
21 border-radius: 4px; 25 border-radius: 4px;
22 box-shadow: 0 0 15px 0 rgba(0, 0, 0, 0.3); 26 box-shadow: 0 0 15px 0 rgba(0, 0, 0, 0.3);
23 overflow: hidden; 27 overflow: hidden;
24 - position: fixed;
25 - top: 0;
26 - bottom: 0;
27 - left: 0;
28 z-index: 999; 28 z-index: 999;
29 display: flex; 29 display: flex;
30 - h1, h2, h3 { 30 + flex-direction: column;
31 - font-weight: 300; 31 + &.small {
32 + margin: 2% auto;
33 + width: 800px;
34 + max-width: 90%;
35 + }
36 + &:before {
37 + display: flex;
38 + align-self: flex-start;
32 } 39 }
33 } 40 }
34 41
35 -#image-manager .dropzone-container { 42 +.popup-header {
43 + display: block;
36 position: relative; 44 position: relative;
37 - border: 3px dashed #DDD; 45 + height: 40px;
46 + .popup-close {
47 + position: absolute;
48 + top: 0;
49 + right: 0;
50 + margin: 0;
51 + height: 40px;
52 + border-radius: 0;
53 + box-shadow: none;
54 + }
55 + .popup-title {
56 + color: #FFF;
57 + padding: 8px $-m;
58 + }
38 } 59 }
39 60
40 -.image-manager-bottom { 61 +.image-manager-body {
41 - position: absolute; 62 + min-height: 60vh;
42 - bottom: 0; 63 +}
43 - right: 0; 64 +
65 +#image-manager .dropzone-container {
66 + position: relative;
67 + border: 3px dashed #DDD;
44 } 68 }
45 69
46 .image-manager-list .image { 70 .image-manager-list .image {
...@@ -103,18 +127,13 @@ ...@@ -103,18 +127,13 @@
103 127
104 .image-manager-sidebar { 128 .image-manager-sidebar {
105 width: 300px; 129 width: 300px;
106 - height: 100%;
107 margin-left: 1px; 130 margin-left: 1px;
108 - padding: 0 $-l; 131 + padding: $-m $-l;
132 + overflow-y: auto;
109 border-left: 1px solid #DDD; 133 border-left: 1px solid #DDD;
110 -} 134 + .dropzone-container {
111 - 135 + margin-top: $-m;
112 -.image-manager-close { 136 + }
113 - position: absolute;
114 - top: 0;
115 - right: 0;
116 - margin: 0;
117 - border-radius: 0;
118 } 137 }
119 138
120 .image-manager-list { 139 .image-manager-list {
...@@ -125,7 +144,6 @@ ...@@ -125,7 +144,6 @@
125 .image-manager-content { 144 .image-manager-content {
126 display: flex; 145 display: flex;
127 flex-direction: column; 146 flex-direction: column;
128 - height: 100%;
129 flex: 1; 147 flex: 1;
130 .container { 148 .container {
131 width: 100%; 149 width: 100%;
...@@ -141,12 +159,13 @@ ...@@ -141,12 +159,13 @@
141 * Copyright (c) 2012 Matias Meno <m@tias.me> 159 * Copyright (c) 2012 Matias Meno <m@tias.me>
142 */ 160 */
143 .dz-message { 161 .dz-message {
144 - font-size: 1.4em; 162 + font-size: 1.2em;
163 + line-height: 1.1;
145 font-style: italic; 164 font-style: italic;
146 color: #aaa; 165 color: #aaa;
147 text-align: center; 166 text-align: center;
148 cursor: pointer; 167 cursor: pointer;
149 - padding: $-xl $-m; 168 + padding: $-l $-m;
150 transition: all ease-in-out 120ms; 169 transition: all ease-in-out 120ms;
151 } 170 }
152 171
......
...@@ -25,6 +25,10 @@ body.flexbox { ...@@ -25,6 +25,10 @@ body.flexbox {
25 } 25 }
26 } 26 }
27 27
28 +.flex-child > div {
29 + flex: 1;
30 +}
31 +
28 /** Rules for all columns */ 32 /** Rules for all columns */
29 div[class^="col-"] img { 33 div[class^="col-"] img {
30 max-width: 100%; 34 max-width: 100%;
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
12 @import "animations"; 12 @import "animations";
13 @import "tinymce"; 13 @import "tinymce";
14 @import "highlightjs"; 14 @import "highlightjs";
15 -@import "image-manager"; 15 +@import "components";
16 @import "header"; 16 @import "header";
17 @import "lists"; 17 @import "lists";
18 @import "pages"; 18 @import "pages";
......
...@@ -21,4 +21,16 @@ ...@@ -21,4 +21,16 @@
21 </div> 21 </div>
22 @include('partials/image-manager', ['imageType' => 'gallery', 'uploaded_to' => $page->id]) 22 @include('partials/image-manager', ['imageType' => 'gallery', 'uploaded_to' => $page->id])
23 23
24 + <div id="entity-selector-wrap">
25 + <div class="overlay">
26 + <div class="popup-body small flex-child">
27 + <div class="popup-header primary-background">
28 + <div class="popup-title">Entity Select</div>
29 + <button class="popup-close neg button">x</button>
30 + </div>
31 + @include('partials/entity-selector', ['name' => 'entity-selector'])
32 + </div>
33 + </div>
34 + </div>
35 +
24 @stop 36 @stop
...\ No newline at end of file ...\ No newline at end of file
......
1 <div id="image-manager" image-type="{{ $imageType }}" ng-controller="ImageManagerController" uploaded-to="{{ $uploaded_to or 0 }}"> 1 <div id="image-manager" image-type="{{ $imageType }}" ng-controller="ImageManagerController" uploaded-to="{{ $uploaded_to or 0 }}">
2 - <div class="overlay anim-slide" ng-show="showing" ng-cloak ng-click="hide()"> 2 + <div class="overlay" ng-cloak ng-click="hide()">
3 - <div class="image-manager-body" ng-click="$event.stopPropagation()"> 3 + <div class="popup-body" ng-click="$event.stopPropagation()">
4 - 4 +
5 - <div class="image-manager-content"> 5 + <div class="popup-header primary-background">
6 - <div ng-if="imageType === 'gallery'" class="container"> 6 + <div class="popup-title">Image Select</div>
7 - <div class="image-manager-header row faded-small nav-tabs"> 7 + <button class="popup-close neg button">x</button>
8 - <div class="col-xs-4 tab-item" title="View all images" ng-class="{selected: (view=='all')}" ng-click="setView('all')"><i class="zmdi zmdi-collection-image"></i> All</div> 8 + </div>
9 - <div class="col-xs-4 tab-item" title="View images uploaded to this book" ng-class="{selected: (view=='book')}" ng-click="setView('book')"><i class="zmdi zmdi-book text-book"></i> Book</div> 9 +
10 - <div class="col-xs-4 tab-item" title="View images uploaded to this page" ng-class="{selected: (view=='page')}" ng-click="setView('page')"><i class="zmdi zmdi-file-text text-page"></i> Page</div> 10 + <div class="flex-fill image-manager-body">
11 +
12 + <div class="image-manager-content">
13 + <div ng-if="imageType === 'gallery'" class="container">
14 + <div class="image-manager-header row faded-small nav-tabs">
15 + <div class="col-xs-4 tab-item" title="View all images" ng-class="{selected: (view=='all')}" ng-click="setView('all')"><i class="zmdi zmdi-collection-image"></i> All</div>
16 + <div class="col-xs-4 tab-item" title="View images uploaded to this book" ng-class="{selected: (view=='book')}" ng-click="setView('book')"><i class="zmdi zmdi-book text-book"></i> Book</div>
17 + <div class="col-xs-4 tab-item" title="View images uploaded to this page" ng-class="{selected: (view=='page')}" ng-click="setView('page')"><i class="zmdi zmdi-file-text text-page"></i> Page</div>
18 + </div>
11 </div> 19 </div>
12 - </div> 20 + <div ng-show="view === 'all'" >
13 - <div ng-show="view === 'all'" > 21 + <form ng-submit="searchImages()" class="contained-search-box">
14 - <form ng-submit="searchImages()" class="contained-search-box"> 22 + <input type="text" placeholder="Search by image name" ng-model="searchTerm">
15 - <input type="text" placeholder="Search by image name" ng-model="searchTerm"> 23 + <button ng-class="{active: searching}" title="Clear Search" type="button" ng-click="cancelSearch()" class="text-button cancel"><i class="zmdi zmdi-close-circle-o"></i></button>
16 - <button ng-class="{active: searching}" title="Clear Search" type="button" ng-click="cancelSearch()" class="text-button cancel"><i class="zmdi zmdi-close-circle-o"></i></button> 24 + <button title="Search" class="text-button" type="submit"><i class="zmdi zmdi-search"></i></button>
17 - <button title="Search" class="text-button" type="submit"><i class="zmdi zmdi-search"></i></button> 25 + </form>
18 - </form> 26 + </div>
19 - </div> 27 + <div class="image-manager-list">
20 - <div class="image-manager-list"> 28 + <div ng-repeat="image in images">
21 - <div ng-repeat="image in images"> 29 + <div class="image anim fadeIn" ng-style="{animationDelay: ($index > 26) ? '160ms' : ($index * 25) + 'ms'}"
22 - <div class="image anim fadeIn" ng-style="{animationDelay: ($index > 26) ? '160ms' : ($index * 25) + 'ms'}" 30 + ng-class="{selected: (image==selectedImage)}" ng-click="imageSelect(image)">
23 - ng-class="{selected: (image==selectedImage)}" ng-click="imageSelect(image)"> 31 + <img ng-src="@{{image.thumbs.gallery}}" ng-attr-alt="@{{image.title}}" ng-attr-title="@{{image.name}}">
24 - <img ng-src="@{{image.thumbs.gallery}}" ng-attr-alt="@{{image.title}}" ng-attr-title="@{{image.name}}"> 32 + <div class="image-meta">
25 - <div class="image-meta"> 33 + <span class="name" ng-bind="image.name"></span>
26 - <span class="name" ng-bind="image.name"></span> 34 + <span class="date">Uploaded @{{ getDate(image.created_at) | date:'mediumDate' }}</span>
27 - <span class="date">Uploaded @{{ getDate(image.created_at) | date:'mediumDate' }}</span> 35 + </div>
28 </div> 36 </div>
29 </div> 37 </div>
38 + <div class="load-more" ng-show="hasMore" ng-click="fetchData()">Load More</div>
30 </div> 39 </div>
31 - <div class="load-more" ng-show="hasMore" ng-click="fetchData()">Load More</div>
32 </div> 40 </div>
33 - </div>
34 41
35 - <button class="neg button image-manager-close" ng-click="hide()">x</button> 42 + <div class="image-manager-sidebar">
43 + <div class="inner">
36 44
37 - <div class="image-manager-sidebar"> 45 + <div class="image-manager-details anim fadeIn" ng-show="selectedImage">
38 - <h2>Images</h2>
39 - <drop-zone upload-url="@{{getUploadUrl()}}" uploaded-to="@{{uploadedTo}}" event-success="uploadSuccess"></drop-zone>
40 - <div class="image-manager-details anim fadeIn" ng-show="selectedImage">
41 46
42 - <hr class="even"> 47 + <form ng-submit="saveImageDetails($event)">
48 + <div>
49 + <a ng-href="@{{selectedImage.url}}" target="_blank" style="display: block;">
50 + <img ng-src="@{{selectedImage.thumbs.gallery}}" ng-attr-alt="@{{selectedImage.title}}" ng-attr-title="@{{selectedImage.name}}">
51 + </a>
52 + </div>
53 + <div class="form-group">
54 + <label for="name">Image Name</label>
55 + <input type="text" id="name" name="name" ng-model="selectedImage.name">
56 + </div>
57 + </form>
58 +
59 + <div ng-show="dependantPages">
60 + <p class="text-neg text-small">
61 + This image is used in the pages below, Click delete again to confirm you want to delete
62 + this image.
63 + </p>
64 + <ul class="text-neg">
65 + <li ng-repeat="page in dependantPages">
66 + <a ng-href="@{{ page.url }}" target="_blank" class="text-neg" ng-bind="page.name"></a>
67 + </li>
68 + </ul>
69 + </div>
70 +
71 + <div class="clearfix">
72 + <form class="float left" ng-submit="deleteImage($event)">
73 + <button class="button neg"><i class="zmdi zmdi-delete"></i></button>
74 + </form>
75 + <button class="button pos anim fadeIn float right" ng-show="selectedImage" ng-click="selectButtonClick()">
76 + <i class="zmdi zmdi-square-right"></i>Select Image
77 + </button>
78 + </div>
43 79
44 - <form ng-submit="saveImageDetails($event)">
45 - <div>
46 - <a ng-href="@{{selectedImage.url}}" target="_blank" style="display: block;">
47 - <img ng-src="@{{selectedImage.thumbs.gallery}}" ng-attr-alt="@{{selectedImage.title}}" ng-attr-title="@{{selectedImage.name}}">
48 - </a>
49 - </div>
50 - <div class="form-group">
51 - <label for="name">Image Name</label>
52 - <input type="text" id="name" name="name" ng-model="selectedImage.name">
53 </div> 80 </div>
54 - </form>
55 -
56 - <hr class="even">
57 -
58 - <div ng-show="dependantPages">
59 - <p class="text-neg text-small">
60 - This image is used in the pages below, Click delete again to confirm you want to delete
61 - this image.
62 - </p>
63 - <ul class="text-neg">
64 - <li ng-repeat="page in dependantPages">
65 - <a ng-href="@{{ page.url }}" target="_blank" class="text-neg" ng-bind="page.name"></a>
66 - </li>
67 - </ul>
68 - </div>
69 81
70 - <form ng-submit="deleteImage($event)"> 82 + <drop-zone upload-url="@{{getUploadUrl()}}" uploaded-to="@{{uploadedTo}}" event-success="uploadSuccess"></drop-zone>
71 - <button class="button neg"><i class="zmdi zmdi-delete"></i>Delete Image</button>
72 - </form>
73 - </div>
74 83
75 - <div class="image-manager-bottom"> 84 +
76 - <button class="button pos anim fadeIn" ng-show="selectedImage" ng-click="selectButtonClick()"> 85 + </div>
77 - <i class="zmdi zmdi-square-right"></i>Select Image
78 - </button>
79 </div> 86 </div>
80 87
88 +
89 +
81 </div> 90 </div>
91 +
82 </div> 92 </div>
83 </div> 93 </div>
84 </div> 94 </div>
...\ No newline at end of file ...\ No newline at end of file
......