Code for making a Shortcut tool for your App
This allows the user to easily make shortcuts to urls they are on and give them names.
The Migration
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateShortcutsTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('shortcuts', function(Blueprint $table)
{
$table->string('id', 36)->primary();
$table->string('url');
$table->string('name');
$table->string('user_id', 36);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('shortcuts');
}
}
The Model
You will see me using scopes as I wanted to make a really simple POC
<?php
/**
* Created by PhpStorm.
* User: alfrednutile
* Date: 3/28/15
* Time: 8:28 PM
*/
namespace BehatEditor\Models;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
class Shortcut extends BaseModel {
public $incrementing = false;
public static $rulesCreate = [
'name' => 'required|min:3',
'url' => 'required'
];
protected $fillable = [
"id",
"url",
"name",
"user_id"
];
public function user()
{
return $this->belongsTo('BehatEditor\User');
}
public function scopeGetAllForCurrentUser($query)
{
return $query->where('user_id', Auth::user()->id)->get();
}
public function scopeDeleteForUser($query, $shortcut_id)
{
try
{
return ($results = $query->where('id', $shortcut_id)->where('user_id', Auth::user()->id)->first()) ? $results->delete() : false;
}
catch(\Exception $e)
{
throw new \Exception(sprintf("Could not delete the shortcut %s", $shortcut_id));
}
}
public function scopeCreateForUser($query, $input)
{
try
{
$uuid = $this->generateNewId()->toString();
$this->create(
[
'id' => (isset($input['id'])) ? $input['id'] : $uuid,
'url' => $input['url'],
'name' => $input['name'],
'user_id' => Auth::user()->id
]
);
return $uuid;
}
catch(\Exception $e)
{
$this->throw_and_log_error(sprintf("Error making shortcut %s", $e->getMessage()));
}
}
}
The Controller
Typically this is a no no too much logic in the controller.
<?php
/**
* Created by PhpStorm.
* User: alfrednutile
* Date: 3/28/15
* Time: 8:45 PM
*/
namespace BehatEditor\Http\Controllers;
use AlfredNutileInc\CoreApp\BaseController;
use BehatEditor\Models\Shortcut;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Validator;
class ShortcutsController extends BaseController {
public function getUserShortCuts()
{
try
{
$results['shortcuts'] = Shortcut::getAllForCurrentUser();
return Response::json($this->responseServices->respond($results, "Loaded Shortcuts"), 200);
}
catch(\Exception $e) {
return Response::json($this->responseServices->respond($e->getMessage(), sprintf("Error Getting Shortcuts Failed %s", $e->getMessage())), 422);
}
}
public function deleteUserShortCut($shortcut_id)
{
try
{
$results = Shortcut::deleteForUser($shortcut_id);
return Response::json($this->responseServices->respond($results, "Deleted Shortcut"), 200);
}
catch(\Exception $e) {
return Response::json($this->responseServices->respond($e->getMessage(), sprintf("Error Getting Shortcuts Failed %s", $e->getMessage())), 422);
}
}
public function postShortcut()
{
try
{
$input = $this->getInput();
$validator = Validator::make($input, Shortcut::$rulesCreate);
if(!$validator->passes()) {
return Response::json($this->responseServices->respond($validator->messages(), "Validation failed"), 422);
}
}
catch(\Exception $e)
{
Log::debug(sprintf("Error making shortcut during validaiton %s", $e->getMessage()));
return Response::json($this->responseServices->respond([], "Creation Error"), 500);
}
try
{
$results = Shortcut::createForUser($input);
return Response::json($this->responseServices->respond($results, "Created Shortcut"), 200);
}
catch(\Exception $e) {
return Response::json($this->responseServices->respond($e->getMessage(), sprintf("Error Getting Shortcuts Failed %s", $e->getMessage())), 422);
}
}
}
Then for the nav area
<li class="shortcut-form">
<form class="navbar-form navbar-left" role="shortcuts">
<div class="input-group">
<input
placeholder="shortcut name"
type="text"
class="form-control input-sm"
ng-model="main.shortcut_new.name">
<span class="input-group-btn">
<button
ng-disabled="!main.shortcut_new.name"
type="button"
class="btn btn-default"
ng-click="main.addShortCut()">
<i class="fa fa-plus-circle"></i>
</button>
</span>
</div>
</form>
</li>
<li class="dropdown">
<a class="dropdown-toggle" href="#">
<i class="fa fa-thumb-tack"></i>
Your Shortcuts<span class="caret"></span>
</a>
<ul class="dropdown-menu dropdown-messages">
<li>
<input
class="form-control"
type="text"
autofocus="{{ form_focus == 'nav' }}"
placeholder="Click Tab to enter mouse into input and search"
data-ng-model="search_shortcuts"
>
</li>
<li class="divider"></li>
<li ng-repeat="shortcut in main.shortcuts | filter:search_shortcuts">
<div class="dropdown-messages-box">
<div>
<span ng-bind-html="shortcut.shortcut"></span>
<a class="pull-right" href="#" ng-click="main.deleteShortcut(shortcut.id)">
<i class="fa fa-trash"></i>
</a>
</div>
</div>
<div class="divider"></div>
</li>
</ul>
</li>
The Angular
We have a MainController for initial app setup then after that ui-router has controllers.
Also you can get the shortcuts via a http request on page load. I just inject the initial load into the blade render. But either is fine really.
# controller.js
function addShortCut()
{
vm.shortcut_new.url = $location.url();
vm.ShortcutsService.create(vm.shortcut_new, vm.callbackCreateShortcutSuccess, vm.callbackShortcutError);
}
function loadShortcuts()
{
vm.shortcuts = [];
angular.forEach(vm.ENV.shortcuts, function(v,i){
var link = vm.makeLink(v);
vm.shortcuts.push( { "id": v.id, "shortcut": link } );
});
}
function deleteShortcut(id)
{
vm.shortcut_to_delete = id;
vm.ShortcutsService.deleteShortcut(id, vm.callbackShortcutSuccess, vm.callbackShortcutError);
}
function callbackShortcutSuccess(response)
{
vm._.remove(vm.shortcuts, function(s) {
return s.id == vm.shortcut_to_delete;
});
vm.toaster.pop("success", "Success updating shortcut");
}
function callbackCreateShortcutSuccess(response)
{
vm.shortcut_new.id = response.data;
var link = vm.makeLink(vm.shortcut_new);
vm.shortcuts.push( { "id": vm.shortcut_new.id, "shortcut": link } );
vm.shortcut_new = {};
vm.toaster.pop('info', "Success creating shortcut");
}
function makeLink(shortcut)
{
return "<a href='/behat#" + shortcut.url + "'>" + shortcut.name + "</a>";
}
function callbackShortcutError(response)
{
vm.toaster.pop("error", "Error updating your shortcut");
}
The Behat API Tests
@api
Feature: Shortcuts
Shortcuts for quick access
As an authenticated user
So I can make and use shortcuts to get from place to place
Background: Login
Given I do basic auth on behat
Scenario: Get My Shortcuts
When I request "GET /api/v1/shortcuts"
Then I get a "200" response
And scope into the "data.shortcuts.0" property
And the properties exist:
"""
url
user_id
"""
Scenario: Delete My Shortcuts
When I request "DELETE /api/v1/shortcuts/mock-shortcut-5"
Then I get a "200" response
Scenario: Can Create a Shortcut
Given I reseed the database
Given I have the payload:
"""
{ "data":
{
"name": "New ShortCut",
"url": "/dashboard"
}
}
"""
When I request "POST /api/v1/shortcuts"
Then I get a "200" response
comments powered by Disqus