From 9c8e6581de9599f34d231a141134af015cb28be5 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Thu, 9 Mar 2023 14:12:42 +0100 Subject: [PATCH] relax unique constraint on techniques --- app/Http/Controllers/TechniqueController.php | 41 +++++++++++++------ ...2023_03_09_125727_tech_unique_per_type.php | 34 +++++++++++++++ resources/js/components/App.js | 16 ++++++++ resources/js/components/pages/Technique.js | 11 +++-- resources/js/components/pages/Techniques.js | 7 +--- resources/js/helpers/Technique.js | 6 +++ routes/api.php | 3 ++ 7 files changed, 97 insertions(+), 21 deletions(-) create mode 100644 database/migrations/2023_03_09_125727_tech_unique_per_type.php diff --git a/app/Http/Controllers/TechniqueController.php b/app/Http/Controllers/TechniqueController.php index b27465e..7173f1e 100644 --- a/app/Http/Controllers/TechniqueController.php +++ b/app/Http/Controllers/TechniqueController.php @@ -10,6 +10,19 @@ use Illuminate\Http\Request; class TechniqueController extends Controller { + public function byType(Request $request, $type) { + $techs = Technique::where('index', true)->where('type', '=', $type); + $this->applyFilter($request, $techs); + return $techs->get()->toJson(); + } + + public function byTypeAndName(Request $request, $type, $name) { + $tech = Technique::where('type', '=', $type)->where('name', '=', $name)->firstOrFail(); + $this->authorize('view', $tech); + $tech->load(['chapters', 'relations']); + return $tech->toJson(); + } + public function forMap($map) { $techs = TechniqueMap::with(['technique', 'technique.relations'])->where('map', '=', $map); @@ -17,6 +30,18 @@ class TechniqueController extends Controller } public function search(Request $request) { + $techs = Technique::where('index', '=', 1); + $this->applyFilter($request, $techs); + return $techs->get()->toJson(); + } + + public function single(Request $request, Technique $tech) { + $this->authorize('view', $tech); + $tech->load(['chapters', 'relations']); + return $tech->toJson(); + } + + protected function applyFilter(Request $request, Builder $query) { $validatedData = $request->validate([ 'phrase' => 'string|nullable', 'ruleset' => 'array|nullable', @@ -27,15 +52,13 @@ class TechniqueController extends Controller 'type' => 'string|nullable', ]); - $techs = Technique::where('index', '=', 1); - if (!empty($validatedData['type'])) { - $techs = $techs->where('type', '=', $validatedData['type']); + $query->where('type', '=', $validatedData['type']); } if (!empty($validatedData['phrase'])) { $search = $validatedData['phrase']; - $techs = $techs->where(function (Builder $query) use ($search) { + $query->where(function (Builder $query) use ($search) { $query->where('title', 'LIKE', '%'.$search.'%') ->orWhere('short', 'LIKE', '%'.$search.'%'); }); @@ -49,7 +72,7 @@ class TechniqueController extends Controller $any = $com || $owg || $mg || $nl; $all = $com && $owg && $mg && $nl; if ($any && !$all) { - $techs->where(function(Builder $query) use ($com, $owg, $mg, $nl) { + $query->where(function(Builder $query) use ($com, $owg, $mg, $nl) { $query->whereNull('rulesets'); if ($com) { $query->orWhere('rulesets->competitive', '=', true); @@ -66,14 +89,6 @@ class TechniqueController extends Controller }); } } - - return $techs->get()->toJson(); - } - - public function single(Request $request, Technique $tech) { - $this->authorize('view', $tech); - $tech->load(['chapters', 'relations']); - return $tech->toJson(); } } diff --git a/database/migrations/2023_03_09_125727_tech_unique_per_type.php b/database/migrations/2023_03_09_125727_tech_unique_per_type.php new file mode 100644 index 0000000..b3624de --- /dev/null +++ b/database/migrations/2023_03_09_125727_tech_unique_per_type.php @@ -0,0 +1,34 @@ +dropUnique(['name']); + $table->unique(['type', 'name']); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('techniques', function(Blueprint $table) { + $table->dropUnique(['type', 'name']); + $table->unique(['name']); + }); + } +}; diff --git a/resources/js/components/App.js b/resources/js/components/App.js index a26683c..3ad2494 100644 --- a/resources/js/components/App.js +++ b/resources/js/components/App.js @@ -70,7 +70,23 @@ const App = () => {
+ } + /> + } + /> } /> + } + /> + } + /> } /> { +const Technique = ({ type }) => { const params = useParams(); const { name } = params; @@ -25,7 +26,7 @@ const Technique = () => { const ctrl = new AbortController(); setLoading(true); axios - .get(`/api/tech/${name}`, { signal: ctrl.signal }) + .get(`/api/pages/${type}/${name}`, { signal: ctrl.signal }) .then(response => { setError(null); setLoading(false); @@ -39,7 +40,7 @@ const Technique = () => { return () => { ctrl.abort(); }; - }, [name]); + }, [name, type]); if (loading) { return ; @@ -67,4 +68,8 @@ const Technique = () => { ; }; +Technique.propTypes = { + type: PropTypes.string, +}; + export default withTranslation()(Technique); diff --git a/resources/js/components/pages/Techniques.js b/resources/js/components/pages/Techniques.js index ebeb6e5..c2d7aec 100644 --- a/resources/js/components/pages/Techniques.js +++ b/resources/js/components/pages/Techniques.js @@ -39,11 +39,8 @@ const Techniques = ({ namespace, type }) => { setLoading(true); } axios - .get(`/api/content`, { - params: { - type, - ...filter, - }, + .get(`/api/pages/${type}`, { + params: filter, signal: ctrl.signal }) .then(response => { diff --git a/resources/js/helpers/Technique.js b/resources/js/helpers/Technique.js index b289341..f3daae7 100644 --- a/resources/js/helpers/Technique.js +++ b/resources/js/helpers/Technique.js @@ -1,6 +1,12 @@ import i18n from '../i18n'; export const getLink = tech => { + if (tech.type === 'dungeon') { + return `/dungeons/${tech.name}`; + } + if (tech.type === 'location') { + return `/locations/${tech.name}`; + } if (tech.type === 'mode') { return `/modes/${tech.name}`; } diff --git a/routes/api.php b/routes/api.php index 8fdfad4..c0db87c 100644 --- a/routes/api.php +++ b/routes/api.php @@ -48,6 +48,9 @@ Route::get('events/{event:name}', 'App\Http\Controllers\EventController@single') Route::get('markers/{map}', 'App\Http\Controllers\TechniqueController@forMap'); +Route::get('pages/{type}', 'App\Http\Controllers\TechniqueController@byType'); +Route::get('pages/{type}/{name}', 'App\Http\Controllers\TechniqueController@byTypeAndName'); + Route::get('protocol/{tournament}', 'App\Http\Controllers\ProtocolController@forTournament'); Route::post('results', 'App\Http\Controllers\ResultController@create'); -- 2.39.2