Skip to content
This repository was archived by the owner on Apr 24, 2020. It is now read-only.

Commit 465e8b7

Browse files
committed
Working with stimulus
1 parent f786978 commit 465e8b7

File tree

16 files changed

+53422
-81
lines changed

16 files changed

+53422
-81
lines changed

.babelrc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{ "plugins": ["@babel/plugin-proposal-class-properties"] }

app/Http/Controllers/Api/NotificationsController.php

+7-5
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class NotificationsController
1313
*
1414
* @var int
1515
*/
16-
protected $refreshInterval = 10;
16+
protected $refreshInterval = 15;
1717

1818
/**
1919
* Returns the notification event stream.
@@ -24,11 +24,13 @@ class NotificationsController
2424
*/
2525
public function index(Request $request)
2626
{
27-
$notifications = new Notifications($request->user());
28-
29-
return new StreamedResponse(function() use ($notifications) {
27+
return new StreamedResponse(function() use ($request) {
3028
while(true) {
31-
echo 'data: ' . json_encode($notifications->resource()) . "\n\n";
29+
$notifications = (new Notifications($request->user()))->get()->transform(function ($notification) {
30+
return view('notifications.notification', compact('notification'))->render();
31+
});
32+
33+
echo 'data: ' . $notifications . "\n\n";
3234
ob_flush();
3335
flush();
3436

app/Http/View/Composers/AppLayoutComposer.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public function compose(View $view)
2121

2222
$view->with([
2323
'counts' => ['domains' => LdapDomain::count()],
24-
'notifications' => json_encode($notifications->resource()),
24+
'notifications' => $notifications->get(),
2525
]);
2626
}
2727
}
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
/** @var \Illuminate\Database\Eloquent\Factory $factory */
4+
5+
use Faker\Generator as Faker;
6+
use Illuminate\Notifications\DatabaseNotification;
7+
8+
$factory->define(DatabaseNotification::class, function (Faker $faker) {
9+
return [
10+
'id' => $faker->uuid,
11+
'type' => 'database',
12+
'data' => ['test'],
13+
];
14+
});

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"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"
1111
},
1212
"devDependencies": {
13+
"@babel/plugin-proposal-class-properties": "^7.5.5",
1314
"axios": "^0.19",
1415
"bootstrap": "^4.0.0",
1516
"cross-env": "^5.1",
@@ -22,6 +23,7 @@
2223
"resolve-url-loader": "2.3.1",
2324
"sass": "^1.20.1",
2425
"sass-loader": "7.*",
26+
"stimulus": "^1.1.1",
2527
"sweetalert2": "^8.17.1",
2628
"turbolinks": "^5.2.0",
2729
"vue": "^2.5.17",

public/css/app.css

+12,334-2
Large diffs are not rendered by default.

public/js/app.js

+40,919-1
Large diffs are not rendered by default.

public/mix-manifest.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
"/js/app.js": "/js/app.js?id=648e5426d480fab7d7c4",
3-
"/css/app.css": "/css/app.css?id=a0f5ffa692a2eeee9792"
2+
"/js/app.js": "/js/app.js?id=0f568466b88fa93442a5",
3+
"/css/app.css": "/css/app.css?id=5bcb1e42abfaad0bbdfd"
44
}

resources/js/app.js

+12-56
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,20 @@
1-
import * as Ladda from 'ladda';
2-
import Turbolinks from 'turbolinks';
3-
import Notifier from './notifier';
4-
5-
require('./bootstrap');
61

7-
window.Vue = require('vue');
2+
import './bootstrap';
83

9-
// Register components...
10-
Vue.component('notification', require('./components/Notification.vue').default);
11-
Vue.component('notifications', require('./components/Notifications.vue').default);
12-
Vue.component('form-confirm', require('./components/FormConfirm.vue').default);
13-
Vue.component('date-picker', require('./components/Datepicker.vue').default);
14-
Vue.component('date-time-picker', require('./components/DateTimePicker.vue').default);
15-
Vue.component('input-selector', require('./components/InputSelector.vue').default);
16-
17-
window.Notifier = new Notifier();
4+
import * as Ladda from 'ladda';
5+
import Turbolinks from 'turbolinks';
6+
import { Application } from 'stimulus';
7+
import { definitionsFromContext } from 'stimulus/webpack-helpers';
188

19-
// Construct a new Vue instance when turbolinks loads...
20-
$(document).on('turbolinks:load', () => {
21-
const app = new Vue({
22-
el: '#app',
23-
});
9+
// Start Stimulus.
10+
const application = Application.start();
11+
const context = require.context('./controllers', true, /\.js$/);
12+
application.load(definitionsFromContext(context));
2413

25-
// Enable tooltips.
26-
$('[data-toggle="tooltip"]').tooltip();
14+
// Boot Turbolinks...
15+
Turbolinks.start();
2716

17+
$(document).on('turbolinks:load', function () {
2818
// Enable ladda.
2919
Ladda.bind('button[type=submit]:not(.no-loading)');
30-
31-
// Autofocus the first input on modal windows.
32-
$(document).on('shown.bs.modal', function () {
33-
$(this).find('[autofocus]').focus();
34-
});
35-
36-
// Show / hide modals when included as an anchor in the URL.
37-
$('.modal').on('show.bs.modal hide.bs.modal', function (e) {
38-
let url = window.location.origin + window.location.pathname;
39-
40-
if (e.type === 'show') {
41-
url = url + '#' + $(e.target).attr('id');
42-
}
43-
44-
window.history.replaceState(window.history.state, "", url);
45-
});
46-
47-
// Open modals if they are included in the URL hash.
48-
let hash = location.hash;
49-
50-
if (hash) {
51-
let modal = $(hash);
52-
53-
// Determine if the given has is a modal.
54-
if (
55-
modal.attr('class') !== undefined &&
56-
modal.attr('class').includes('modal')
57-
) {
58-
modal.modal('show');
59-
}
60-
}
6120
});
62-
63-
// Boot Turbolinks...
64-
Turbolinks.start();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { Controller } from "stimulus"
2+
import { NativeEventSource, EventSourcePolyfill } from 'event-source-polyfill';
3+
4+
const EventSource = NativeEventSource || EventSourcePolyfill;
5+
6+
export default class extends Controller {
7+
static targets = ['count', 'notification', 'list'];
8+
9+
static eventSource;
10+
11+
connect() {
12+
this.updateCount();
13+
14+
this.eventSource = new EventSource(this.data.get('url'));
15+
16+
this.eventSource.addEventListener('message', (event) => {
17+
let notifications = '';
18+
19+
JSON.parse(event.data).forEach((notification) => {
20+
notifications += notification;
21+
});
22+
23+
this.listTarget.innerHTML = notifications;
24+
25+
this.updateCount();
26+
}, false);
27+
28+
this.eventSource.addEventListener('error', event => {
29+
if (event.readyState === EventSource.CLOSED) {
30+
console.log('EventSource was closed');
31+
console.log(EventSource);
32+
}
33+
}, false);
34+
}
35+
36+
disconnect() {
37+
this.eventSource.close();
38+
}
39+
40+
updateCount() {
41+
// Set the total number of notifications.
42+
this.countTarget.innerHTML = this.notificationTargets.length;
43+
}
44+
}

resources/views/layouts/app.blade.php

+2-11
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,10 @@
33
@section('head')
44
<script src="{{ asset(mix('js/app.js')) }}" data-turbolinks-track="reload"></script>
55
<link href="{{ asset(mix('css/app.css')) }}" rel="stylesheet" data-turbolinks-track="reload">
6-
7-
@auth
8-
<script>
9-
Notifier.init('{{ route('api.notifications') }}');
10-
</script>
11-
@endauth
126
@endsection
137

148
@section('body')
15-
<div id="app" v-cloak>
9+
<div id="app">
1610
@include('layouts.flash')
1711

1812
<nav class="navbar navbar-expand-md navbar-dark bg-dark navbar-app shadow-sm">
@@ -58,10 +52,7 @@
5852
</a>
5953
</li>
6054
@else
61-
<notifications
62-
url="{{ route('api.notifications') }}"
63-
:default-notifications="{{ $notifications }}"
64-
></notifications>
55+
@include('layouts.notifications')
6556

6657
<li class="nav-item dropdown">
6758
<a id="user-dropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>

resources/views/layouts/base.blade.php

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
<head>
44
<meta charset="utf-8">
55
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
6-
<meta name="turbolinks-cache-control" content="no-cache">
76

87
<!-- CSRF Token -->
98
<meta name="csrf-token" content="{{ csrf_token() }}">
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<li class="nav-item dropdown" data-controller="notifications" data-notifications-url="{{ route('api.notifications') }}">
2+
<a
3+
href="#"
4+
class="nav-link dropdown-toggle"
5+
data-toggle="dropdown"
6+
aria-haspopup="true"
7+
aria-expanded="false"
8+
>
9+
<i class="far fa-bell"></i>
10+
<span data-target="notifications.count">0</span>
11+
<span class="caret"></span>
12+
</a>
13+
14+
<div class="dropdown-menu dropdown-menu-right notifications">
15+
<h6 class="dropdown-header bg-white">Notifications</h6>
16+
17+
<div data-target="notifications.list">
18+
@foreach($notifications as $notification)
19+
@include('notifications.notification')
20+
@endforeach
21+
</div>
22+
23+
<div class="dropdown-divider"></div>
24+
25+
<div class="p-2 px-3">
26+
<a class="btn btn-block btn-sm btn-primary" href="#">View All</a>
27+
</div>
28+
</div>
29+
</li>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<a href="#" class="dropdown-item" data-target="notifications.notification">
2+
Test
3+
</a>

storage/framework/cache/data/.gitignore

-2
This file was deleted.

yarn.lock

+52
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,18 @@
6464
"@babel/traverse" "^7.4.4"
6565
"@babel/types" "^7.4.4"
6666

67+
"@babel/helper-create-class-features-plugin@^7.5.5":
68+
version "7.6.0"
69+
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.6.0.tgz#769711acca889be371e9bc2eb68641d55218021f"
70+
integrity sha512-O1QWBko4fzGju6VoVvrZg0RROCVifcLxiApnGP3OWfWzvxRZFCoBD81K5ur5e3bVY2Vf/5rIJm8cqPKn8HUJng==
71+
dependencies:
72+
"@babel/helper-function-name" "^7.1.0"
73+
"@babel/helper-member-expression-to-functions" "^7.5.5"
74+
"@babel/helper-optimise-call-expression" "^7.0.0"
75+
"@babel/helper-plugin-utils" "^7.0.0"
76+
"@babel/helper-replace-supers" "^7.5.5"
77+
"@babel/helper-split-export-declaration" "^7.4.4"
78+
6779
"@babel/helper-define-map@^7.5.5":
6880
version "7.5.5"
6981
resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.5.5.tgz#3dec32c2046f37e09b28c93eb0b103fd2a25d369"
@@ -227,6 +239,14 @@
227239
"@babel/helper-remap-async-to-generator" "^7.1.0"
228240
"@babel/plugin-syntax-async-generators" "^7.2.0"
229241

242+
"@babel/plugin-proposal-class-properties@^7.5.5":
243+
version "7.5.5"
244+
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.5.tgz#a974cfae1e37c3110e71f3c6a2e48b8e71958cd4"
245+
integrity sha512-AF79FsnWFxjlaosgdi421vmYG6/jg79bVD0dpD44QdgobzHKuLZ6S3vl8la9qIeSwGi8i1fS0O1mfuDAAdo1/A==
246+
dependencies:
247+
"@babel/helper-create-class-features-plugin" "^7.5.5"
248+
"@babel/helper-plugin-utils" "^7.0.0"
249+
230250
"@babel/plugin-proposal-dynamic-import@^7.5.0":
231251
version "7.5.0"
232252
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.5.0.tgz#e532202db4838723691b10a67b8ce509e397c506"
@@ -668,6 +688,30 @@
668688
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b"
669689
integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==
670690

691+
"@stimulus/core@^1.1.1":
692+
version "1.1.1"
693+
resolved "https://registry.yarnpkg.com/@stimulus/core/-/core-1.1.1.tgz#42b0cfe5b73ca492f41de64b77a03980bae92c82"
694+
integrity sha512-PVJv7IpuQx0MVPCBblXc6O2zbCmU8dlxXNH4bC9KK6LsvGaE+PCXXrXQfXUwAsse1/CmRu/iQG7Ov58himjiGg==
695+
dependencies:
696+
"@stimulus/mutation-observers" "^1.1.1"
697+
698+
"@stimulus/multimap@^1.1.1":
699+
version "1.1.1"
700+
resolved "https://registry.yarnpkg.com/@stimulus/multimap/-/multimap-1.1.1.tgz#b95e3fd607345ab36e5d5b55486ee1a12d56b331"
701+
integrity sha512-26R1fI3a8uUj0WlMmta4qcfIQGlagegdP4PTz6lz852q/dXlG6r+uPS/bx+H8GtfyS+OOXVr3SkZ0Zg0iRqRfQ==
702+
703+
"@stimulus/mutation-observers@^1.1.1":
704+
version "1.1.1"
705+
resolved "https://registry.yarnpkg.com/@stimulus/mutation-observers/-/mutation-observers-1.1.1.tgz#0f6c6f081308427fed2a26360dda0c173b79cfc0"
706+
integrity sha512-/zCnnw1KJlWO2mrx0yxYaRFZWMGnDMdOgSnI4hxDLxdWVuL2HMROU8FpHWVBLjKY3T9A+lGkcrmPGDHF3pfS9w==
707+
dependencies:
708+
"@stimulus/multimap" "^1.1.1"
709+
710+
"@stimulus/webpack-helpers@^1.1.1":
711+
version "1.1.1"
712+
resolved "https://registry.yarnpkg.com/@stimulus/webpack-helpers/-/webpack-helpers-1.1.1.tgz#eff60cd4e58b921d1a2764dc5215f5141510f2c2"
713+
integrity sha512-XOkqSw53N9072FLHvpLM25PIwy+ndkSSbnTtjKuyzsv8K5yfkFB2rv68jU1pzqYa9FZLcvZWP4yazC0V38dx9A==
714+
671715
"@types/events@*":
672716
version "3.0.0"
673717
resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7"
@@ -6058,6 +6102,14 @@ static-extend@^0.1.1:
60586102
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
60596103
integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
60606104

6105+
stimulus@^1.1.1:
6106+
version "1.1.1"
6107+
resolved "https://registry.yarnpkg.com/stimulus/-/stimulus-1.1.1.tgz#53c2fded6849e7b85eed3ed8dd76e33abd74bec5"
6108+
integrity sha512-R0mBqKp48YnRDZOxZ8hiOH4Ilph3Yj78CIFTBkCwyHs4iGCpe7xlEdQ7cjIxb+7qVCSxFKgxO+mAQbsNgt/5XQ==
6109+
dependencies:
6110+
"@stimulus/core" "^1.1.1"
6111+
"@stimulus/webpack-helpers" "^1.1.1"
6112+
60616113
stream-browserify@^2.0.1:
60626114
version "2.0.2"
60636115
resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b"

0 commit comments

Comments
 (0)