Add support for etag and not modified resources
This commit is contained in:
parent
14183e390c
commit
235a70160b
|
@ -16,10 +16,20 @@ class AlertController extends Controller
|
|||
public function index()
|
||||
{
|
||||
return response()->json(
|
||||
Alert::with('crew.user')
|
||||
->where('closed', false)
|
||||
->orderBy('created_at', 'desc')
|
||||
->get()
|
||||
request()->query('full', false) ?
|
||||
Alert::with(['crew.user' => [
|
||||
"name",
|
||||
"username",
|
||||
"chief",
|
||||
"driver"
|
||||
]])
|
||||
->where('closed', false)
|
||||
->orderBy('created_at', 'desc')
|
||||
->get()
|
||||
:
|
||||
Alert::where('closed', false)
|
||||
->orderBy('created_at', 'desc')
|
||||
->get()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -113,10 +123,15 @@ class AlertController extends Controller
|
|||
*/
|
||||
public function show(Request $request, $id)
|
||||
{
|
||||
User::where('id', $request->user()->id)->update(['last_access' => now()]);
|
||||
|
||||
return response()->json(
|
||||
Alert::with('crew.user')->find($id)
|
||||
Alert::with(['crew.user' => [
|
||||
"name",
|
||||
"username",
|
||||
"chief",
|
||||
"driver"
|
||||
]])
|
||||
->where('id', $id)
|
||||
->first()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
"laravel/framework": "^10.0",
|
||||
"laravel/sanctum": "^3.2",
|
||||
"laravel/tinker": "^2.8",
|
||||
"matthewbdaly/laravel-etag-middleware": "^1.3",
|
||||
"santigarcor/laratrust": "^7.2",
|
||||
"sentry/sentry-laravel": "^3.7"
|
||||
},
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "f099d4ac47fd2d3bbc07fe77412bb9bd",
|
||||
"content-hash": "f8b683b55dd63e861103c15d13fed172",
|
||||
"packages": [
|
||||
{
|
||||
"name": "brick/math",
|
||||
|
@ -2202,6 +2202,61 @@
|
|||
],
|
||||
"time": "2023-08-05T12:09:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "matthewbdaly/laravel-etag-middleware",
|
||||
"version": "1.3.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/matthewbdaly/laravel-etag-middleware.git",
|
||||
"reference": "048cb22f5849f695f134e7e13cb52b4c21ef6fd4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/matthewbdaly/laravel-etag-middleware/zipball/048cb22f5849f695f134e7e13cb52b4c21ef6fd4",
|
||||
"reference": "048cb22f5849f695f134e7e13cb52b4c21ef6fd4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/http": "^5.5|^6.0|^7.0|^8.0|^9.0|^10.0",
|
||||
"illuminate/support": "^5.5|^6.0|^7.0|^8.0|^9.0|^10.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^1.0",
|
||||
"php-coveralls/php-coveralls": "^2.1",
|
||||
"phpunit/phpunit": "^4.8|^5.2|^9.0",
|
||||
"squizlabs/php_codesniffer": "^3.7",
|
||||
"vimeo/psalm": "^5.8"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Matthewbdaly\\ETagMiddleware\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Matthew Daly",
|
||||
"email": "450801+matthewbdaly@users.noreply.github.com"
|
||||
}
|
||||
],
|
||||
"description": "A Laravel middleware for adding ETags to HTTP requests to improve response times",
|
||||
"keywords": [
|
||||
"ETags",
|
||||
"Etag",
|
||||
"http",
|
||||
"laravel",
|
||||
"middleware"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/matthewbdaly/laravel-etag-middleware/issues",
|
||||
"source": "https://github.com/matthewbdaly/laravel-etag-middleware/tree/1.3.6"
|
||||
},
|
||||
"time": "2023-03-20T16:12:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"version": "3.4.0",
|
||||
|
|
|
@ -14,6 +14,7 @@ use App\Http\Controllers\ServiceTypeController;
|
|||
use App\Http\Controllers\TrainingController;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use \Matthewbdaly\ETagMiddleware\ETag;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
@ -44,16 +45,16 @@ Route::middleware('auth:sanctum')->group( function () {
|
|||
Route::get('/schedules', [ScheduleSlotsController::class, 'index']);
|
||||
Route::post('/schedules', [ScheduleSlotsController::class, 'store']);
|
||||
|
||||
Route::get('/availability', [AvailabilityController::class, 'get']);
|
||||
Route::get('/availability', [AvailabilityController::class, 'get'])->middleware(ETag::class);
|
||||
Route::post('/availability', [AvailabilityController::class, 'updateAvailability']);
|
||||
Route::post('/manual_mode', [AvailabilityController::class, 'updateAvailabilityManualMode']);
|
||||
|
||||
Route::get('/alerts', [AlertController::class, 'index']);
|
||||
Route::get('/alerts', [AlertController::class, 'index'])->middleware(ETag::class);
|
||||
Route::post('/alerts', [AlertController::class, 'store']);
|
||||
Route::get('/alerts/{id}', [AlertController::class, 'show']);
|
||||
Route::get('/alerts/{id}', [AlertController::class, 'show'])->middleware(ETag::class);
|
||||
Route::patch('/alerts/{id}', [AlertController::class, 'update']);
|
||||
|
||||
Route::get('/services', [ServiceController::class, 'index']);
|
||||
Route::get('/services', [ServiceController::class, 'index'])->middleware(ETag::class);
|
||||
Route::post('/services', [ServiceController::class, 'createOrUpdate']);
|
||||
Route::get('/services/{id}', [ServiceController::class, 'show']);
|
||||
Route::delete('/services/{id}', [ServiceController::class, 'destroy']);
|
||||
|
@ -63,12 +64,12 @@ Route::middleware('auth:sanctum')->group( function () {
|
|||
Route::get('/places/search', [PlacesController::class, 'search']);
|
||||
Route::get('/places/{id}', [PlacesController::class, 'show']);
|
||||
|
||||
Route::get('/trainings', [TrainingController::class, 'index']);
|
||||
Route::get('/trainings', [TrainingController::class, 'index'])->middleware(ETag::class);
|
||||
Route::post('/trainings', [TrainingController::class, 'createOrUpdate']);
|
||||
Route::get('/trainings/{id}', [TrainingController::class, 'show']);
|
||||
Route::delete('/trainings/{id}', [TrainingController::class, 'destroy']);
|
||||
|
||||
Route::get('/logs', [LogsController::class, 'index']);
|
||||
Route::get('/logs', [LogsController::class, 'index'])->middleware(ETag::class);
|
||||
|
||||
Route::post('/telegram_login_token', [TelegramController::class, 'loginToken']);
|
||||
|
||||
|
|
|
@ -59,7 +59,8 @@
|
|||
"scripts": [],
|
||||
"serviceWorker": true,
|
||||
"ngswConfigPath": "ngsw-config.json",
|
||||
"sourceMap": true
|
||||
"sourceMap": true,
|
||||
"allowedCommonJsDependencies": ["crypto-js"]
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
|
|
|
@ -26,6 +26,8 @@ export class ModalAlertComponent implements OnInit, OnDestroy {
|
|||
|
||||
alertClosed = 0;
|
||||
|
||||
private etag = "";
|
||||
|
||||
constructor(
|
||||
public bsModalRef: BsModalRef,
|
||||
private api: ApiClientService,
|
||||
|
@ -36,7 +38,9 @@ export class ModalAlertComponent implements OnInit, OnDestroy {
|
|||
|
||||
loadResponsesData() {
|
||||
//TODO: do not update data if not changed. Support for content hash in response header?
|
||||
this.api.get(`alerts/${this.id}`).then((response) => {
|
||||
this.api.get(`alerts/${this.id}`, {}, this.etag).then((response) => {
|
||||
if(this.api.isLastSame) return;
|
||||
this.etag = this.api.lastEtag;
|
||||
console.log(response, this.alertClosed, response.closed);
|
||||
if(this.alertClosed !== response.closed) this.alertClosed = response.closed;
|
||||
if(!isEqual(this.crewUsers, response.crew)) this.crewUsers = response.crew;
|
||||
|
|
|
@ -60,6 +60,7 @@ export class TableComponent implements OnInit, OnDestroy {
|
|||
public data: any = [];
|
||||
public displayedData: any = [];
|
||||
public originalData: any = [];
|
||||
private etag: string = "";
|
||||
|
||||
public loadDataInterval: NodeJS.Timer | undefined = undefined;
|
||||
|
||||
|
@ -87,7 +88,9 @@ export class TableComponent implements OnInit, OnDestroy {
|
|||
|
||||
loadTableData() {
|
||||
if(!this.sourceType) this.sourceType = "list";
|
||||
this.api.get(this.sourceType).then((data: any) => {
|
||||
this.api.get(this.sourceType, {}, this.etag).then((data: any) => {
|
||||
if(this.api.isLastSame) return;
|
||||
this.etag = this.api.lastEtag;
|
||||
this.data = data.filter((row: any) => typeof row.hidden !== 'undefined' ? !row.hidden : true);
|
||||
this.originalData = this.data;
|
||||
this.totalElements = this.data.length;
|
||||
|
|
|
@ -25,6 +25,8 @@ export class ListComponent implements OnInit, OnDestroy {
|
|||
|
||||
public alertLoading = false;
|
||||
|
||||
private etag = "";
|
||||
|
||||
constructor(
|
||||
public api: ApiClientService,
|
||||
public auth: AuthService,
|
||||
|
@ -35,7 +37,9 @@ export class ListComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
loadAvailability() {
|
||||
this.api.get("availability").then((response) => {
|
||||
this.api.get("availability", {}, this.etag).then((response) => {
|
||||
if(this.api.isLastSame) return;
|
||||
this.etag = this.api.lastEtag;
|
||||
this.available = response.available;
|
||||
this.manual_mode = response.manual_mode;
|
||||
}).catch((err) => {
|
||||
|
|
|
@ -8,6 +8,9 @@ import { Subject } from "rxjs";
|
|||
export class ApiClientService {
|
||||
private apiRoot = 'api/';
|
||||
|
||||
public lastEtag = "";
|
||||
public isLastSame = false;
|
||||
|
||||
public alertsChanged = new Subject<void>();
|
||||
public availableUsers: undefined | number = undefined;
|
||||
|
||||
|
@ -20,12 +23,20 @@ export class ApiClientService {
|
|||
return this.apiRoot + endpoint;
|
||||
}
|
||||
|
||||
public get(endpoint: string, data: any = {}) {
|
||||
public get(endpoint: string, data: any = {}, etag: string = "") {
|
||||
return new Promise<any>((resolve, reject) => {
|
||||
this.http.get(this.apiEndpoint(endpoint), {
|
||||
params: new HttpParams({ fromObject: data })
|
||||
params: new HttpParams({ fromObject: data }),
|
||||
observe: 'response',
|
||||
headers: (etag !== "" && etag !== null) ? {
|
||||
'If-None-Match': etag
|
||||
} : {}
|
||||
}).subscribe({
|
||||
next: (v) => resolve(v),
|
||||
next: (v: any) => {
|
||||
this.lastEtag = v.headers.get("etag");
|
||||
this.isLastSame = etag === this.lastEtag;
|
||||
resolve(v.body);
|
||||
},
|
||||
error: (e) => reject(e)
|
||||
});
|
||||
});
|
||||
|
|
|
@ -21,6 +21,7 @@ export class AppComponent {
|
|||
public loadingRoute = false;
|
||||
private loadAlertsInterval: NodeJS.Timer | undefined = undefined;
|
||||
public alerts = [];
|
||||
private alertsEtag = "";
|
||||
|
||||
constructor(
|
||||
public auth: AuthService,
|
||||
|
@ -37,8 +38,10 @@ export class AppComponent {
|
|||
|
||||
loadAlerts() {
|
||||
if(this.auth.profile) {
|
||||
this.api.get("alerts").then((response) => {
|
||||
this.api.get("alerts", {}, this.alertsEtag).then((response) => {
|
||||
if(this.api.isLastSame) return;
|
||||
this.alerts = response;
|
||||
this.alertsEtag = this.api.lastEtag;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue