A ton of progress, search start
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
bed34d5350
commit
d086b29bcc
@ -4,15 +4,13 @@ namespace App\Http\Controllers;
|
|||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class BookController extends Controller
|
class BookController extends Controller {
|
||||||
{
|
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Http\Response
|
* @return \Illuminate\Http\Response
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index() {
|
||||||
{
|
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,8 +19,7 @@ class BookController extends Controller
|
|||||||
*
|
*
|
||||||
* @return \Illuminate\Http\Response
|
* @return \Illuminate\Http\Response
|
||||||
*/
|
*/
|
||||||
public function create()
|
public function create() {
|
||||||
{
|
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,8 +29,7 @@ class BookController extends Controller
|
|||||||
* @param \Illuminate\Http\Request $request
|
* @param \Illuminate\Http\Request $request
|
||||||
* @return \Illuminate\Http\Response
|
* @return \Illuminate\Http\Response
|
||||||
*/
|
*/
|
||||||
public function store(Request $request)
|
public function store(Request $request) {
|
||||||
{
|
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,8 +39,7 @@ class BookController extends Controller
|
|||||||
* @param int $id
|
* @param int $id
|
||||||
* @return \Illuminate\Http\Response
|
* @return \Illuminate\Http\Response
|
||||||
*/
|
*/
|
||||||
public function show($id)
|
public function show($id) {
|
||||||
{
|
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,8 +49,7 @@ class BookController extends Controller
|
|||||||
* @param int $id
|
* @param int $id
|
||||||
* @return \Illuminate\Http\Response
|
* @return \Illuminate\Http\Response
|
||||||
*/
|
*/
|
||||||
public function edit($id)
|
public function edit($id) {
|
||||||
{
|
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,8 +60,7 @@ class BookController extends Controller
|
|||||||
* @param int $id
|
* @param int $id
|
||||||
* @return \Illuminate\Http\Response
|
* @return \Illuminate\Http\Response
|
||||||
*/
|
*/
|
||||||
public function update(Request $request, $id)
|
public function update(Request $request, $id) {
|
||||||
{
|
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,8 +70,7 @@ class BookController extends Controller
|
|||||||
* @param int $id
|
* @param int $id
|
||||||
* @return \Illuminate\Http\Response
|
* @return \Illuminate\Http\Response
|
||||||
*/
|
*/
|
||||||
public function destroy($id)
|
public function destroy($id) {
|
||||||
{
|
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\Location;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class LocationController extends Controller {
|
class LocationController extends Controller {
|
||||||
@ -37,10 +38,16 @@ class LocationController extends Controller {
|
|||||||
* Display the specified resource.
|
* Display the specified resource.
|
||||||
*
|
*
|
||||||
* @param int $id
|
* @param int $id
|
||||||
* @return \Illuminate\Http\Response
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function show($id) {
|
public function show($id) {
|
||||||
//
|
$location = Location::find($id);
|
||||||
|
|
||||||
|
if (!$location) {
|
||||||
|
abort(404);
|
||||||
|
}
|
||||||
|
|
||||||
|
return view('location', [ 'location' => $location ]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,12 +2,73 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\Author;
|
||||||
|
use App\Models\Book;
|
||||||
|
use App\Models\Location;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
class MainController extends Controller {
|
class MainController extends Controller {
|
||||||
public function index() {
|
public function index() {
|
||||||
return view('welcome');
|
$rows = Book::paginate(15);
|
||||||
|
|
||||||
|
return view('index', [ 'rows' => $rows ]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function add() {
|
public function search(Request $request) {
|
||||||
return view('add');
|
$this->validate($request, [
|
||||||
|
'query' => [ 'required' ]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$rows = Book::where('name', 'LIKE', '%' . $request->get('query') . '%')->paginate(15);
|
||||||
|
|
||||||
|
return view('index', [ 'rows' => $rows ]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function add(Request $request) {
|
||||||
|
return view('add', [
|
||||||
|
'old' => array_filter($request->old('books', []), function($item) {
|
||||||
|
return !empty($item['barcode']);
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save(Request $request) {
|
||||||
|
$this->validate($request, [
|
||||||
|
'location' => [ 'required' ]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$input = array_filter($request->get('books'), function($item) {
|
||||||
|
return !empty($item['barcode']) && !empty($item['name']);
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->getValidationFactory()->make($input, [
|
||||||
|
'*.barcode' => [ 'required' ],
|
||||||
|
'*.name' => [ 'required' ]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$location = Location::firstOrCreate([
|
||||||
|
'name' => trim($request->get('location'))
|
||||||
|
]);
|
||||||
|
|
||||||
|
foreach ($input as $item) {
|
||||||
|
$book = Book::create([
|
||||||
|
'location_id' => $location->id,
|
||||||
|
'barcode' => $item['barcode'],
|
||||||
|
'name' => $item['name']
|
||||||
|
]);
|
||||||
|
|
||||||
|
$authors = [];
|
||||||
|
|
||||||
|
foreach (Arr::get($item, 'authors') as $author) {
|
||||||
|
$authors[] = Author::firstOrCreate([
|
||||||
|
'name' => $author
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$authors = array_map(function($author) { return $author->id; }, $authors);
|
||||||
|
|
||||||
|
$book->authors()->attach($authors);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
class Author extends Authenticatable {
|
class Author extends Model {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
|
@ -2,9 +2,15 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use App\Services\Search\BookConfigurator;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use ScoutElastic\Searchable;
|
||||||
|
|
||||||
class Book extends Authenticatable {
|
class Book extends Model {
|
||||||
|
|
||||||
|
use Searchable;
|
||||||
|
|
||||||
|
protected $indexConfigurator = BookConfigurator::class;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
@ -12,14 +18,28 @@ class Book extends Authenticatable {
|
|||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'name',
|
'location_id', 'barcode', 'name',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function author() {
|
public function authors() {
|
||||||
return $this->hasMany(Author::class);
|
return $this->belongsToMany(Author::class, 'book_authors');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function location() {
|
public function location() {
|
||||||
return $this->belongsTo(Location::class);
|
return $this->belongsTo(Location::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected $mapping = [
|
||||||
|
'properties' => [
|
||||||
|
'name' => [
|
||||||
|
'type' => 'text',
|
||||||
|
// Also you can configure multi-fields, more details you can find here https://www.elastic.co/guide/en/elasticsearch/reference/current/multi-fields.html
|
||||||
|
'fields' => [
|
||||||
|
'raw' => [
|
||||||
|
'type' => 'keyword',
|
||||||
|
]
|
||||||
|
]
|
||||||
|
],
|
||||||
|
]
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
class Location extends Authenticatable {
|
class Location extends Model {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
|
22
app/Services/Search/BookConfigurator.php
Normal file
22
app/Services/Search/BookConfigurator.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\Services\Search;
|
||||||
|
|
||||||
|
use ScoutElastic\IndexConfigurator;
|
||||||
|
|
||||||
|
class BookConfigurator extends IndexConfigurator
|
||||||
|
{
|
||||||
|
// It's not obligatory to determine name. By default it'll be a snaked class name without `IndexConfigurator` part.
|
||||||
|
protected $name = 'books';
|
||||||
|
|
||||||
|
// You can specify any settings you want, for example, analyzers.
|
||||||
|
protected $settings = [
|
||||||
|
'analysis' => [
|
||||||
|
'analyzer' => [
|
||||||
|
'es_std' => [
|
||||||
|
'type' => 'standard',
|
||||||
|
'stopwords' => '_spanish_'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
@ -6,15 +6,16 @@
|
|||||||
"type": "project",
|
"type": "project",
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.3|^8.0",
|
"php": "^7.3|^8.0",
|
||||||
|
"babenkoivan/scout-elasticsearch-driver": "^4.2",
|
||||||
"fideloper/proxy": "^4.4",
|
"fideloper/proxy": "^4.4",
|
||||||
"fruitcake/laravel-cors": "^2.0",
|
"fruitcake/laravel-cors": "^2.0",
|
||||||
"google/apiclient": "^2.2",
|
"google/apiclient": "^2.2",
|
||||||
"guzzlehttp/guzzle": "^7.0.1",
|
"guzzlehttp/guzzle": "^7.0.1",
|
||||||
"laravel/framework": "^8.12",
|
"laravel/framework": "^8.12",
|
||||||
|
"laravel/scout": "^8.5",
|
||||||
"laravel/tinker": "^2.5",
|
"laravel/tinker": "^2.5",
|
||||||
"laravel/ui": "^3.0",
|
"laravel/ui": "^3.0",
|
||||||
"sunra/php-simple-html-dom-parser": "^1.5",
|
"sunra/php-simple-html-dom-parser": "^1.5"
|
||||||
"yajra/laravel-datatables-oracle": "^9.0"
|
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"facade/ignition": "^2.5",
|
"facade/ignition": "^2.5",
|
||||||
|
1461
composer.lock
generated
1461
composer.lock
generated
File diff suppressed because it is too large
Load Diff
32
package.json
32
package.json
@ -2,20 +2,32 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "npm run development",
|
"dev": "npm run development",
|
||||||
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
|
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||||
"watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
|
"watch": "npm run development -- --watch",
|
||||||
"watch-poll": "npm run watch -- --watch-poll",
|
"watch-poll": "npm run watch -- --watch-poll",
|
||||||
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
|
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --disable-host-check --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||||
"prod": "npm run production",
|
"prod": "npm run production",
|
||||||
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
|
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --config=node_modules/laravel-mix/setup/webpack.config.js"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"axios": "^0.17",
|
"@ttskch/select2-bootstrap4-theme": "^1.3.4",
|
||||||
"bootstrap-sass": "^3.3.7",
|
"axios": "^0.19",
|
||||||
"cross-env": "^5.1",
|
"bootstrap": "^4.0.0",
|
||||||
|
"cross-env": "^7.0",
|
||||||
|
"datatables.net-bs4": "^1.10.23",
|
||||||
|
"datatables.net-buttons-bs4": "^1.6.5",
|
||||||
"jquery": "^3.2",
|
"jquery": "^3.2",
|
||||||
"laravel-mix": "^1.0",
|
"laravel-mix": "^5.0.1",
|
||||||
"lodash": "^4.17.4",
|
"lodash": "^4.17.19",
|
||||||
"vue": "^2.5.7"
|
"popper.js": "^1.12",
|
||||||
|
"resolve-url-loader": "^2.3.1",
|
||||||
|
"sass": "^1.20.1",
|
||||||
|
"sass-loader": "^8.0.0",
|
||||||
|
"select2": "^4.0.13",
|
||||||
|
"vue": "^2.5.17",
|
||||||
|
"vue-template-compiler": "^2.6.10"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"vue-router": "^3.4.9"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
11287
public/css/app.css
vendored
11287
public/css/app.css
vendored
File diff suppressed because it is too large
Load Diff
2359
public/css/bootstrap-grid.css
vendored
2359
public/css/bootstrap-grid.css
vendored
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
10
public/css/bootstrap-grid.min.css
vendored
10
public/css/bootstrap-grid.min.css
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
88
public/css/bootstrap-reboot.css
vendored
88
public/css/bootstrap-reboot.css
vendored
@ -1,8 +1,8 @@
|
|||||||
/*!
|
/*!
|
||||||
* Bootstrap Reboot v4.0.0-beta.2 (https://getbootstrap.com)
|
* Bootstrap Reboot v4.5.3 (https://getbootstrap.com/)
|
||||||
* Copyright 2011-2017 The Bootstrap Authors
|
* Copyright 2011-2020 The Bootstrap Authors
|
||||||
* Copyright 2011-2017 Twitter, Inc.
|
* Copyright 2011-2020 Twitter, Inc.
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||||
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
||||||
*/
|
*/
|
||||||
*,
|
*,
|
||||||
@ -15,22 +15,16 @@ html {
|
|||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
line-height: 1.15;
|
line-height: 1.15;
|
||||||
-webkit-text-size-adjust: 100%;
|
-webkit-text-size-adjust: 100%;
|
||||||
-ms-text-size-adjust: 100%;
|
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||||
-ms-overflow-style: scrollbar;
|
|
||||||
-webkit-tap-highlight-color: transparent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@-ms-viewport {
|
article, aside, figcaption, figure, footer, header, hgroup, main, nav, section {
|
||||||
width: device-width;
|
|
||||||
}
|
|
||||||
|
|
||||||
article, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section {
|
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
@ -39,8 +33,8 @@ body {
|
|||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
[tabindex="-1"]:focus {
|
[tabindex="-1"]:focus:not(:focus-visible) {
|
||||||
outline: none !important;
|
outline: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr {
|
hr {
|
||||||
@ -66,6 +60,8 @@ abbr[data-original-title] {
|
|||||||
text-decoration: underline dotted;
|
text-decoration: underline dotted;
|
||||||
cursor: help;
|
cursor: help;
|
||||||
border-bottom: 0;
|
border-bottom: 0;
|
||||||
|
-webkit-text-decoration-skip-ink: none;
|
||||||
|
text-decoration-skip-ink: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
address {
|
address {
|
||||||
@ -101,10 +97,6 @@ blockquote {
|
|||||||
margin: 0 0 1rem;
|
margin: 0 0 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
dfn {
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
b,
|
b,
|
||||||
strong {
|
strong {
|
||||||
font-weight: bolder;
|
font-weight: bolder;
|
||||||
@ -134,7 +126,6 @@ a {
|
|||||||
color: #007bff;
|
color: #007bff;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
-webkit-text-decoration-skip: objects;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
a:hover {
|
a:hover {
|
||||||
@ -142,25 +133,21 @@ a:hover {
|
|||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:not([href]):not([tabindex]) {
|
a:not([href]):not([class]) {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:not([href]):not([tabindex]):focus, a:not([href]):not([tabindex]):hover {
|
a:not([href]):not([class]):hover {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:not([href]):not([tabindex]):focus {
|
|
||||||
outline: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre,
|
pre,
|
||||||
code,
|
code,
|
||||||
kbd,
|
kbd,
|
||||||
samp {
|
samp {
|
||||||
font-family: monospace, monospace;
|
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,21 +167,9 @@ img {
|
|||||||
border-style: none;
|
border-style: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
svg:not(:root) {
|
svg {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
vertical-align: middle;
|
||||||
|
|
||||||
a,
|
|
||||||
area,
|
|
||||||
button,
|
|
||||||
[role="button"],
|
|
||||||
input:not([type="range"]),
|
|
||||||
label,
|
|
||||||
select,
|
|
||||||
summary,
|
|
||||||
textarea {
|
|
||||||
-ms-touch-action: manipulation;
|
|
||||||
touch-action: manipulation;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
table {
|
table {
|
||||||
@ -204,18 +179,19 @@ table {
|
|||||||
caption {
|
caption {
|
||||||
padding-top: 0.75rem;
|
padding-top: 0.75rem;
|
||||||
padding-bottom: 0.75rem;
|
padding-bottom: 0.75rem;
|
||||||
color: #868e96;
|
color: #6c757d;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
caption-side: bottom;
|
caption-side: bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
th {
|
th {
|
||||||
text-align: inherit;
|
text-align: inherit;
|
||||||
|
text-align: -webkit-match-parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
label {
|
label {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-bottom: .5rem;
|
margin-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
@ -248,13 +224,28 @@ select {
|
|||||||
text-transform: none;
|
text-transform: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[role="button"] {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
word-wrap: normal;
|
||||||
|
}
|
||||||
|
|
||||||
button,
|
button,
|
||||||
html [type="button"],
|
[type="button"],
|
||||||
[type="reset"],
|
[type="reset"],
|
||||||
[type="submit"] {
|
[type="submit"] {
|
||||||
-webkit-appearance: button;
|
-webkit-appearance: button;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button:not(:disabled),
|
||||||
|
[type="button"]:not(:disabled),
|
||||||
|
[type="reset"]:not(:disabled),
|
||||||
|
[type="submit"]:not(:disabled) {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
button::-moz-focus-inner,
|
button::-moz-focus-inner,
|
||||||
[type="button"]::-moz-focus-inner,
|
[type="button"]::-moz-focus-inner,
|
||||||
[type="reset"]::-moz-focus-inner,
|
[type="reset"]::-moz-focus-inner,
|
||||||
@ -269,13 +260,6 @@ input[type="checkbox"] {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="date"],
|
|
||||||
input[type="time"],
|
|
||||||
input[type="datetime-local"],
|
|
||||||
input[type="month"] {
|
|
||||||
-webkit-appearance: listbox;
|
|
||||||
}
|
|
||||||
|
|
||||||
textarea {
|
textarea {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
resize: vertical;
|
resize: vertical;
|
||||||
@ -314,7 +298,6 @@ progress {
|
|||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
[type="search"]::-webkit-search-cancel-button,
|
|
||||||
[type="search"]::-webkit-search-decoration {
|
[type="search"]::-webkit-search-decoration {
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
}
|
}
|
||||||
@ -330,6 +313,7 @@ output {
|
|||||||
|
|
||||||
summary {
|
summary {
|
||||||
display: list-item;
|
display: list-item;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
template {
|
template {
|
||||||
|
File diff suppressed because one or more lines are too long
10
public/css/bootstrap-reboot.min.css
vendored
10
public/css/bootstrap-reboot.min.css
vendored
@ -1,8 +1,8 @@
|
|||||||
/*!
|
/*!
|
||||||
* Bootstrap Reboot v4.0.0-beta.2 (https://getbootstrap.com)
|
* Bootstrap Reboot v4.5.3 (https://getbootstrap.com/)
|
||||||
* Copyright 2011-2017 The Bootstrap Authors
|
* Copyright 2011-2020 The Bootstrap Authors
|
||||||
* Copyright 2011-2017 Twitter, Inc.
|
* Copyright 2011-2020 Twitter, Inc.
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||||
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
||||||
*/*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}@-ms-viewport{width:device-width}article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg:not(:root){overflow:hidden}[role=button],a,area,button,input:not([type=range]),label,select,summary,textarea{-ms-touch-action:manipulation;touch-action:manipulation}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#868e96;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item}template{display:none}[hidden]{display:none!important}
|
*/*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([class]){color:inherit;text-decoration:none}a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}
|
||||||
/*# sourceMappingURL=bootstrap-reboot.min.css.map */
|
/*# sourceMappingURL=bootstrap-reboot.min.css.map */
|
File diff suppressed because one or more lines are too long
4485
public/css/bootstrap.css
vendored
4485
public/css/bootstrap.css
vendored
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
10
public/css/bootstrap.min.css
vendored
10
public/css/bootstrap.min.css
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
61309
public/js/app.js
vendored
61309
public/js/app.js
vendored
File diff suppressed because it is too large
Load Diff
3882
public/js/bootstrap.bundle.js
vendored
3882
public/js/bootstrap.bundle.js
vendored
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
8
public/js/bootstrap.bundle.min.js
vendored
8
public/js/bootstrap.bundle.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
3342
public/js/bootstrap.js
vendored
3342
public/js/bootstrap.js
vendored
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
8
public/js/bootstrap.min.js
vendored
8
public/js/bootstrap.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
22
resources/assets/js/app.js
vendored
22
resources/assets/js/app.js
vendored
@ -1,22 +0,0 @@
|
|||||||
|
|
||||||
/**
|
|
||||||
* First we will load all of this project's JavaScript dependencies which
|
|
||||||
* includes Vue and other libraries. It is a great starting point when
|
|
||||||
* building robust, powerful web applications using Vue and Laravel.
|
|
||||||
*/
|
|
||||||
|
|
||||||
require('./bootstrap');
|
|
||||||
|
|
||||||
window.Vue = require('vue');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Next, we will create a fresh Vue application instance and attach it to
|
|
||||||
* the page. Then, you may begin adding components to this application
|
|
||||||
* or customize the JavaScript scaffolding to fit your unique needs.
|
|
||||||
*/
|
|
||||||
|
|
||||||
Vue.component('example-component', require('./components/ExampleComponent.vue'));
|
|
||||||
|
|
||||||
const app = new Vue({
|
|
||||||
el: '#app'
|
|
||||||
});
|
|
@ -1,23 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-8 col-md-offset-2">
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading">Example Component</div>
|
|
||||||
|
|
||||||
<div class="panel-body">
|
|
||||||
I'm an example component!
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
mounted() {
|
|
||||||
console.log('Component mounted.')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
38
resources/assets/sass/_variables.scss
vendored
38
resources/assets/sass/_variables.scss
vendored
@ -1,38 +0,0 @@
|
|||||||
|
|
||||||
// Body
|
|
||||||
$body-bg: #f5f8fa;
|
|
||||||
|
|
||||||
// Borders
|
|
||||||
$laravel-border-color: darken($body-bg, 10%);
|
|
||||||
$list-group-border: $laravel-border-color;
|
|
||||||
$navbar-default-border: $laravel-border-color;
|
|
||||||
$panel-default-border: $laravel-border-color;
|
|
||||||
$panel-inner-border: $laravel-border-color;
|
|
||||||
|
|
||||||
// Brands
|
|
||||||
$brand-primary: #3097D1;
|
|
||||||
$brand-info: #8eb4cb;
|
|
||||||
$brand-success: #2ab27b;
|
|
||||||
$brand-warning: #cbb956;
|
|
||||||
$brand-danger: #bf5329;
|
|
||||||
|
|
||||||
// Typography
|
|
||||||
$icon-font-path: "~bootstrap-sass/assets/fonts/bootstrap/";
|
|
||||||
$font-family-sans-serif: "Raleway", sans-serif;
|
|
||||||
$font-size-base: 14px;
|
|
||||||
$line-height-base: 1.6;
|
|
||||||
$text-color: #636b6f;
|
|
||||||
|
|
||||||
// Navbar
|
|
||||||
$navbar-default-bg: #fff;
|
|
||||||
|
|
||||||
// Buttons
|
|
||||||
$btn-default-color: $text-color;
|
|
||||||
|
|
||||||
// Inputs
|
|
||||||
$input-border: lighten($text-color, 40%);
|
|
||||||
$input-border-focus: lighten($brand-primary, 25%);
|
|
||||||
$input-color-placeholder: lighten($text-color, 30%);
|
|
||||||
|
|
||||||
// Panels
|
|
||||||
$panel-default-heading-bg: #fff;
|
|
9
resources/assets/sass/app.scss
vendored
9
resources/assets/sass/app.scss
vendored
@ -1,9 +0,0 @@
|
|||||||
|
|
||||||
// Fonts
|
|
||||||
@import url("https://fonts.googleapis.com/css?family=Raleway:300,400,600");
|
|
||||||
|
|
||||||
// Variables
|
|
||||||
@import "variables";
|
|
||||||
|
|
||||||
// Bootstrap
|
|
||||||
@import "~bootstrap-sass/assets/stylesheets/bootstrap";
|
|
133
resources/js/app.js
vendored
Normal file
133
resources/js/app.js
vendored
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* First we will load all of this project's JavaScript dependencies which
|
||||||
|
* includes Vue and other libraries. It is a great starting point when
|
||||||
|
* building robust, powerful web applications using Vue and Laravel.
|
||||||
|
*/
|
||||||
|
|
||||||
|
require('./bootstrap');
|
||||||
|
|
||||||
|
$(document).ready(function(e) {
|
||||||
|
|
||||||
|
$.fn.dataTable.render.authorValue = function(_, context, book) {
|
||||||
|
let authors = [];
|
||||||
|
|
||||||
|
console.log(book);
|
||||||
|
for (let author of book.authors) {
|
||||||
|
authors.push(author.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return authors.join(', ');
|
||||||
|
};
|
||||||
|
|
||||||
|
var authorOptions = {
|
||||||
|
placeholder: 'Authors',
|
||||||
|
tags: true,
|
||||||
|
ajax: {
|
||||||
|
url: '/authors/search',
|
||||||
|
dataType: 'json'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var locationOptions = {
|
||||||
|
placeholder: 'Location',
|
||||||
|
tags: true
|
||||||
|
};
|
||||||
|
|
||||||
|
$('#add-form .select2-author').select2(authorOptions);
|
||||||
|
|
||||||
|
$('#add-form .select2-location').select2(locationOptions);
|
||||||
|
|
||||||
|
$('#add-form').on('click', '.remove-row', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
$(this).closest('.form-row').remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#add-form').on('keydown', '.barcode_input', function(e) {
|
||||||
|
if (e.keyCode === 13) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#add-form').on('keyup', '.barcode_input', function (e) {
|
||||||
|
if (e.keyCode === 13) {
|
||||||
|
// Do something
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
var $this = $(this),
|
||||||
|
$row = $this.closest('.form-row'),
|
||||||
|
barcodeValue = $this.val();
|
||||||
|
|
||||||
|
if (barcodeValue === '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.get('/lookup/' + barcodeValue, function(res) {
|
||||||
|
$row.find('input[name*=name]').val(res.title);
|
||||||
|
|
||||||
|
var $authors = $row.find('.select2-author');
|
||||||
|
|
||||||
|
$authors.children('option').remove();
|
||||||
|
|
||||||
|
for (var i = 0; i < res.authors.length; i++) {
|
||||||
|
$authors.append($('<option>', {value: res.authors[i], text: res.authors[i], selected: 'selected'}));
|
||||||
|
}
|
||||||
|
|
||||||
|
$authors.trigger('change');
|
||||||
|
}, 'json');
|
||||||
|
|
||||||
|
var count = emptyRowCount();
|
||||||
|
|
||||||
|
console.log('Empty rows:', count);
|
||||||
|
|
||||||
|
if (count < 1) {
|
||||||
|
var firstIndex = 0,
|
||||||
|
$container = $row.closest('.row-container');
|
||||||
|
|
||||||
|
|
||||||
|
for (var i = 0; i < 200; i++) {
|
||||||
|
if ($container.find('.form-row[data-index=' + i + ']').length < 1) {
|
||||||
|
firstIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var $template = $('#add-template'),
|
||||||
|
$clone = $template.clone();
|
||||||
|
|
||||||
|
$clone.attr('data-index', firstIndex);
|
||||||
|
|
||||||
|
$clone.find('input, select').each(function() {
|
||||||
|
$(this).attr('name', $(this).attr('name').replace('__INDEX__', firstIndex));
|
||||||
|
});
|
||||||
|
|
||||||
|
$clone.removeAttr('id');
|
||||||
|
$clone.find('input[type=text]').val('');
|
||||||
|
|
||||||
|
$clone.removeClass('invisible').addClass('form-row');
|
||||||
|
|
||||||
|
$container.append($clone);
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
$clone.find('.barcode_input').focus();
|
||||||
|
$clone.find('.select2-author').select2(authorOptions);
|
||||||
|
}, 150);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function emptyRowCount() {
|
||||||
|
var $barcodes = $('#add-form .barcode_input');
|
||||||
|
|
||||||
|
var count = 0;
|
||||||
|
|
||||||
|
$barcodes.each(function() {
|
||||||
|
if ($(this).val() == '') {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
window._ = require('lodash');
|
window._ = require('lodash');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -8,9 +7,13 @@ window._ = require('lodash');
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
window.Popper = require('popper.js').default;
|
||||||
window.$ = window.jQuery = require('jquery');
|
window.$ = window.jQuery = require('jquery');
|
||||||
|
|
||||||
require('bootstrap-sass');
|
require('bootstrap');
|
||||||
|
require('select2');
|
||||||
|
require('datatables.net-bs4');
|
||||||
|
require('datatables.net-buttons-bs4');
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -23,31 +26,19 @@ window.axios = require('axios');
|
|||||||
|
|
||||||
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
|
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
|
||||||
|
|
||||||
/**
|
|
||||||
* Next we will register the CSRF Token as a common header with Axios so that
|
|
||||||
* all outgoing HTTP requests automatically have it attached. This is just
|
|
||||||
* a simple convenience so we don't have to attach every token manually.
|
|
||||||
*/
|
|
||||||
|
|
||||||
let token = document.head.querySelector('meta[name="csrf-token"]');
|
|
||||||
|
|
||||||
if (token) {
|
|
||||||
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
|
|
||||||
} else {
|
|
||||||
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Echo exposes an expressive API for subscribing to channels and listening
|
* Echo exposes an expressive API for subscribing to channels and listening
|
||||||
* for events that are broadcast by Laravel. Echo and event broadcasting
|
* for events that are broadcast by Laravel. Echo and event broadcasting
|
||||||
* allows your team to easily build robust real-time web applications.
|
* allows your team to easily build robust real-time web applications.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// import Echo from 'laravel-echo'
|
// import Echo from 'laravel-echo';
|
||||||
|
|
||||||
// window.Pusher = require('pusher-js');
|
// window.Pusher = require('pusher-js');
|
||||||
|
|
||||||
// window.Echo = new Echo({
|
// window.Echo = new Echo({
|
||||||
// broadcaster: 'pusher',
|
// broadcaster: 'pusher',
|
||||||
// key: 'your-pusher-key'
|
// key: process.env.MIX_PUSHER_APP_KEY,
|
||||||
|
// cluster: process.env.MIX_PUSHER_APP_CLUSTER,
|
||||||
|
// forceTLS: true
|
||||||
// });
|
// });
|
14
resources/sass/app.scss
vendored
Normal file
14
resources/sass/app.scss
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// Bootstrap
|
||||||
|
@import "../../node_modules/bootstrap/scss/bootstrap";
|
||||||
|
|
||||||
|
// DataTables
|
||||||
|
@import "../../node_modules/datatables.net-bs4/css/dataTables.bootstrap4.css";
|
||||||
|
@import "../../node_modules/datatables.net-buttons-bs4/css/buttons.bootstrap4.css";
|
||||||
|
|
||||||
|
body {
|
||||||
|
padding-top: 5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-row {
|
||||||
|
padding-bottom: 6px;
|
||||||
|
}
|
@ -1,7 +1,8 @@
|
|||||||
@extends('layouts.main')
|
@extends('layouts.main')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<form id="add-form">
|
<form id="add-form" method="POST" action="{{ route('save') }}">
|
||||||
|
{{ csrf_field() }}
|
||||||
<div class="form-row justify-content-md-center">
|
<div class="form-row justify-content-md-center">
|
||||||
<div class="col-4">
|
<div class="col-4">
|
||||||
<select name="location" class="form-control select2-location">
|
<select name="location" class="form-control select2-location">
|
||||||
@ -9,29 +10,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
<div class="form-row">
|
<div class="row-container">
|
||||||
<div class="col">
|
@if (!empty($old))
|
||||||
<input name="books[][barcode]" type="text" class="form-control barcode_input" placeholder="Barcode">
|
@foreach ($old as $index => $item)
|
||||||
</div>
|
@include('partials/row', [ 'index' => $index, 'item' => $item ])
|
||||||
<div class="col-4">
|
@endforeach
|
||||||
<input name="books[][name]" type="text" class="form-control" placeholder="Name">
|
@include('partials/row', [ 'index' => count($old), 'item' => [] ])
|
||||||
</div>
|
@else
|
||||||
<div class="col">
|
@include('partials/row', [ 'index' => 0])
|
||||||
<select name="books[][authors]" class="form-control select2-author" multiple="multiple">
|
@endif
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<button class="btn btn-primary" name="save" type="submit">
|
||||||
|
Save
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<div id="add-template" class="invisible">
|
@include('partials/row', [ 'id' => 'add-template', 'htmlClass' => 'invisible' ])
|
||||||
<div class="col">
|
|
||||||
<input name="books[][barcode]" type="text" class="form-control barcode_input" placeholder="Barcode">
|
|
||||||
</div>
|
|
||||||
<div class="col-4">
|
|
||||||
<input name="books[][name]" type="text" class="form-control" placeholder="Name">
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<select name="books[][authors]" class="form-control select2-author" multiple="multiple">
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endsection
|
@endsection
|
21
resources/views/index.blade.php
Normal file
21
resources/views/index.blade.php
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
@extends('layouts.main')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<table class="table table-compact">
|
||||||
|
<thead>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Authors</th>
|
||||||
|
<th>Location</th>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@foreach ($rows as $row)
|
||||||
|
<tr>
|
||||||
|
<td>{{ $row->name }}</td>
|
||||||
|
<td>{{ $row->authors->pluck('name')->join(', ') }}</td>
|
||||||
|
<td>{{ $row->location->name }}</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{{ $rows->links() }}
|
||||||
|
@endsection
|
@ -8,49 +8,20 @@
|
|||||||
|
|
||||||
<title>{{ config('app.name') }}</title>
|
<title>{{ config('app.name') }}</title>
|
||||||
|
|
||||||
<!-- Bootstrap core CSS -->
|
<link href="{{ mix('css/app.css') }}" rel="stylesheet">
|
||||||
<link href="{{ url('css/bootstrap.min.css') }}" rel="stylesheet">
|
|
||||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet" />
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet" />
|
||||||
<link href="{{ url('css/select2-bs4.css') }}" rel="stylesheet">
|
|
||||||
<link href="{{ url('css/app.css') }}" rel="stylesheet">
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
|
@include('partials/navbar')
|
||||||
<a class="navbar-brand" href="#">{{ config('app.name') }}</a>
|
|
||||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault"
|
|
||||||
aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
|
|
||||||
<span class="navbar-toggler-icon"></span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<div class="collapse navbar-collapse" id="navbarsExampleDefault">
|
|
||||||
<ul class="navbar-nav mr-auto">
|
|
||||||
<li class="nav-item active">
|
|
||||||
<a class="nav-link" href="/">Home <span class="sr-only">(current)</span></a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="/add">Add</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<form class="form-inline my-2 my-lg-0">
|
|
||||||
<input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">
|
|
||||||
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<main role="main" class="container">
|
<main role="main" class="container">
|
||||||
@yield('content')
|
@yield('content')
|
||||||
</main><!-- /.container -->
|
</main><!-- /.container -->
|
||||||
|
|
||||||
<script
|
<script src="{{ mix('js/app.js') }}"></script>
|
||||||
src="https://code.jquery.com/jquery-3.2.1.min.js"
|
<script src="{{ asset('vendor/datatables/buttons.server-side.js') }}"></script>
|
||||||
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
|
@stack('scripts')
|
||||||
crossorigin="anonymous"></script>
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script>
|
|
||||||
<script src="{{ url('js/bootstrap.min.js') }}"></script>
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script>
|
|
||||||
<script src="{{ url('js/app.js') }}"></script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
22
resources/views/partials/navbar.blade.php
Normal file
22
resources/views/partials/navbar.blade.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
|
||||||
|
<a class="navbar-brand" href="#">{{ config('app.name') }}</a>
|
||||||
|
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault"
|
||||||
|
aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class="collapse navbar-collapse" id="navbarsExampleDefault">
|
||||||
|
<ul class="navbar-nav mr-auto">
|
||||||
|
<li class="nav-item active">
|
||||||
|
<a class="nav-link" href="/">Home <span class="sr-only">(current)</span></a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/add">Add</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<form class="form-inline my-2 my-lg-0" action="{{ route('search') }}">
|
||||||
|
<input name="query" class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search" />
|
||||||
|
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</nav>
|
20
resources/views/partials/row.blade.php
Normal file
20
resources/views/partials/row.blade.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<div {!! !empty($id) ? 'id="' . $id . '" ' : '' !!}class="form-row {{ $htmlClass ?? '' }}" data-index="{{ $index ?? '__INDEX__' }}">
|
||||||
|
<div class="col">
|
||||||
|
<input name="books[{{ $index ?? '__INDEX__' }}][barcode]" type="text" class="form-control barcode_input" placeholder="Barcode" value="{{ $item['barcode'] ?? '' }}">
|
||||||
|
</div>
|
||||||
|
<div class="col-4">
|
||||||
|
<input name="books[{{ $index ?? '__INDEX__' }}][name]" type="text" class="form-control" placeholder="Name" value="{{ $item['name'] ?? '' }}">
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<select name="books[{{ $index ?? '__INDEX__' }}][authors][]" class="form-control select2-author" multiple="multiple">
|
||||||
|
@if(!empty($item['authors']))
|
||||||
|
@foreach($item['authors'] as $author)
|
||||||
|
<option value="{{ $author }}" selected="selected">{{ $author }}</option>
|
||||||
|
@endforeach
|
||||||
|
@endif
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-1">
|
||||||
|
<button class="remove-row btn btn-danger">Remove</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -1 +0,0 @@
|
|||||||
@extends('layouts.main')
|
|
@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
Route::get('/', 'MainController@index');
|
Route::get('/', 'MainController@index');
|
||||||
Route::get('/add', 'MainController@add');
|
Route::get('/add', 'MainController@add');
|
||||||
|
Route::post('/save', 'MainController@save')->name('save');
|
||||||
|
Route::get('/search', 'MainController@search')->name('search');
|
||||||
|
|
||||||
Route::get('/lookup/{isbn}', 'LookupController@lookup');
|
Route::get('/lookup/{isbn}', 'LookupController@lookup');
|
||||||
|
|
||||||
|
6
webpack.mix.js
vendored
6
webpack.mix.js
vendored
@ -1,4 +1,4 @@
|
|||||||
let mix = require('laravel-mix');
|
const mix = require('laravel-mix');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
@ -11,5 +11,5 @@ let mix = require('laravel-mix');
|
|||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mix.js('resources/assets/js/app.js', 'public/js')
|
mix.js('resources/js/app.js', 'public/js')
|
||||||
.sass('resources/assets/sass/app.scss', 'public/css');
|
.sass('resources/sass/app.scss', 'public/css');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user