diff --git a/app/Facades/WidgetFacade.php b/app/Facades/WidgetFacade.php new file mode 100644 index 0000000..cc1bce1 --- /dev/null +++ b/app/Facades/WidgetFacade.php @@ -0,0 +1,15 @@ +middleware('auth'); - } - /** * Show the application dashboard. * diff --git a/app/Http/Controllers/TableController.php b/app/Http/Controllers/TableController.php index b7c509e..fcfcf4e 100644 --- a/app/Http/Controllers/TableController.php +++ b/app/Http/Controllers/TableController.php @@ -14,9 +14,9 @@ class TableController extends Controller public function create() { $exampleColSpec = - "string, latin, Latin Name\n". - "string, common, Common Name\n". - "int, lifespan, Lifespan"; + "latin, string, Latin Name\n". + "common, string, Common Name\n". + "lifespan, int, Lifespan (years)"; $exampleData = "Mercenaria mercenaria, hard clam, 40\n" . @@ -27,4 +27,18 @@ class TableController extends Controller compact('exampleColSpec', 'exampleData') ); } + + public function storeNew(Request $request) + { + $this->validate($request, [ + 'table-name' => 'required', + 'table-descr' => 'string|nullable', + 'license' => 'string|nullable', + 'upstream' => 'string|nullable', + 'col-spec' => 'required', + 'row-data' => 'string|nullable', + ]); + + return "Ok."; + } } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 3dc7939..95e9b5f 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,6 +2,7 @@ namespace App\Providers; +use App\View\WidgetFactory; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider @@ -25,6 +26,8 @@ class AppServiceProvider extends ServiceProvider */ public function register() { - // + $this->app->singleton(WidgetFactory::class, function () { + return new WidgetFactory(); + }); } } diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 5ea48d3..69772c1 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -53,7 +53,11 @@ class RouteServiceProvider extends ServiceProvider { Route::middleware('web') ->namespace($this->namespace) - ->group(base_path('routes/web.php')); + ->group(base_path('routes/public.php')); + + Route::middleware(['web', 'auth']) + ->namespace($this->namespace) + ->group(base_path('routes/user.php')); } /** diff --git a/app/View/Widget.php b/app/View/Widget.php new file mode 100644 index 0000000..41527ab --- /dev/null +++ b/app/View/Widget.php @@ -0,0 +1,108 @@ +id = 'field-'.$name; + $this->name = $name; + $this->label = $label; + $this->viewName = $viewName; + } + + // setting attributes via magic method + public function __call($method, $args) + { + static $cssProps = [ + 'height', 'minHeight', 'maxHeight' + ]; + + if (empty($args)) $args = ['']; + + $arg = $args[0]; + + // css + $lccamel = $method; + if (in_array($lccamel, $cssProps)) { + return $this->css(kebab_case($lccamel), $arg); + } + + if (property_exists($this, $method)) { + $this->$method = $arg; + } + else { + $this->attributes[$method] = $arg; + } + + return $this; + } + + public function css($prop, $val) + { + $this->style[$prop] = $val; + return $this; + } + + public function __get($name) + { + if ($name == 'attributes') { + return $this->compileAttribs(); + } + + if ($name == 'value') { + return old($this->name, $this->value); + } + + if (property_exists($this, $name)) { + return $this->$name; + } + + return null; + } + + public function compileAttribs() + { + // compile attribs string + $attribs_s = array_reduce(array_keys($this->attributes), function ($carry, $key) { + return $carry . ' ' . $key . '="' . e($this->attributes[$key]) . '"'; + }, ''); + + // add a compiled list of styles + if (!empty($this->style)) { + $attribs_s .= 'style="'.trim(e(array_reduce(array_keys($this->style), function ($carry, $key) { + return $carry . $key . ': ' . $this->style[$key] . '; '; + }, ''))).'"'; + } + + return trim($attribs_s); + } + + public function render() + { + return view('form.'.$this->viewName)->with(['w' => $this]); + } + + public function __toString() + { + return (string) $this->render(); + } +} diff --git a/app/View/WidgetFactory.php b/app/View/WidgetFactory.php new file mode 100644 index 0000000..6d08ef7 --- /dev/null +++ b/app/View/WidgetFactory.php @@ -0,0 +1,27 @@ +minHeight('4em'); + } +} diff --git a/config/app.php b/config/app.php index b2b1b29..199b8ff 100644 --- a/config/app.php +++ b/config/app.php @@ -217,6 +217,7 @@ return [ // sideload 'SocialAuth' => AdamWathan\EloquentOAuth\Facades\OAuth::class, + 'Widget' => App\Facades\WidgetFacade::class, ], // -------------- added keys -------------- diff --git a/public/fonts/fa-dtbl-1-preview.html b/public/fonts/fa-dtbl-1-preview.html new file mode 100644 index 0000000..0fa4298 --- /dev/null +++ b/public/fonts/fa-dtbl-1-preview.html @@ -0,0 +1,386 @@ + + + + fa-dtbl-1 glyphs preview + + + + + + + + + +
+
+

fa-dtbl-1 contains 12 glyphs:

+ Toggle Preview Characters +
+ + +
+
+ PpPpPpPpPpPpPpPpPpPp +
+
+ 12141618212436486072 +
+
+ + +
+
+ +
+
+ PpPpPpPpPpPpPpPpPpPp +
+
+ 12141618212436486072 +
+
+ + +
+
+ +
+
+ PpPpPpPpPpPpPpPpPpPp +
+
+ 12141618212436486072 +
+
+ + + +
+
+ +
+
+ PpPpPpPpPpPpPpPpPpPp +
+
+ 12141618212436486072 +
+
+ + +
+
+ +
+
+ PpPpPpPpPpPpPpPpPpPp +
+
+ 12141618212436486072 +
+
+ + +
+
+ +
+
+ PpPpPpPpPpPpPpPpPpPp +
+
+ 12141618212436486072 +
+
+ + +
+
+ +
+
+ PpPpPpPpPpPpPpPpPpPp +
+
+ 12141618212436486072 +
+
+ + +
+
+ +
+
+ PpPpPpPpPpPpPpPpPpPp +
+
+ 12141618212436486072 +
+
+ + +
+
+ +
+
+ PpPpPpPpPpPpPpPpPpPp +
+
+ 12141618212436486072 +
+
+ + + +
+
+ +
+
+ PpPpPpPpPpPpPpPpPpPp +
+
+ 12141618212436486072 +
+
+ + +
+
+ +
+
+ PpPpPpPpPpPpPpPpPpPp +
+
+ 12141618212436486072 +
+
+ + +
+
+ +
+
+ PpPpPpPpPpPpPpPpPpPp +
+
+ 12141618212436486072 +
+
+ + +
+
+ + + +
+ + diff --git a/public/fonts/fa-dtbl-1.css b/public/fonts/fa-dtbl-1.css index fe8f918..138f940 100644 --- a/public/fonts/fa-dtbl-1.css +++ b/public/fonts/fa-dtbl-1.css @@ -38,10 +38,15 @@ font-smoothing: antialiased; } -.fa-facebook-square::before { content: "\f100"; } -.fa-github::before { content: "\f101"; } -.fa-google::before { content: "\f102"; } -.fa-sign-in::before { content: "\f103"; } -.fa-sign-out::before { content: "\f104"; } -.fa-user-circle-o::before { content: "\f105"; } -.fa-user-plus::before { content: "\f106"; } +.fa-check::before { content: "\f100"; } +.fa-facebook-square::before { content: "\f101"; } +.fa-floppy-o::before, .fa-save::before { content: "\f102"; } +.fa-github::before { content: "\f103"; } +.fa-google::before { content: "\f104"; } +.fa-question-circle::before { content: "\f105"; } +.fa-sign-in::before { content: "\f106"; } +.fa-sign-out::before { content: "\f107"; } +.fa-times::before, .fa-close::before { content: "\f108"; } +.fa-trash-o::before { content: "\f109"; } +.fa-user-circle-o::before { content: "\f10a"; } +.fa-user-plus::before { content: "\f10b"; } diff --git a/public/fonts/fa-dtbl-1.eot b/public/fonts/fa-dtbl-1.eot index 1aedfba..3cea901 100644 Binary files a/public/fonts/fa-dtbl-1.eot and b/public/fonts/fa-dtbl-1.eot differ diff --git a/public/fonts/fa-dtbl-1.svg b/public/fonts/fa-dtbl-1.svg index 27b577e..cb7fc6f 100644 --- a/public/fonts/fa-dtbl-1.svg +++ b/public/fonts/fa-dtbl-1.svg @@ -1,11 +1,11 @@ -Created by FontForge 20170805 at Mon Jul 16 22:14:13 2018 +Created by FontForge 20170805 at Sat Jul 21 17:17:47 2018 By ondra The Fork Awesome font is licensed under the SIL OFL 1.1 (http://scripts.sil.org/OFL). Fork Awesome is a fork based of off Font Awesome 4.7.0 by Dave Gandy. More info on licenses at https://forkawesome.github.io @@ -22,32 +22,49 @@ The Fork Awesome font is licensed under the SIL OFL 1.1 (http://scripts.sil.org/ bbox="0 -256 2048 1536" underline-thickness="89.6" underline-position="-179.2" - unicode-range="U+0020-F106" + unicode-range="U+0020-F10B" /> - + - + - - + - - + + - diff --git a/public/fonts/fa-dtbl-1.ttf b/public/fonts/fa-dtbl-1.ttf index cf3fd69..9fa1282 100644 Binary files a/public/fonts/fa-dtbl-1.ttf and b/public/fonts/fa-dtbl-1.ttf differ diff --git a/public/fonts/fa-dtbl-1.woff2 b/public/fonts/fa-dtbl-1.woff2 index 36240f5..b9123ca 100644 Binary files a/public/fonts/fa-dtbl-1.woff2 and b/public/fonts/fa-dtbl-1.woff2 differ diff --git a/resources/assets/js/app.js b/resources/assets/js/app.js index ffc5e64..50e0ad6 100644 --- a/resources/assets/js/app.js +++ b/resources/assets/js/app.js @@ -7,6 +7,13 @@ require('./bootstrap'); +$(function () { + $('[data-toggle="tooltip"]').tooltip({ + container: 'body' + }) +}) + + // // window.Vue = require('vue'); // diff --git a/resources/assets/sass/_bst-modules.scss b/resources/assets/sass/_bst-modules.scss index c6548d7..0ee0f65 100644 --- a/resources/assets/sass/_bst-modules.scss +++ b/resources/assets/sass/_bst-modules.scss @@ -25,8 +25,8 @@ @import "~bootstrap/scss/list-group"; @import "~bootstrap/scss/close"; @import "~bootstrap/scss/modal"; -//@import "~bootstrap/scss/tooltip"; -//@import "~bootstrap/scss/popover"; +@import "~bootstrap/scss/tooltip"; +@import "~bootstrap/scss/popover"; //@import "~bootstrap/scss/carousel"; @import "~bootstrap/scss/utilities"; //@import "~bootstrap/scss/print"; diff --git a/resources/assets/sass/_variables.scss b/resources/assets/sass/_variables.scss index 45bc727..927e2c5 100644 --- a/resources/assets/sass/_variables.scss +++ b/resources/assets/sass/_variables.scss @@ -19,3 +19,7 @@ $card-border-radius: 5px; $card-inner-border-radius: 2px; $list-group-hover-bg: rgba($primary, .1); + +$tooltip-max-width: 300px; +$tooltip-bg: darken($primary, 20%); +$tooltip-arrow-color: $tooltip-bg; diff --git a/resources/assets/sass/app.scss b/resources/assets/sass/app.scss index 82008a1..1e6f7bb 100644 --- a/resources/assets/sass/app.scss +++ b/resources/assets/sass/app.scss @@ -7,6 +7,18 @@ @import "variables"; @import "bst-modules"; +html { + overflow-y: scroll; +} + +.tooltip-inner { + text-align: left; +} + +.tooltip-inner { + box-shadow: 0 2px 5px rgba(black, .3); +} + .page-navbar { background: white; border-bottom: 1px solid $primary; diff --git a/resources/views/form/_help.blade.php b/resources/views/form/_help.blade.php new file mode 100644 index 0000000..fc2cb46 --- /dev/null +++ b/resources/views/form/_help.blade.php @@ -0,0 +1,11 @@ +
+ @if($w->help) + help, '<')) + data-html="true" + @endif + title="{{ $w->help }}"> + @endif +
diff --git a/resources/views/form/input.blade.php b/resources/views/form/input.blade.php new file mode 100644 index 0000000..2867fbd --- /dev/null +++ b/resources/views/form/input.blade.php @@ -0,0 +1,21 @@ +@php +/** @var \App\View\Widget $w */ +@endphp + +
+ +
+ attributes !!}> + + @if ($errors->has($w->name)) + + {{ $errors->first($w->name) }} + + @endif +
+ @include('form._help') +
diff --git a/resources/views/form/textarea.blade.php b/resources/views/form/textarea.blade.php new file mode 100644 index 0000000..77d8028 --- /dev/null +++ b/resources/views/form/textarea.blade.php @@ -0,0 +1,20 @@ +@php +/** @var \App\View\Widget $w */ +@endphp + +
+ +
+ + + @if ($errors->has($w->name)) + + {{ $errors->first($w->name) }} + + @endif +
+ @include('form._help') +
diff --git a/resources/views/table/create.blade.php b/resources/views/table/create.blade.php index a3a8783..b4b93fd 100644 --- a/resources/views/table/create.blade.php +++ b/resources/views/table/create.blade.php @@ -2,92 +2,49 @@ @section('content')
-
-
-
- - - - @if ($errors->has('table-name')) - - {{ $errors->first('table-name') }} - - @endif -
- -
- - +
+

New Table

- @if ($errors->has('table-descr')) - - {{ $errors->first('table-descr') }} - - @endif -
- -
- - - - @if ($errors->has('license')) - - {{ $errors->first('license', 'CC0') }} - - @endif -
+ @csrf +
+ {!! Widget::text('table-name', 'Title')->help('Unique among your tables') !!} + + {!! Widget::textarea('table-descr', 'Description')->height('8em') + ->help('Description what data is in the table. Please use the dedicated + fields for License and data source. URLs in a full format will be clickable.') !!} + + {!! Widget::text('license', 'License') + ->help('License applicable to the table\'s data, if any. By default, all + tables are CC0 or Public Domain.') !!} + + {!! Widget::text('upstream', 'Adapted from') + ->help('If you took the data from some external site, a book, etc., write it here. + URLs in a full format will be clickable.') !!} + + {!! Widget::textarea('col-spec', 'Columns')->value($exampleColSpec)->height('8em') + ->help(' +
+ Column parameters in CSV format: +
    +
  • column identifier
    letters, numbers, underscore +
  • column data type
    int, string, float, bool +
  • column title
    used for display (optional) +
+
') !!} + + {!! Widget::textarea('row-data', 'Initial data')->value($exampleData)->height('12em') + ->help(' + Initial table data in CSV format, columns corresponding to the + specification you entered above.') !!}
- - - - @if ($errors->has('upstream')) - - {{ $errors->first('upstream') }} - - @endif -
- -
-
-
-

Insert the initial table definition and data in CSV format. Columns are defined as CSV rows:

-
    -
  • type (int, string, float, bool) -
  • column identifier (letters, numbers, and underscore only) -
  • user-friendly column title -
+
+
- -
- - - - @if ($errors->has('col-spec')) - - {{ $errors->first('col-spec') }} - - @endif -
- -
- - - - @if ($errors->has('row-data')) - - {{ $errors->first('row-data') }} - - @endif -
-
+
@endsection diff --git a/routes/login.php b/routes/login.php index b4b315d..0a69307 100644 --- a/routes/login.php +++ b/routes/login.php @@ -1,4 +1,5 @@ name('home'); + +// Table resource +Route::group([ + 'prefix' => 'table', +], function () { + Route::get('create', 'TableController@create')->name('table.create'); + Route::post('create', 'TableController@storeNew')->name('table.storeNew'); +}); + diff --git a/routes/web.php b/routes/web.php deleted file mode 100644 index 73db1ef..0000000 --- a/routes/web.php +++ /dev/null @@ -1,34 +0,0 @@ -name('home'); - -Route::get('/table/create', 'TableController@create')->name('table.create');