From 1fa079b46626b5cbb3d1b055542e4a98b4b0ca0a Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Thu, 12 May 2016 23:12:05 +0100 Subject: [PATCH] Started the page attributes interface --- app/Attribute.php | 2 +- app/Http/Controllers/AttributeController.php | 11 +-- app/Http/Controllers/PageController.php | 2 +- app/Repos/AttributeRepo.php | 1 + ...6_05_06_185215_create_attributes_table.php | 2 + resources/assets/js/controllers.js | 94 ++++++++++++++++++- resources/assets/sass/styles.scss | 14 +++ resources/views/pages/create.blade.php | 17 ---- resources/views/pages/edit.blade.php | 17 +++- resources/views/pages/form.blade.php | 1 + tests/Entity/AttributeTests.php | 25 +++-- 11 files changed, 152 insertions(+), 34 deletions(-) delete mode 100644 resources/views/pages/create.blade.php diff --git a/app/Attribute.php b/app/Attribute.php index 62dc62be7..3fe201a42 100644 --- a/app/Attribute.php +++ b/app/Attribute.php @@ -6,7 +6,7 @@ */ class Attribute extends Model { - protected $fillable = ['name', 'value']; + protected $fillable = ['name', 'value', 'order']; /** * Get the entity that this attribute belongs to diff --git a/app/Http/Controllers/AttributeController.php b/app/Http/Controllers/AttributeController.php index d7282696a..6e6913722 100644 --- a/app/Http/Controllers/AttributeController.php +++ b/app/Http/Controllers/AttributeController.php @@ -38,18 +38,15 @@ class AttributeController extends Controller */ public function updateForEntity($entityType, $entityId, Request $request) { - - $this->validate($request, [ - 'attributes.*.name' => 'required|min:3|max:250', - 'attributes.*.value' => 'max:250' - ]); - $entity = $this->attributeRepo->getEntity($entityType, $entityId, 'update'); if ($entity === null) return $this->jsonError("Entity not found", 404); $inputAttributes = $request->input('attributes'); $attributes = $this->attributeRepo->saveAttributesToEntity($entity, $inputAttributes); - return response()->json($attributes); + return response()->json([ + 'attributes' => $attributes, + 'message' => 'Attributes successfully updated' + ]); } /** diff --git a/app/Http/Controllers/PageController.php b/app/Http/Controllers/PageController.php index 19e5632a4..da9273743 100644 --- a/app/Http/Controllers/PageController.php +++ b/app/Http/Controllers/PageController.php @@ -72,7 +72,7 @@ class PageController extends Controller $this->checkOwnablePermission('page-create', $book); $this->setPageTitle('Edit Page Draft'); - return view('pages/create', ['draft' => $draft, 'book' => $book]); + return view('pages/edit', ['page' => $draft, 'book' => $book, 'isDraft' => true]); } /** diff --git a/app/Repos/AttributeRepo.php b/app/Repos/AttributeRepo.php index 7318b253b..fb742b2d8 100644 --- a/app/Repos/AttributeRepo.php +++ b/app/Repos/AttributeRepo.php @@ -80,6 +80,7 @@ class AttributeRepo $entity->attributes()->delete(); $newAttributes = []; foreach ($attributes as $attribute) { + if (trim($attribute['name']) === '') continue; $newAttributes[] = $this->newInstanceFromInput($attribute); } diff --git a/database/migrations/2016_05_06_185215_create_attributes_table.php b/database/migrations/2016_05_06_185215_create_attributes_table.php index df3e55421..b6412037c 100644 --- a/database/migrations/2016_05_06_185215_create_attributes_table.php +++ b/database/migrations/2016_05_06_185215_create_attributes_table.php @@ -18,10 +18,12 @@ class CreateAttributesTable extends Migration $table->string('entity_type', 100); $table->string('name'); $table->string('value'); + $table->integer('order'); $table->timestamps(); $table->index('name'); $table->index('value'); + $table->index('order'); $table->index(['entity_id', 'entity_type']); }); } diff --git a/resources/assets/js/controllers.js b/resources/assets/js/controllers.js index 8b3d952be..e73efaac9 100644 --- a/resources/assets/js/controllers.js +++ b/resources/assets/js/controllers.js @@ -400,4 +400,96 @@ module.exports = function (ngApp, events) { }]); -}; \ No newline at end of file + ngApp.controller('PageAttributeController', ['$scope', '$http', '$attrs', + function ($scope, $http, $attrs) { + + const pageId = Number($attrs.pageId); + $scope.attributes = []; + + /** + * Push an empty attribute to the end of the scope attributes. + */ + function addEmptyAttribute() { + $scope.attributes.push({ + name: '', + value: '' + }); + } + + /** + * Get all attributes for the current book and add into scope. + */ + function getAttributes() { + $http.get('/ajax/attributes/get/page/' + pageId).then((responseData) => { + $scope.attributes = responseData.data; + addEmptyAttribute(); + }); + } + getAttributes(); + + /** + * Set the order property on all attributes. + */ + function setAttributeOrder() { + for (let i = 0; i < $scope.attributes.length; i++) { + $scope.attributes[i].order = i; + } + } + + /** + * When an attribute changes check if another empty editable + * field needs to be added onto the end. + * @param attribute + */ + $scope.attributeChange = function(attribute) { + let cPos = $scope.attributes.indexOf(attribute); + if (cPos !== $scope.attributes.length-1) return; + + if (attribute.name !== '' || attribute.value !== '') { + addEmptyAttribute(); + } + }; + + /** + * When an attribute field loses focus check the attribute to see if its + * empty and therefore could be removed from the list. + * @param attribute + */ + $scope.attributeBlur = function(attribute) { + let isLast = $scope.attributes.length - 1 === $scope.attributes.indexOf(attribute); + if (attribute.name === '' && attribute.value === '' && !isLast) { + let cPos = $scope.attributes.indexOf(attribute); + $scope.attributes.splice(cPos, 1); + } + }; + + $scope.saveAttributes = function() { + setAttributeOrder(); + let postData = {attributes: $scope.attributes}; + $http.post('/ajax/attributes/update/page/' + pageId, postData).then((responseData) => { + $scope.attributes = responseData.data.attributes; + addEmptyAttribute(); + events.emit('success', responseData.data.message); + }) + }; + + }]); + +}; + + + + + + + + + + + + + + + + + diff --git a/resources/assets/sass/styles.scss b/resources/assets/sass/styles.scss index d8453b9ed..4b6b1cc46 100644 --- a/resources/assets/sass/styles.scss +++ b/resources/assets/sass/styles.scss @@ -201,4 +201,18 @@ $btt-size: 40px; background-color: $negative; color: #EEE; } +} + +// Attribute form +.floating-toolbox { + background-color: #FFF; + border: 1px solid #BBB; + border-radius: 3px; + padding: $-l; + position: fixed; + right: $-xl*2; + top: 100px; + z-index: 99; + height: 800px; + overflow-y: scroll; } \ No newline at end of file diff --git a/resources/views/pages/create.blade.php b/resources/views/pages/create.blade.php deleted file mode 100644 index 2c6403e48..000000000 --- a/resources/views/pages/create.blade.php +++ /dev/null @@ -1,17 +0,0 @@ -@extends('base') - -@section('head') - -@stop - -@section('body-class', 'flexbox') - -@section('content') - -
-
- @include('pages/form', ['model' => $draft]) -
-
- @include('partials/image-manager', ['imageType' => 'gallery', 'uploaded_to' => $draft->id]) -@stop \ No newline at end of file diff --git a/resources/views/pages/edit.blade.php b/resources/views/pages/edit.blade.php index 0ad06fc53..a536ad23e 100644 --- a/resources/views/pages/edit.blade.php +++ b/resources/views/pages/edit.blade.php @@ -10,9 +10,24 @@
- + @if(!isset($isDraft)) + + @endif @include('pages/form', ['model' => $page])
+ +
+
+ + + + + +
+ +
+
+
@include('partials/image-manager', ['imageType' => 'gallery', 'uploaded_to' => $page->id]) diff --git a/resources/views/pages/form.blade.php b/resources/views/pages/form.blade.php index 7ce9dbfe5..aa05a9014 100644 --- a/resources/views/pages/form.blade.php +++ b/resources/views/pages/form.blade.php @@ -41,6 +41,7 @@ @include('form/text', ['name' => 'name', 'placeholder' => 'Page Title']) +
@if(setting('app-editor') === 'wysiwyg')