Toggle navigation
Toggle navigation
This project
Loading...
Sign in
Зуев Егор
/
wiki.dev
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Snippets
Network
Create a new issue
Commits
Issue Boards
Files
Commits
Network
Compare
Branches
Tags
Authored by
Dan Brown
2015-12-30 18:38:18 +0000
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
Commit
46c2e8b14e32995f4e405375bda77f7e7452a692
46c2e8b1
1 parent
3347b3b2
Moved all vuejs parts over to angular
Show whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
452 additions
and
440 deletions
gulpfile.js
package.json
resources/assets/js/components/drop-zone.html
resources/assets/js/components/image-manager.vue
resources/assets/js/components/image-picker.html
resources/assets/js/components/image-picker.vue
resources/assets/js/controllers.js
resources/assets/js/directives.js
resources/assets/js/global.js
resources/assets/js/jquery-extensions.js
resources/assets/js/pages/book-show.js
resources/assets/js/pages/page-form.js
resources/assets/js/services.js
resources/assets/sass/_image-manager.scss
resources/assets/sass/styles.scss
resources/views/base.blade.php
resources/views/books/show.blade.php
resources/views/books/sort.blade.php
resources/views/pages/create.blade.php
resources/views/pages/edit.blade.php
resources/views/pages/page-display.blade.php
resources/views/partials/image-manager.blade.php
resources/views/settings/index.blade.php
resources/views/users/edit.blade.php
gulpfile.js
View file @
46c2e8b
...
...
@@ -21,6 +21,6 @@ elixir.extend('queryVersion', function(inputFiles) {
elixir
(
function
(
mix
)
{
mix
.
sass
(
'styles.scss'
)
.
sass
(
'print-styles.scss'
)
.
browserify
(
[
'jquery-extensions.js'
,
'global.js'
]
,
'public/js/common.js'
)
.
browserify
(
'global.js'
,
'public/js/common.js'
)
.
queryVersion
([
'css/styles.css'
,
'css/print-styles.css'
,
'js/common.js'
]);
});
...
...
package.json
View file @
46c2e8b
{
"private"
:
true
,
"devDependencies"
:
{
"gulp"
:
"^3.9.0"
,
"insert-css"
:
"^0.2.0"
"gulp"
:
"^3.9.0"
},
"dependencies"
:
{
"angular"
:
"^1.5.0-rc.0"
,
"angular-animate"
:
"^1.5.0-rc.0"
,
"angular-resource"
:
"^1.5.0-rc.0"
,
"angular-sanitize"
:
"^1.5.0-rc.0"
,
"babel-runtime"
:
"^5.8.29"
,
"bootstrap-sass"
:
"^3.0.0"
,
"dropzone"
:
"^4.0.1"
,
"laravel-elixir"
:
"^3.4.0"
,
"vue"
:
"^1.0.13"
,
"vue-hot-reload-api"
:
"^1.2.1"
,
"vue-resource"
:
"^0.5.1"
,
"vueify"
:
"^5.0.1"
,
"vueify-insert-css"
:
"^1.0.0"
,
"zeroclipboard"
:
"^2.2.0"
}
}
...
...
resources/assets/js/components/drop-zone.html
0 → 100644
View file @
46c2e8b
<div
class=
"dropzone-container"
>
<div
class=
"dz-message"
>
Drop files or click here to upload
</div>
</div>
\ No newline at end of file
resources/assets/js/components/image-manager.vue
deleted
100644 → 0
View file @
3347b3b
<template>
<div id="image-manager">
<div class="overlay" v-el:overlay @click="overlayClick">
<div class="image-manager-body">
<div class="image-manager-content">
<div class="image-manager-list">
<div v-for="image in images">
<img class="anim fadeIn"
:class="{selected: (image==selectedImage)}"
:src="image.thumbs.gallery" :alt="image.title" :title="image.name"
@click="imageClick(image)"
:style="{animationDelay: ($index > 26) ? '160ms' : ($index * 25) + 'ms'}">
</div>
<div class="load-more" v-show="hasMore" @click="fetchData">Load More</div>
</div>
</div>
<button class="neg button image-manager-close" @click="hide">x</button>
<div class="image-manager-sidebar">
<h2 v-el:image-title>Images</h2>
<hr class="even">
<div class="dropzone-container" v-el:drop-zone>
<div class="dz-message">Drop files or click here to upload</div>
</div>
<div class="image-manager-details anim fadeIn" v-show="selectedImage">
<hr class="even">
<form @submit="saveImageDetails" v-el:image-form>
<div class="form-group">
<label for="name">Image Name</label>
<input type="text" id="name" name="name" v-model="selectedImage.name">
</div>
</form>
<hr class="even">
<div v-show="dependantPages">
<p class="text-neg text-small">
This image is used in the pages below, Click delete again to confirm you want to delete
this image.
</p>
<ul class="text-neg">
<li v-for="page in dependantPages">
<a :href="page.url" target="_blank" class="text-neg">{{ page.name }}</a>
</li>
</ul>
</div>
<form @submit="deleteImage" v-el:image-delete-form>
<button class="button neg"><i class="zmdi zmdi-delete"></i>Delete Image</button>
</form>
</div>
<div class="image-manager-bottom">
<button class="button pos anim fadeIn" v-show="selectedImage" @click="selectButtonClick"><i
class="zmdi zmdi-square-right"></i>Select Image
</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
var Dropzone = require('dropzone');
module.exports = {
data: function () {
return {
images: [],
hasMore: false,
page: 0,
cClickTime: 0,
selectedImage: false,
dependantPages: false,
deleteForm: {},
token: document.querySelector('meta[name=token]').getAttribute('content'),
dataLoaded: false
}
},
props: {
imageType: {
type: String,
required: true
}
},
created: function () {
window.ImageManager = this;
},
ready: function () {
// Create dropzone
this.setupDropZone();
},
methods: {
fetchData: function () {
var url = '/images/' + this.imageType + '/all/' + this.page;
this.$http.get(url).then((response) => {
this.images = this.images.concat(response.data.images);
this.hasMore = response.data.hasMore;
this.page++;
});
},
setupDropZone: function () {
var _this = this;
var dropZone = new Dropzone(_this.$els.dropZone, {
url: '/images/' + _this.imageType + '/upload',
init: function () {
var dz = this;
dz.on("sending", function (file, xhr, data) {
data.append("_token", _this.token);
});
dz.on("success", function (file, data) {
_this.images.unshift(data);
$(file.previewElement).fadeOut(400, function () {
dz.removeFile(file);
});
});
dz.on('error', function (file, errorMessage, xhr) {
if (errorMessage.file) {
$(file.previewElement).find('[data-dz-errormessage]').text(errorMessage.file[0]);
}
console.log(errorMessage);
});
}
});
},
returnCallback: function (image) {
this.callback(image);
},
imageClick: function (image) {
var dblClickTime = 380;
var cTime = (new Date()).getTime();
var timeDiff = cTime - this.cClickTime;
if (this.cClickTime !== 0 && timeDiff < dblClickTime && this.selectedImage === image) {
// DoubleClick
if (this.callback) {
this.returnCallback(image);
}
this.hide();
} else {
this.selectedImage = (this.selectedImage === image) ? false : image;
this.dependantPages = false;
}
this.cClickTime = cTime;
},
selectButtonClick: function () {
if (this.callback) this.returnCallback(this.selectedImage);
this.hide();
},
show: function (callback) {
this.callback = callback;
this.$els.overlay.style.display = 'block';
// Get initial images if they have not yet been loaded in.
if (!this.dataLoaded) {
this.fetchData(this.page);
this.dataLoaded = true;
}
},
overlayClick: function (e) {
if (e.target.className === 'overlay') {
this.hide();
}
},
hide: function () {
this.$els.overlay.style.display = 'none';
},
saveImageDetails: function (e) {
e.preventDefault();
this.selectedImage._token = this.token;
var form = $(this.$els.imageForm);
var url = '/images/update/' + this.selectedImage.id;
this.$http.put(url, this.selectedImage).then((response) => {
form.showSuccess('Image name updated');
}, (response) => {
form.showFailure(response.data);
});
},
deleteImage: function (e) {
e.preventDefault();
var _this = this;
_this.deleteForm.force = _this.dependantPages !== false;
_this.deleteForm._token = _this.token;
var url = '/images/' + _this.selectedImage.id;
this.$http.delete(url, this.deleteForm).then((response) => {
this.images.splice(this.images.indexOf(this.selectedImage), 1);
this.selectedImage = false;
$(this.$els.imageTitle).showSuccess('Image Deleted');
}, (response) => {
// Pages failure
if (response.status === 400) {
_this.dependantPages = response.data;
}
});
}
}
};
</script>
\ No newline at end of file
resources/assets/js/components/image-picker.html
0 → 100644
View file @
46c2e8b
<div
class=
"image-picker"
>
<div>
<img
ng-if=
"image && image !== 'none'"
ng-src=
"{{image}}"
ng-class=
"{{imageClass}}"
alt=
"Image Preview"
>
<img
ng-if=
"image === '' && defaultImage"
ng-src=
"{{defaultImage}}"
ng-class=
"{{imageClass}}"
alt=
"Image Preview"
>
</div>
<button
class=
"button"
type=
"button"
ng-click=
"showImageManager()"
>
Select Image
</button>
<br>
<button
class=
"text-button"
ng-click=
"reset()"
type=
"button"
>
Reset
</button>
<span
ng-show=
"showRemove"
class=
"sep"
>
|
</span>
<button
ng-show=
"showRemove"
class=
"text-button neg"
ng-click=
"remove()"
type=
"button"
>
Remove
</button>
<input
type=
"hidden"
ng-attr-name=
"{{name}}"
ng-attr-id=
"{{name}}"
ng-attr-value=
"{{value}}"
>
</div>
\ No newline at end of file
resources/assets/js/components/image-picker.vue
deleted
100644 → 0
View file @
3347b3b
<template>
<div class="image-picker">
<div>
<img v-if="image && image !== 'none'" :src="image" :class="imageClass" alt="Image Preview">
<img v-if="image === '' && defaultImage" :src="defaultImage" :class="imageClass" alt="Image Preview">
</div>
<button class="button" type="button" @click="showImageManager">Select Image</button>
<br>
<button class="text-button" @click="reset" type="button">Reset</button> <span v-show="showRemove" class="sep">|</span> <button v-show="showRemove" class="text-button neg" @click="remove" type="button">Remove</button>
<input type="hidden" :name="name" :id="name" v-model="value">
</div>
</template>
<script>
module.exports = {
props: {
currentImage: {
required: true,
type: String
},
currentId: {
required: false,
default: 'false',
type: String
},
name: {
required: true,
type: String
},
defaultImage: {
required: true,
type: String
},
imageClass: {
required: true,
type: String
},
resizeWidth: {
type: String
},
resizeHeight: {
type: String
},
resizeCrop: {
type: Boolean
},
showRemove: {
type: Boolean,
default: 'true'
}
},
data: function() {
return {
image: this.currentImage,
value: false
}
},
compiled: function() {
this.value = this.currentId === 'false' ? this.currentImage : this.currentId;
},
methods: {
setCurrentValue: function(imageModel, imageUrl) {
this.image = imageUrl;
this.value = this.currentId === 'false' ? imageUrl : imageModel.id;
},
showImageManager: function(e) {
ImageManager.show((image) => {
this.updateImageFromModel(image);
});
},
reset: function() {
this.setCurrentValue({id: 0}, this.defaultImage);
},
remove: function() {
this.image = 'none';
this.value = 'none';
},
updateImageFromModel: function(model) {
var isResized = this.resizeWidth && this.resizeHeight;
if (!isResized) {
this.setCurrentValue(model, model.url);
return;
}
var cropped = this.resizeCrop ? 'true' : 'false';
var requestString = '/images/thumb/' + model.id + '/' + this.resizeWidth + '/' + this.resizeHeight + '/' + cropped;
this.$http.get(requestString).then((response) => {
this.setCurrentValue(model, response.data.url);
});
}
}
};
</script>
\ No newline at end of file
resources/assets/js/controllers.js
0 → 100644
View file @
46c2e8b
"use strict"
;
module
.
exports
=
function
(
ngApp
)
{
ngApp
.
controller
(
'ImageManagerController'
,
[
'$scope'
,
'$attrs'
,
'$http'
,
'$timeout'
,
'imageManagerService'
,
function
(
$scope
,
$attrs
,
$http
,
$timeout
,
imageManagerService
)
{
$scope
.
images
=
[];
$scope
.
imageType
=
$attrs
.
imageType
;
$scope
.
selectedImage
=
false
;
$scope
.
dependantPages
=
false
;
$scope
.
showing
=
false
;
$scope
.
hasMore
=
false
;
$scope
.
imageUpdateSuccess
=
false
;
$scope
.
imageDeleteSuccess
=
false
;
var
page
=
0
;
var
previousClickTime
=
0
;
var
dataLoaded
=
false
;
var
callback
=
false
;
$scope
.
getUploadUrl
=
function
()
{
return
'/images/'
+
$scope
.
imageType
+
'/upload'
;
};
$scope
.
uploadSuccess
=
function
(
file
,
data
)
{
$scope
.
$apply
(()
=>
{
$scope
.
images
.
unshift
(
data
);
});
};
function
callbackAndHide
(
returnData
)
{
if
(
callback
)
callback
(
returnData
);
$scope
.
showing
=
false
;
}
$scope
.
imageSelect
=
function
(
image
)
{
var
dblClickTime
=
300
;
var
currentTime
=
Date
.
now
();
var
timeDiff
=
currentTime
-
previousClickTime
;
if
(
timeDiff
<
dblClickTime
)
{
// If double click
callbackAndHide
(
image
);
}
else
{
// If single
$scope
.
selectedImage
=
image
;
$scope
.
dependantPages
=
false
;
}
previousClickTime
=
currentTime
;
};
$scope
.
selectButtonClick
=
function
()
{
callbackAndHide
(
$scope
.
selectedImage
);
};
function
show
(
doneCallback
)
{
callback
=
doneCallback
;
$scope
.
showing
=
true
;
// Get initial images if they have not yet been loaded in.
if
(
!
dataLoaded
)
{
fetchData
();
dataLoaded
=
true
;
}
}
imageManagerService
.
show
=
show
;
imageManagerService
.
showExternal
=
function
(
doneCallback
)
{
$scope
.
$apply
(()
=>
{
show
(
doneCallback
);
});
};
window
.
ImageManager
=
imageManagerService
;
$scope
.
hide
=
function
()
{
$scope
.
showing
=
false
;
};
function
fetchData
()
{
var
url
=
'/images/'
+
$scope
.
imageType
+
'/all/'
+
page
;
$http
.
get
(
url
).
then
((
response
)
=>
{
$scope
.
images
=
$scope
.
images
.
concat
(
response
.
data
.
images
);
$scope
.
hasMore
=
response
.
data
.
hasMore
;
page
++
;
});
}
$scope
.
saveImageDetails
=
function
(
event
)
{
event
.
preventDefault
();
var
url
=
'/images/update/'
+
$scope
.
selectedImage
.
id
;
$http
.
put
(
url
,
this
.
selectedImage
).
then
((
response
)
=>
{
$scope
.
imageUpdateSuccess
=
true
;
$timeout
(()
=>
{
$scope
.
imageUpdateSuccess
=
false
;
},
3000
);
},
(
response
)
=>
{
var
errors
=
response
.
data
;
var
message
=
''
;
Object
.
keys
(
errors
).
forEach
((
key
)
=>
{
message
+=
errors
[
key
].
join
(
'\n'
);
});
$scope
.
imageUpdateFailure
=
message
;
$timeout
(()
=>
{
$scope
.
imageUpdateFailure
=
false
;
},
5000
);
});
};
$scope
.
deleteImage
=
function
(
event
)
{
event
.
preventDefault
();
var
force
=
$scope
.
dependantPages
!==
false
;
var
url
=
'/images/'
+
$scope
.
selectedImage
.
id
;
if
(
force
)
url
+=
'?force=true'
;
$http
.
delete
(
url
).
then
((
response
)
=>
{
$scope
.
images
.
splice
(
$scope
.
images
.
indexOf
(
$scope
.
selectedImage
),
1
);
$scope
.
selectedImage
=
false
;
$scope
.
imageDeleteSuccess
=
true
;
$timeout
(()
=>
{
$scope
.
imageDeleteSuccess
=
false
;
},
3000
);
},
(
response
)
=>
{
// Pages failure
if
(
response
.
status
===
400
)
{
$scope
.
dependantPages
=
response
.
data
;
}
});
};
}]);
ngApp
.
controller
(
'BookShowController'
,
[
'$scope'
,
'$http'
,
'$attrs'
,
function
(
$scope
,
$http
,
$attrs
)
{
$scope
.
searching
=
false
;
$scope
.
searchTerm
=
''
;
$scope
.
searchResults
=
''
;
$scope
.
searchBook
=
function
(
e
)
{
e
.
preventDefault
();
var
term
=
$scope
.
searchTerm
;
if
(
term
.
length
==
0
)
return
;
$scope
.
searching
=
true
;
$scope
.
searchResults
=
''
;
var
searchUrl
=
'/search/book/'
+
$attrs
.
bookId
;
searchUrl
+=
'?term='
+
encodeURIComponent
(
term
);
$http
.
get
(
searchUrl
).
then
((
response
)
=>
{
$scope
.
searchResults
=
response
.
data
;
});
};
$scope
.
checkSearchForm
=
function
()
{
if
(
$scope
.
searchTerm
.
length
<
1
)
{
$scope
.
searching
=
false
;
}
};
$scope
.
clearSearch
=
function
()
{
$scope
.
searching
=
false
;
$scope
.
searchTerm
=
''
;
};
}]);
};
\ No newline at end of file
resources/assets/js/directives.js
View file @
46c2e8b
"use strict"
;
var
DropZone
=
require
(
'dropzone'
);
var
toggleSwitchTemplate
=
require
(
'./components/toggle-switch.html'
);
var
imagePickerTemplate
=
require
(
'./components/image-picker.html'
);
var
dropZoneTemplate
=
require
(
'./components/drop-zone.html'
);
module
.
exports
=
function
(
ngApp
)
{
/**
* Toggle Switches
* Ha
ve
basic on/off functionality.
* Ha
s
basic on/off functionality.
* Use string values of 'true' & 'false' to dictate the current state.
*/
ngApp
.
directive
(
'toggleSwitch'
,
function
()
{
...
...
@@ -29,4 +33,127 @@ module.exports = function(ngApp) {
});
/**
* Image Picker
* Is a simple front-end interface that connects to an ImageManager if present.
*/
ngApp
.
directive
(
'imagePicker'
,
[
'$http'
,
'imageManagerService'
,
function
(
$http
,
imageManagerService
)
{
return
{
restrict
:
'E'
,
template
:
imagePickerTemplate
,
scope
:
{
name
:
'@'
,
resizeHeight
:
'@'
,
resizeWidth
:
'@'
,
resizeCrop
:
'@'
,
showRemove
:
'='
,
currentImage
:
'@'
,
currentId
:
'@'
,
defaultImage
:
'@'
,
imageClass
:
'@'
},
link
:
function
(
scope
,
element
,
attrs
)
{
var
usingIds
=
typeof
scope
.
currentId
!==
'undefined'
||
scope
.
currentId
===
'false'
;
scope
.
image
=
scope
.
currentImage
;
scope
.
value
=
scope
.
currentImage
||
''
;
function
setImage
(
imageModel
,
imageUrl
)
{
scope
.
image
=
imageUrl
;
scope
.
value
=
usingIds
?
imageModel
.
id
:
imageUrl
;
}
scope
.
reset
=
function
()
{
setImage
({
id
:
0
},
scope
.
defaultImage
);
};
scope
.
remove
=
function
()
{
scope
.
image
=
'none'
;
scope
.
value
=
'none'
;
};
scope
.
showImageManager
=
function
()
{
imageManagerService
.
show
((
image
)
=>
{
scope
.
updateImageFromModel
(
image
);
});
};
scope
.
updateImageFromModel
=
function
(
model
)
{
var
isResized
=
scope
.
resizeWidth
&&
scope
.
resizeHeight
;
if
(
!
isResized
)
{
scope
.
$apply
(()
=>
{
setImage
(
model
,
model
.
url
);
});
return
;
}
var
cropped
=
scope
.
resizeCrop
?
'true'
:
'false'
;
var
requestString
=
'/images/thumb/'
+
model
.
id
+
'/'
+
scope
.
resizeWidth
+
'/'
+
scope
.
resizeHeight
+
'/'
+
cropped
;
$http
.
get
(
requestString
).
then
((
response
)
=>
{
setImage
(
model
,
response
.
data
.
url
);
});
};
}
};
}]);
/**
* DropZone
* Used for uploading images
*/
ngApp
.
directive
(
'dropZone'
,
[
function
()
{
return
{
restrict
:
'E'
,
template
:
dropZoneTemplate
,
scope
:
{
uploadUrl
:
'@'
,
eventSuccess
:
'='
,
eventError
:
'='
},
link
:
function
(
scope
,
element
,
attrs
)
{
var
dropZone
=
new
DropZone
(
element
[
0
].
querySelector
(
'.dropzone-container'
),
{
url
:
scope
.
uploadUrl
,
init
:
function
()
{
var
dz
=
this
;
dz
.
on
(
'sending'
,
function
(
file
,
xhr
,
data
)
{
var
token
=
window
.
document
.
querySelector
(
'meta[name=token]'
).
getAttribute
(
'content'
);
data
.
append
(
'_token'
,
token
);
});
if
(
typeof
scope
.
eventSuccess
!==
'undefined'
)
dz
.
on
(
'success'
,
scope
.
eventSuccess
);
dz
.
on
(
'success'
,
function
(
file
,
data
)
{
$
(
file
.
previewElement
).
fadeOut
(
400
,
function
()
{
dz
.
removeFile
(
file
);
});
});
if
(
typeof
scope
.
eventError
!==
'undefined'
)
dz
.
on
(
'error'
,
scope
.
eventError
);
dz
.
on
(
'error'
,
function
(
file
,
errorMessage
,
xhr
)
{
if
(
errorMessage
.
file
)
{
$
(
file
.
previewElement
).
find
(
'[data-dz-errormessage]'
).
text
(
errorMessage
.
file
[
0
]);
}
});
}
});
}
};
}]);
ngApp
.
directive
(
'dropdown'
,
[
function
()
{
return
{
restrict
:
'A'
,
link
:
function
(
scope
,
element
,
attrs
)
{
var
menu
=
element
.
find
(
'ul'
);
element
.
find
(
'[dropdown-toggle]'
).
on
(
'click'
,
function
()
{
menu
.
show
().
addClass
(
'anim menuIn'
);
element
.
mouseleave
(
function
()
{
menu
.
hide
();
menu
.
removeClass
(
'anim menuIn'
);
});
});
}
};
}]);
};
\ No newline at end of file
...
...
resources/assets/js/global.js
View file @
46c2e8b
...
...
@@ -6,9 +6,32 @@ window.ZeroClipboard.config({
// AngularJS - Create application and load components
var
angular
=
require
(
'angular'
);
var
angularResource
=
require
(
'angular-resource'
);
var
app
=
angular
.
module
(
'bookStack'
,
[
'ngResource'
]);
var
directives
=
require
(
'./directives'
)(
app
);
var
ngResource
=
require
(
'angular-resource'
);
var
ngAnimate
=
require
(
'angular-animate'
);
var
ngSanitize
=
require
(
'angular-sanitize'
);
var
ngApp
=
angular
.
module
(
'bookStack'
,
[
'ngResource'
,
'ngAnimate'
,
'ngSanitize'
]);
var
services
=
require
(
'./services'
)(
ngApp
);
var
directives
=
require
(
'./directives'
)(
ngApp
);
var
controllers
=
require
(
'./controllers'
)(
ngApp
);
//Global jQuery Config & Extensions
// Smooth scrolling
jQuery
.
fn
.
smoothScrollTo
=
function
()
{
if
(
this
.
length
===
0
)
return
;
$
(
'body'
).
animate
({
scrollTop
:
this
.
offset
().
top
-
60
// Adjust to change final scroll position top margin
},
800
);
// Adjust to change animations speed (ms)
return
this
;
};
// Making contains text expression not worry about casing
$
.
expr
[
":"
].
contains
=
$
.
expr
.
createPseudo
(
function
(
arg
)
{
return
function
(
elem
)
{
return
$
(
elem
).
text
().
toUpperCase
().
indexOf
(
arg
.
toUpperCase
())
>=
0
;
};
});
// Global jQuery Elements
$
(
function
()
{
...
...
@@ -18,9 +41,6 @@ $(function () {
$
(
this
).
fadeOut
(
100
);
});
// Dropdown toggles
$
(
'[data-dropdown]'
).
dropDown
();
// Chapter page list toggles
$
(
'.chapter-toggle'
).
click
(
function
(
e
)
{
e
.
preventDefault
();
...
...
@@ -30,6 +50,11 @@ $(function () {
});
function
elemExists
(
selector
)
{
return
document
.
querySelector
(
selector
)
!==
null
;
}
// TinyMCE editor
if
(
elemExists
(
'#html-editor'
))
{
var
tinyMceOptions
=
require
(
'./pages/page-form'
);
...
...
resources/assets/js/jquery-extensions.js
deleted
100644 → 0
View file @
3347b3b
// Smooth scrolling
jQuery
.
fn
.
smoothScrollTo
=
function
()
{
if
(
this
.
length
===
0
)
return
;
$
(
'body'
).
animate
({
scrollTop
:
this
.
offset
().
top
-
60
// Adjust to change final scroll position top margin
},
800
);
// Adjust to change animations speed (ms)
return
this
;
};
// Making contains text expression not worry about casing
$
.
expr
[
":"
].
contains
=
$
.
expr
.
createPseudo
(
function
(
arg
)
{
return
function
(
elem
)
{
return
$
(
elem
).
text
().
toUpperCase
().
indexOf
(
arg
.
toUpperCase
())
>=
0
;
};
});
// Show a success message after the element it's called upon.
jQuery
.
fn
.
showSuccess
=
function
(
message
)
{
var
elem
=
$
(
this
);
var
success
=
$
(
'<div class="text-pos" style="display:none;"><i class="zmdi zmdi-check-circle"></i>'
+
message
+
'</div>'
);
elem
.
after
(
success
);
success
.
slideDown
(
400
,
function
()
{
setTimeout
(
function
()
{
success
.
slideUp
(
400
,
function
()
{
success
.
remove
();
})
},
2000
);
});
};
// Show a failure messages from laravel. Searches for the name of the inputs.
jQuery
.
fn
.
showFailure
=
function
(
messageMap
)
{
var
elem
=
$
(
this
);
$
.
each
(
messageMap
,
function
(
key
,
messages
)
{
var
input
=
elem
.
find
(
'[name="'
+
key
+
'"]'
).
last
();
var
fail
=
$
(
'<div class="text-neg" style="display:none;"><i class="zmdi zmdi-alert-circle"></i>'
+
messages
.
join
(
"\n"
)
+
'</div>'
);
input
.
after
(
fail
);
fail
.
slideDown
(
400
,
function
()
{
setTimeout
(
function
()
{
fail
.
slideUp
(
400
,
function
()
{
fail
.
remove
();
})
},
2000
);
});
});
};
// Submit the form that the called upon element sits in.
jQuery
.
fn
.
submitForm
=
function
()
{
$
(
this
).
closest
(
'form'
).
submit
();
};
// Dropdown menu display
jQuery
.
fn
.
dropDown
=
function
()
{
var
container
=
$
(
this
),
menu
=
container
.
find
(
'ul'
);
container
.
find
(
'[data-dropdown-toggle]'
).
on
(
'click'
,
function
()
{
menu
.
show
().
addClass
(
'anim menuIn'
);
container
.
mouseleave
(
function
()
{
menu
.
hide
();
menu
.
removeClass
(
'anim menuIn'
);
});
});
};
\ No newline at end of file
resources/assets/js/pages/book-show.js
deleted
100644 → 0
View file @
3347b3b
module
.
exports
=
{
el
:
'#book-dashboard'
,
data
:
{
searching
:
false
,
searchTerm
:
''
,
searchResults
:
''
},
methods
:
{
searchBook
:
function
(
e
)
{
e
.
preventDefault
();
var
term
=
this
.
searchTerm
;
if
(
term
.
length
==
0
)
return
;
this
.
searching
=
true
;
this
.
searchResults
=
''
;
var
searchUrl
=
this
.
$els
.
form
.
getAttribute
(
'action'
);
searchUrl
+=
'?term='
+
encodeURIComponent
(
term
);
this
.
$http
.
get
(
searchUrl
,
function
(
data
)
{
this
.
$set
(
'searchResults'
,
data
);
});
},
checkSearchForm
:
function
(
e
)
{
if
(
this
.
searchTerm
.
length
<
1
)
{
this
.
searching
=
false
;
}
},
clearSearch
:
function
(
e
)
{
this
.
searching
=
false
;
this
.
searchTerm
=
''
;
}
}
};
\ No newline at end of file
resources/assets/js/pages/page-form.js
View file @
46c2e8b
...
...
@@ -98,7 +98,7 @@ module.exports = {
icon
:
'image'
,
tooltip
:
'Insert an image'
,
onclick
:
function
()
{
ImageManager
.
show
(
function
(
image
)
{
window
.
ImageManager
.
showExternal
(
function
(
image
)
{
var
html
=
'<a href="'
+
image
.
url
+
'" target="_blank">'
;
html
+=
'<img src="'
+
image
.
thumbs
.
display
+
'" alt="'
+
image
.
name
+
'">'
;
html
+=
'</a>'
;
...
...
@@ -106,6 +106,7 @@ module.exports = {
});
}
});
// Paste image-uploads
editor
.
on
(
'paste'
,
function
(
e
)
{
if
(
e
.
clipboardData
)
{
...
...
resources/assets/js/services.js
0 → 100644
View file @
46c2e8b
"use strict"
;
module
.
exports
=
function
(
ngApp
)
{
ngApp
.
factory
(
'imageManagerService'
,
function
()
{
return
{
show
:
false
,
showExternal
:
false
};
});
};
\ No newline at end of file
resources/assets/sass/_image-manager.scss
View file @
46c2e8b
.overlay
{
background-color
:
rgba
(
0
,
0
,
0
,
0
.2
);
position
:
fixed
;
display
:
none
;
z-index
:
95536
;
width
:
100%
;
height
:
100%
;
...
...
resources/assets/sass/styles.scss
View file @
46c2e8b
...
...
@@ -18,6 +18,10 @@
[
v-cloak
],
[
v-show
]
{
display
:
none
;}
[
ng
\
:cloak
],
[
ng-cloak
],
.ng-cloak
{
display
:
none
!
important
;
}
// Jquery Sortable Styles
.dragged
{
position
:
absolute
;
...
...
resources/views/base.blade.php
View file @
46c2e8b
...
...
@@ -52,8 +52,8 @@
@endif
</div>
@if($signedIn)
<div
class=
"dropdown-container"
d
ata-d
ropdown
>
<span
class=
"user-name"
d
ata-d
ropdown-toggle
>
<div
class=
"dropdown-container"
dropdown
>
<span
class=
"user-name"
dropdown-toggle
>
<img
class=
"avatar"
src=
"{{$currentUser->getAvatar(30)}}"
alt=
"{{ $currentUser->name }}"
>
<span
class=
"name"
>
{{ $currentUser->name }}
</span>
<i
class=
"zmdi zmdi-caret-down"
></i>
</span>
...
...
resources/views/books/show.blade.php
View file @
46c2e8b
...
...
@@ -27,15 +27,15 @@
</div>
<div
class=
"container"
id=
"book-dashboard"
>
<div
class=
"container"
id=
"book-dashboard"
ng-controller=
"BookShowController"
book-id=
"{{ $book->id }}"
>
<div
class=
"row"
>
<div
class=
"col-md-7"
>
<h1>
{{$book->name}}
</h1>
<div
class=
"book-content
anim fadeIn"
v
-show=
"!searching"
>
<p
class=
"text-muted"
>
{{$book->description}}
</p>
<div
class=
"book-content
"
ng
-show=
"!searching"
>
<p
class=
"text-muted"
ng-non-bindable
>
{{$book->description}}
</p>
<div
class=
"page-list"
>
<div
class=
"page-list"
ng-non-bindable
>
<hr>
@if(count($bookChildren) > 0)
@foreach($bookChildren as $childElement)
...
...
@@ -62,12 +62,12 @@
</p>
</div>
</div>
<div
class=
"search-results"
v
-show=
"searching"
>
<h3
class=
"text-muted"
>
Search Results
<a
v-if=
"searching"
@
click=
"clearSearch
"
class=
"text-small"
><i
class=
"zmdi zmdi-close"
></i>
Clear Search
</a></h3>
<div
v
-if=
"!searchResults"
>
<div
class=
"search-results"
ng-cloak
ng
-show=
"searching"
>
<h3
class=
"text-muted"
>
Search Results
<a
ng-if=
"searching"
ng-click=
"clearSearch()
"
class=
"text-small"
><i
class=
"zmdi zmdi-close"
></i>
Clear Search
</a></h3>
<div
ng
-if=
"!searchResults"
>
@include('partials/loading-icon')
</div>
<div
v
-html=
"searchResults"
></div>
<div
ng-bind
-html=
"searchResults"
></div>
</div>
...
...
@@ -76,11 +76,10 @@
<div
class=
"col-md-4 col-md-offset-1"
>
<div
class=
"margin-top large"
></div>
<div
class=
"search-box"
>
<form
@
submit=
"searchBook"
@
input=
"checkSearchForm"
v-el:form
action=
"/search/book/{{ $book->id }}"
>
{!! csrf_field() !!}
<input
v-model=
"searchTerm"
type=
"text"
name=
"term"
placeholder=
"Search This Book"
>
<form
ng-submit=
"searchBook($event)"
>
<input
ng-model=
"searchTerm"
ng-change=
"checkSearchForm()"
type=
"text"
name=
"term"
placeholder=
"Search This Book"
>
<button
type=
"submit"
><i
class=
"zmdi zmdi-search"
></i></button>
<button
v-if=
"searching"
@
click=
"clearSearch
"
type=
"button"
><i
class=
"zmdi zmdi-close"
></i></button>
<button
ng-if=
"searching"
ng-click=
"clearSearch()
"
type=
"button"
><i
class=
"zmdi zmdi-close"
></i></button>
</form>
</div>
<div
class=
"activity anim fadeIn"
>
...
...
resources/views/books/sort.blade.php
View file @
46c2e8b
@extends('base')
@section('head')
<script
src=
"/libs/jquery-sortable/jquery-sortable.min.js"
></script>
@stop
@section('content')
<div
class=
"container"
>
...
...
resources/views/pages/create.blade.php
View file @
46c2e8b
...
...
@@ -16,5 +16,5 @@
@endif
</form>
</div>
<image-manager
image-type=
"gallery"
></image-manager>
@include('partials/image-manager', ['imageType' => 'gallery'])
@stop
\ No newline at end of file
...
...
resources/views/pages/edit.blade.php
View file @
46c2e8b
...
...
@@ -14,6 +14,6 @@
@include('pages/form', ['model' => $page])
</form>
</div>
<image-manager
image-type=
"gallery"
></image-manager>
@include('partials/image-manager', ['imageType' => 'gallery'])
@stop
\ No newline at end of file
...
...
resources/views/pages/page-display.blade.php
View file @
46c2e8b
<div
v-pr
e
>
<div
ng-non-bindabl
e
>
<h1
id=
"bkmrk-page-title"
>
{{$page->name}}
</h1>
{!! $page->html !!}
...
...
resources/views/partials/image-manager.blade.php
0 → 100644
View file @
46c2e8b
<div
id=
"image-manager"
image-type=
"{{ $imageType }}"
ng-controller=
"ImageManagerController"
>
<div
class=
"overlay anim-slide"
ng-show=
"showing"
ng-cloak
ng-click=
"hide()"
>
<div
class=
"image-manager-body"
ng-click=
"$event.stopPropagation()"
>
<div
class=
"image-manager-content"
>
<div
class=
"image-manager-list"
>
<div
ng-repeat=
"image in images"
>
<img
class=
"anim fadeIn"
ng-class=
"{selected: (image==selectedImage)}"
ng-src=
"@{{image.thumbs.gallery}}"
ng-attr-alt=
"@{{image.title}}"
ng-attr-title=
"@{{image.name}}"
ng-click=
"imageSelect(image)"
ng-style=
"{animationDelay: ($index > 26) ? '160ms' : ($index * 25) + 'ms'}"
>
</div>
<div
class=
"load-more"
ng-show=
"hasMore"
ng-click=
"fetchData()"
>
Load More
</div>
</div>
</div>
<button
class=
"neg button image-manager-close"
ng-click=
"hide()"
>
x
</button>
<div
class=
"image-manager-sidebar"
>
<h2>
Images
</h2>
<hr
class=
"even"
>
<drop-zone
upload-url=
"@{{getUploadUrl()}}"
event-success=
"uploadSuccess"
></drop-zone>
<div
class=
"image-manager-details anim fadeIn"
ng-show=
"selectedImage"
>
<hr
class=
"even"
>
<form
ng-submit=
"saveImageDetails($event)"
>
<div
class=
"form-group"
>
<label
for=
"name"
>
Image Name
</label>
<input
type=
"text"
id=
"name"
name=
"name"
ng-model=
"selectedImage.name"
>
<p
class=
"text-pos text-small"
ng-show=
"imageUpdateSuccess"
><i
class=
"fa fa-check"
></i>
Image name updated
</p>
<p
class=
"text-neg text-small"
ng-show=
"imageUpdateFailure"
><i
class=
"fa fa-times"
></i>
<span
ng-bind=
"imageUpdateFailure"
></span></p>
</div>
</form>
<hr
class=
"even"
>
<div
ng-show=
"dependantPages"
>
<p
class=
"text-neg text-small"
>
This image is used in the pages below, Click delete again to confirm you want to delete
this image.
</p>
<ul
class=
"text-neg"
>
<li
ng-repeat=
"page in dependantPages"
>
<a
ng-href=
"@{{ page.url }}"
target=
"_blank"
class=
"text-neg"
ng-bind=
"page.name"
></a>
</li>
</ul>
</div>
<form
ng-submit=
"deleteImage($event)"
>
<button
class=
"button neg"
><i
class=
"zmdi zmdi-delete"
></i>
Delete Image
</button>
</form>
</div>
<p
class=
"text-pos"
ng-show=
"imageDeleteSuccess"
><i
class=
"fa fa-check"
></i>
Image deleted
</p>
<div
class=
"image-manager-bottom"
>
<button
class=
"button pos anim fadeIn"
ng-show=
"selectedImage"
ng-click=
"selectButtonClick()"
>
<i
class=
"zmdi zmdi-square-right"
></i>
Select Image
</button>
</div>
</div>
</div>
</div>
</div>
\ No newline at end of file
resources/views/settings/index.blade.php
View file @
46c2e8b
...
...
@@ -33,7 +33,7 @@
<div
class=
"form-group"
id=
"logo-control"
>
<label
for=
"setting-app-logo"
>
Application Logo
</label>
<p
class=
"small"
>
This image should be 43px in height.
<br>
Large images will be scaled down.
</p>
<image-picker
resize-height=
"43"
resize-width=
"200"
current-image=
"{{ Setting::get('app-logo', '') }}"
default-image=
"/logo.png"
name=
"setting-app-logo"
image-class=
"logo-image"
></image-picker>
<image-picker
resize-height=
"43"
show-remove=
"true"
resize-width=
"200"
current-image=
"{{ Setting::get('app-logo', '') }}"
default-image=
"/logo.png"
name=
"setting-app-logo"
image-class=
"logo-image"
></image-picker>
</div>
</div>
</div>
...
...
@@ -86,6 +86,6 @@
</div>
<image-manager
image-type=
"system"
></image-manager>
@include('partials/image-manager', ['imageType' => 'system'])
@stop
...
...
resources/views/users/edit.blade.php
View file @
46c2e8b
...
...
@@ -33,7 +33,7 @@
<div
class=
"form-group"
id=
"logo-control"
>
<label
for=
"user-avatar"
>
User Avatar
</label>
<p
class=
"small"
>
This image should be approx 256px square.
</p>
<image-picker
resize-height=
"512"
resize-width=
"512"
current-image=
"{{ $user->getAvatar(80) }}"
current-id=
"{{ $user->image_id }}"
default-image=
"/user_avatar.png"
name=
"image_id"
show-remove=
"false"
image-class=
"
avatar large
"
></image-picker>
<image-picker
resize-height=
"512"
resize-width=
"512"
current-image=
"{{ $user->getAvatar(80) }}"
current-id=
"{{ $user->image_id }}"
default-image=
"/user_avatar.png"
name=
"image_id"
show-remove=
"false"
image-class=
"
['avatar' ,'large']
"
></image-picker>
</div>
</div>
</div>
...
...
@@ -79,5 +79,5 @@
</div>
<p
class=
"margin-top large"
><br></p>
<image-manager
image-type=
"user"
></image-manager>
@include('partials/image-manager', ['imageType' => 'user'])
@stop
...
...
Please
register
or
sign in
to post a comment