From 792de8b342be2118cf6e0fc097ecfbf676593454 Mon Sep 17 00:00:00 2001 From: Kovah Date: Wed, 6 Oct 2021 09:02:50 +0200 Subject: [PATCH] Notify users if a link already exists in create and edit forms (#318) --- .../Controllers/App/BookmarkletController.php | 2 ++ app/Http/Controllers/FetchController.php | 10 +++++++--- .../Controllers/Models/LinkController.php | 5 ++++- resources/assets/js/components/UrlField.js | 11 +++++++++-- resources/lang/en_US/link.php | 1 + resources/views/models/links/edit.blade.php | 6 +++++- .../links/partials/create-form.blade.php | 19 ++++++++++--------- .../App/BookmarkletControllerTest.php | 15 +++++++++++++++ 8 files changed, 53 insertions(+), 16 deletions(-) diff --git a/app/Http/Controllers/App/BookmarkletController.php b/app/Http/Controllers/App/BookmarkletController.php index 08465086..9b8b19cd 100644 --- a/app/Http/Controllers/App/BookmarkletController.php +++ b/app/Http/Controllers/App/BookmarkletController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers\App; use App\Http\Controllers\Controller; +use App\Models\Link; use Illuminate\Contracts\View\Factory; use Illuminate\Contracts\View\View; use Illuminate\Http\RedirectResponse; @@ -43,6 +44,7 @@ public function getLinkAddForm(Request $request) session(['bookmarklet.create' => true]); return view('app.bookmarklet.create', [ + 'existing_link' => Link::withTrashed()->whereUrl($newUrl)->first() ?: false, 'bookmark_url' => $newUrl, 'bookmark_title' => $newTitle, 'bookmark_description' => $newDescription, diff --git a/app/Http/Controllers/FetchController.php b/app/Http/Controllers/FetchController.php index bbc75f9d..55867532 100644 --- a/app/Http/Controllers/FetchController.php +++ b/app/Http/Controllers/FetchController.php @@ -92,11 +92,15 @@ public function searchExistingUrls(Request $request): JsonResponse return response()->json([]); } - $linkCount = Link::byUser(auth()->user()->id) + $link = Link::byUser(auth()->user()->id) ->where('url', trim($query)) - ->count(); + ->where('id', '!=', $request->input('ignore_id', 0)) + ->first(); - return response()->json(['linkFound' => $linkCount > 0]); + return response()->json([ + 'linkFound' => $link !== null, + 'editLink' => $link ? route('links.edit', ['link' => $link]) : null, + ]); } /** diff --git a/app/Http/Controllers/Models/LinkController.php b/app/Http/Controllers/Models/LinkController.php index 19593474..fe7a2402 100644 --- a/app/Http/Controllers/Models/LinkController.php +++ b/app/Http/Controllers/Models/LinkController.php @@ -49,7 +49,9 @@ public function create(): View // Reset the bookmarklet session identifier to prevent issues on regular pages session()->forget('bookmarklet.create'); - return view('models.links.create'); + return view('models.links.create', [ + 'existing_link' => null, + ]); } /** @@ -115,6 +117,7 @@ public function edit(Link $link): View { return view('models.links.edit', [ 'link' => $link, + 'existing_link' => null, ]); } diff --git a/resources/assets/js/components/UrlField.js b/resources/assets/js/components/UrlField.js index aa94e45d..f4a7a563 100644 --- a/resources/assets/js/components/UrlField.js +++ b/resources/assets/js/components/UrlField.js @@ -8,6 +8,8 @@ export default class UrlField { this.$field = $el; this.$field.addEventListener('keyup', this.onKeyup.bind(this)); + this.$linkExistsWarning = document.querySelector('.link-exists'); + this.$linkExistsLink = this.$linkExistsWarning.querySelector('a'); const $tags = document.querySelector('#tags'); this.tagSuggestions = $tags ? getInstance($tags, TagsSelect) : null; @@ -20,14 +22,14 @@ export default class UrlField { // Check for existing links if the value is longer than http:// if (value.length > 6) { - this.checkforExistingUrl(value); + this.checkForExistingUrl(value); } else { this.resetField(); } }); } - checkforExistingUrl (url) { + checkForExistingUrl (url) { const checkUrl = window.appData.routes.fetch.existingLinks; fetch(checkUrl, { @@ -36,6 +38,7 @@ export default class UrlField { headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ _token: window.appData.user.token, + ignore_id: this.$field.dataset.ignoreId ?? null, query: url }) }).then((response) => { @@ -45,8 +48,12 @@ export default class UrlField { // If the link already exist, mark the field as invalid if (result.linkFound === true) { this.$field.classList.add('is-invalid'); + this.$linkExistsLink.href = result.editLink; + this.$linkExistsWarning.classList.remove('d-none'); } else { this.$field.classList.remove('is-invalid'); + this.$linkExistsWarning.classList.add('d-none'); + this.$linkExistsLink.href = ''; this.querySiteForMetaTags(url); } diff --git a/resources/lang/en_US/link.php b/resources/lang/en_US/link.php index e95ba19f..810f47bb 100644 --- a/resources/lang/en_US/link.php +++ b/resources/lang/en_US/link.php @@ -59,6 +59,7 @@ 'deletion_error' => 'Link could not be deleted.', 'duplicates_found' => 'LinkAce found possible duplicates of the submitted URL:', + 'existing_found' => 'A Link with that URL already exists.', 'notifications.linkcheck.errors' => 'LinkAce found errors while checking your Links.', 'notifications.linkcheck.errors.moved' => '⚠ ️The following Links moved to a new location:', diff --git a/resources/views/models/links/edit.blade.php b/resources/views/models/links/edit.blade.php index 4ca1e3e5..058f409e 100644 --- a/resources/views/models/links/edit.blade.php +++ b/resources/views/models/links/edit.blade.php @@ -16,10 +16,14 @@
- + @if ($errors->has('url'))
-

- @lang('validation.unique', ['attribute' => trans('link.url')]) +

- @if ($errors->has('url')) - - @endif + @error('url') + + @enderror
@@ -44,7 +45,7 @@ class="form-control{{ $errors->has('title') ? ' is-invalid' : '' }}"
+ >{{ old('description') ?: $bookmark_description ?? '' }} @if ($errors->has('description'))