Implement feature flags and update views

This commit implements feature flags using the "ylsideas/feature-flags" library and updates various frontend views to show or hide sections based on the feature flag. Additionally, a new migration file is created for the features database table and the LibraryItem model is updated with a new searchLibraryItems function. The composer.json and composer.lock files are updated to include the new dependencies.
This commit is contained in:
HolgerHatGarKeineNode
2023-12-08 21:40:48 +01:00
parent 245ebc9220
commit 0c820be43b
27 changed files with 377 additions and 98 deletions

24
.features.php.dist Normal file
View File

@@ -0,0 +1,24 @@
<?php
use Illuminate\Contracts\Foundation\Application;
/**
* @returns array<string, bool>
*/
return static function (Application $app): array {
return [
'change.country' => false,
'change.language' => true,
'news' => false,
'courses' => false,
'library' => false,
'events' => true,
'bookcases' => false,
'meetups' => true,
'association' => false,
'nostr.groups' => false,
'nostr.plebs' => false,
];
};

2
.gitignore vendored
View File

@@ -30,3 +30,5 @@ yarn-error.log
!.yarn/releases
.blueprint
.features.php

View File

@@ -14,19 +14,12 @@ class Gallery extends Component
public function mount()
{
$this->bindles = LibraryItem::query()
->where('type', 'bindle')
->latest('id')
->get();
$this->bindles = LibraryItem::searchLibraryItems('bindle');
}
public function updatedSearch($value)
{
$this->bindles = LibraryItem::query()
->where('type', 'bindle')
->where('name', 'ilike', "%{$value}%")
->latest('id')
->get();
$this->bindles = LibraryItem::searchLibraryItems('bindle', $value);
}
public function deleteBindle($id)

View File

@@ -164,4 +164,17 @@ class LibraryItem extends Model implements HasMedia, Sortable, Feedable
->link(url()->route('article.view', ['libraryItem' => $this]))
->authorName($this->lecturer->name);
}
public static function searchLibraryItems($type, $value = null)
{
$query = self::query()
->where('type', $type)
->latest('id');
if ($value) {
$query->where('name', 'ilike', "%{$value}%");
}
return $query->get();
}
}

View File

@@ -65,6 +65,7 @@
"symfony/mailgun-mailer": "^6.2",
"wesselperik/nova-status-field": "^2.1",
"wireui/wireui": "^1.17.9",
"ylsideas/feature-flags": "^2.0",
"ziffmedia/nova-select-plus": "^2.0"
},
"require-dev": {

80
composer.lock generated
View File

@@ -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": "2c9601391937e04775f009c27b16b988",
"content-hash": "70c5fa8fde773985983d2761e278c402",
"packages": [
{
"name": "akuechler/laravel-geoly",
@@ -14560,6 +14560,84 @@
],
"time": "2023-10-25T05:42:02+00:00"
},
{
"name": "ylsideas/feature-flags",
"version": "v2.4.2",
"source": {
"type": "git",
"url": "https://github.com/ylsideas/feature-flags.git",
"reference": "39baec4645098c3d5bc52d4e5c3c5b2bc4204f94"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ylsideas/feature-flags/zipball/39baec4645098c3d5bc52d4e5c3c5b2bc4204f94",
"reference": "39baec4645098c3d5bc52d4e5c3c5b2bc4204f94",
"shasum": ""
},
"require": {
"illuminate/contracts": "10.*|^9.6",
"php": "^8.1"
},
"require-dev": {
"laravel/pint": "^1.2",
"nunomaduro/collision": "^6.0|^5.0",
"nunomaduro/larastan": "^2.0|^1.0",
"orchestra/testbench": "^8.0|^7.0",
"pestphp/pest": "^1.21",
"pestphp/pest-plugin-laravel": "^1.1",
"phpstan/extension-installer": "^1.1",
"phpstan/phpdoc-parser": "^1.15",
"phpstan/phpstan-deprecation-rules": "^1.0",
"phpstan/phpstan-phpunit": "^1.0",
"phpunit/phpunit": "^9.5.13",
"rector/rector": "^0.14.2",
"spatie/laravel-ray": "^1.26"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"YlsIdeas\\FeatureFlags\\FeatureFlagsServiceProvider"
],
"aliases": {
"Features": "YlsIdeas\\FeatureFlags\\Facades\\Features"
}
}
},
"autoload": {
"psr-4": {
"YlsIdeas\\FeatureFlags\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Peter Fox",
"email": "peter.fox@ylsideas.co",
"role": "Developer"
}
],
"description": "A Laravel package for handling feature flags",
"homepage": "https://github.com/ylsideas/feature-flags",
"keywords": [
"feature-flags",
"ylsideas"
],
"support": {
"issues": "https://github.com/ylsideas/feature-flags/issues",
"source": "https://github.com/ylsideas/feature-flags/tree/v2.4.2"
},
"funding": [
{
"url": "https://github.com/peterfox",
"type": "github"
}
],
"time": "2023-12-01T18:56:48+00:00"
},
{
"name": "zbateson/mail-mime-parser",
"version": "2.4.0",

51
config/features.php Normal file
View File

@@ -0,0 +1,51 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Pipeline
|--------------------------------------------------------------------------
|
| The pipeline for the feature to travel through.
|
*/
'pipeline' => ['database', 'in_memory'],
/*
|--------------------------------------------------------------------------
| Gateways
|--------------------------------------------------------------------------
|
| Configures the different gateway options
|
*/
'gateways' => [
'in_memory' => [
'file' => env('FEATURE_FLAG_IN_MEMORY_FILE', '.features.php'),
'driver' => 'in_memory',
],
'database' => [
'driver' => 'database',
'cache' => [
'ttl' => 600,
],
'connection' => env('FEATURE_FLAG_DATABASE_CONNECTION'),
'table' => env('FEATURE_FLAG_DATABASE_TABLE', 'features'),
],
'gate' => [
'driver' => 'gate',
'gate' => env('FEATURE_FLAG_GATE_GATE', 'feature'),
'guard' => env('FEATURE_FLAG_GATE_GUARD'),
'cache' => [
'ttl' => 600,
],
],
'redis' => [
'driver' => 'redis',
'prefix' => env('FEATURE_FLAG_REDIS_PREFIX', 'features'),
'connection' => env('FEATURE_FLAG_REDIS_CONNECTION', 'default'),
],
],
];

View File

@@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateFeaturesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('features', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('title')->nullable();
$table->string('feature')->unique();
$table->text('description')->nullable();
$table->timestamp('active_at')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('features');
}
}

View File

@@ -156,6 +156,7 @@
{{-- FOOTER --}}
<livewire:frontend.footer/>
@feature('nostr.groups')
<div wire:ignore class="z-50 hidden md:block">
<script
src="{{ asset('dist/einundzwanzig.chat.js') }}"
@@ -166,4 +167,6 @@
></script>
<link rel="stylesheet" href="{{ asset('dist/einundzwanzig.chat.css') }}">
</div>
@endfeature
</div>

View File

@@ -21,6 +21,7 @@
{{-- FOOTER --}}
<livewire:frontend.footer/>
@feature('nostr.groups')
<div wire:ignore class="z-50 hidden md:block">
<script
src="{{ asset('dist/einundzwanzig.chat.js') }}"
@@ -31,4 +32,6 @@
></script>
<link rel="stylesheet" href="{{ asset('dist/einundzwanzig.chat.css') }}">
</div>
@endfeature
</div>

View File

@@ -67,6 +67,7 @@
{{-- FOOTER --}}
<livewire:frontend.footer/>
@feature('nostr.groups')
<div wire:ignore class="z-50 hidden md:block">
<script
src="{{ asset('dist/einundzwanzig.chat.js') }}"
@@ -77,4 +78,6 @@
></script>
<link rel="stylesheet" href="{{ asset('dist/einundzwanzig.chat.css') }}">
</div>
@endfeature
</div>

View File

@@ -161,6 +161,7 @@
{{-- FOOTER --}}
<livewire:frontend.footer/>
@feature('nostr.groups')
<div wire:ignore class="z-50 hidden md:block">
<script
src="{{ asset('dist/einundzwanzig.chat.js') }}"
@@ -171,4 +172,6 @@
></script>
<link rel="stylesheet" href="{{ asset('dist/einundzwanzig.chat.css') }}">
</div>
@endfeature
</div>

View File

@@ -54,6 +54,7 @@
{{-- FOOTER --}}
<livewire:frontend.footer/>
@feature('nostr.groups')
<div wire:ignore class="z-50 hidden md:block">
<script
src="{{ asset('dist/einundzwanzig.chat.js') }}"
@@ -64,4 +65,6 @@
></script>
<link rel="stylesheet" href="{{ asset('dist/einundzwanzig.chat.css') }}">
</div>
@endfeature
</div>

View File

@@ -19,19 +19,33 @@
</div>
<div class="hidden lg:flex lg:gap-x-8" x-data="Components.popoverGroup()" x-init="init()">
@feature('news')
@include('livewire.frontend.navigation.news')
@endfeature
@feature('meetups')
@include('livewire.frontend.navigation.meetups')
@endfeature
@feature('courses')
@include('livewire.frontend.navigation.courses')
@endfeature
@feature('library')
@include('livewire.frontend.navigation.library')
@endfeature
@feature('events')
@include('livewire.frontend.navigation.events')
@endfeature
@feature('bookcases')
@include('livewire.frontend.navigation.bookcases')
@endfeature
@feature('association')
@include('livewire.frontend.navigation.association')
@endfeature
@auth
@include('livewire.frontend.navigation.profile')

View File

@@ -45,6 +45,7 @@
{{ __('Meetup dates') }}
</a>
@feature('nostr.plebs')
<a href="{{ route('nostr.plebs') }}"
class="flex gap-x-4 py-2 text-sm font-semibold leading-6 text-gray-900">
<svg class="svg-inline--fa flex-none text-gray-400 w-6 h-5 mr-2 -ml-1" fill="#000000"
@@ -141,6 +142,7 @@
</svg>
{{ __('Plebs on Nostr') }}
</a>
@endfeature
</div>
</div>

View File

@@ -1,4 +1,5 @@
<div class="min-h-screen bg-21gray flex flex-col justify-between">
<section class="relative px-10 pt-16 pb-24 sm:py-16 sm:overflow-hidden">
<img class="absolute h-43 left-0 z-0 w-3/4 transform -translate-y-1/2 opacity-70 top-1/2"
src="{{ asset('img/gradient-blob.svg') }}">
@@ -13,6 +14,7 @@
</p>
<div
class="max-w-sm text-lg text-gray-200 space-y-2 sm:space-y-0 sm:space-x-2 flex flex-col sm:flex-row items-start sm:items-end">
@feature('change.country')
<x-native-select
label="{{ __('Change country') }}"
wire:model="c"
@@ -20,6 +22,8 @@
option-value="code"
:options="$countries"
/>
@endfeature
@feature('change.language')
<x-select
label="{{ __('Change language') }}"
wire:model="l"
@@ -29,6 +33,7 @@
option-label="name"
option-value="language"
/>
@endfeature
<div class="py-2 sm:py-0">
@if(!auth()->check())
<x-button secondary href="{{ route('auth.login') }}">
@@ -50,6 +55,7 @@
<div class="grid w-full grid-cols-1 gap-8 sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4">
{{-- News --}}
@feature('news')
<div class="row-span-2 col-span-full sm:col-span-1 md:col-start-1 sm:row-start-2 md:row-start-3">
<a href="{{ route('article.overview') }}"
class="relative flex flex-col items-start justify-end w-full h-full overflow-hidden bg-black shadow-lg rounded-xl group"
@@ -68,7 +74,9 @@
</div>
</a>
</div>
@endfeature
@feature('courses')
<div
class="row-span-2 col-span-full sm:col-span-1 md:col-start-1 xl:col-start-2 sm:row-start-4 md:row-start-5 xl:row-start-2">
<a href="{{ route('school.table.course', ['country' => $c]) }}"
@@ -90,7 +98,9 @@
</div>
</a>
</div>
@endfeature
@feature('library')
<div
class="row-span-2 col-span-full sm:col-span-1 md:col-start-2 xl:col-start-2 sm:row-start-6 md:row-start-2 xl:row-start-4">
<a href="{{ route('library.table.libraryItems', ['country' => $c]) }}"
@@ -112,7 +122,9 @@
</div>
</a>
</div>
@endfeature
@feature('events')
<div
class="row-span-2 col-span-full sm:col-span-1 md:col-start-2 xl:col-start-3 sm:row-start-1 md:row-start-4 xl:row-start-1">
<a href="{{ route('bitcoinEvent.table.bitcoinEvent', ['country' => $c]) }}"
@@ -134,7 +146,9 @@
</div>
</a>
</div>
@endfeature
@feature('bookcases')
<div
class="row-span-2 col-span-full sm:col-span-1 md:col-start-3 xl:col-start-3 sm:row-start-3 md:row-start-1 xl:row-start-3">
<a href="{{ route('bookCases.world', ['country' => $c]) }}"
@@ -156,7 +170,9 @@
</div>
</a>
</div>
@endfeature
@feature('meetups')
<div
class="row-span-2 col-span-full sm:col-span-1 md:col-start-3 xl:col-start-4 sm:row-start-5 md:row-start-3 xl:row-start-2">
<a href="{{ route('meetup.table.meetup', ['country' => $c]) }}"
@@ -176,6 +192,7 @@
</div>
</a>
</div>
@endfeature
</div>
</div>
@@ -185,6 +202,7 @@
<livewire:frontend.footer/>
</div>
@feature('nostr.groups')
<div wire:ignore class="z-50 hidden md:block">
<script
src="{{ asset('dist/einundzwanzig.chat.js') }}"
@@ -195,4 +213,5 @@
></script>
<link rel="stylesheet" href="{{ asset('dist/einundzwanzig.chat.css') }}">
</div>
@endfeature
</div>

View File

@@ -171,6 +171,7 @@
{{-- FOOTER --}}
<livewire:frontend.footer/>
@feature('nostr.groups')
<div wire:ignore class="z-50 hidden md:block">
<script
src="{{ asset('dist/einundzwanzig.chat.js') }}"
@@ -181,4 +182,6 @@
></script>
<link rel="stylesheet" href="{{ asset('dist/einundzwanzig.chat.css') }}">
</div>
@endfeature
</div>

View File

@@ -117,6 +117,7 @@
{{-- FOOTER --}}
<livewire:frontend.footer/>
@feature('nostr.groups')
<div wire:ignore class="z-50 hidden md:block">
<script
src="{{ asset('dist/einundzwanzig.chat.js') }}"
@@ -127,4 +128,6 @@
></script>
<link rel="stylesheet" href="{{ asset('dist/einundzwanzig.chat.css') }}">
</div>
@endfeature
</div>

View File

@@ -319,6 +319,7 @@
{{-- FOOTER --}}
<livewire:frontend.footer/>
@feature('nostr.groups')
<div wire:ignore class="z-50 hidden md:block">
<script
src="{{ asset('dist/einundzwanzig.chat.js') }}"
@@ -329,4 +330,6 @@
></script>
<link rel="stylesheet" href="{{ asset('dist/einundzwanzig.chat.css') }}">
</div>
@endfeature
</div>

View File

@@ -211,6 +211,7 @@
{{-- FOOTER --}}
<livewire:frontend.footer/>
@feature('nostr.groups')
<div wire:ignore class="z-50 hidden md:block">
<script
src="{{ asset('dist/einundzwanzig.chat.js') }}"
@@ -221,4 +222,6 @@
></script>
<link rel="stylesheet" href="{{ asset('dist/einundzwanzig.chat.css') }}">
</div>
@endfeature
</div>

View File

@@ -61,6 +61,7 @@
{{-- FOOTER --}}
<livewire:frontend.footer/>
@feature('nostr.groups')
<div wire:ignore class="z-50 hidden md:block">
<script
src="{{ asset('dist/einundzwanzig.chat.js') }}"
@@ -71,4 +72,6 @@
></script>
<link rel="stylesheet" href="{{ asset('dist/einundzwanzig.chat.css') }}">
</div>
@endfeature
</div>

View File

@@ -201,6 +201,7 @@
{{-- FOOTER --}}
<livewire:frontend.footer/>
@feature('nostr.groups')
@push('modals')
<div wire:ignore class="z-50 hidden md:block">
<script
@@ -213,4 +214,5 @@
<link rel="stylesheet" href="{{ asset('dist/einundzwanzig.chat.css') }}">
</div>
@endpush
@endfeature
</div>

View File

@@ -37,6 +37,7 @@
</div>
</div>
@feature('nostr.groups')
<div wire:ignore class="z-50 hidden md:block">
<script
src="{{ asset('dist/einundzwanzig.chat.js') }}"
@@ -47,4 +48,6 @@
></script>
<link rel="stylesheet" href="{{ asset('dist/einundzwanzig.chat.css') }}">
</div>
@endfeature
</div>

View File

@@ -340,6 +340,7 @@
});
}})"></div>
@feature('nostr.groups')
@push('modals')
<div wire:ignore class="z-50 hidden md:block">
<script src="https://cdn.jsdelivr.net/npm/party-js@latest/bundle/party.min.js"></script>
@@ -353,4 +354,6 @@
<link rel="stylesheet" href="{{ asset('dist/einundzwanzig.chat.css') }}">
</div>
@endpush
@endfeature
</div>

View File

@@ -227,6 +227,7 @@
</form>
</div>
@feature('nostr.groups')
<div wire:ignore class="z-50 hidden md:block">
<script
src="{{ asset('dist/einundzwanzig.chat.js') }}"
@@ -237,4 +238,6 @@
></script>
<link rel="stylesheet" href="{{ asset('dist/einundzwanzig.chat.css') }}">
</div>
@endfeature
</div>

View File

@@ -192,6 +192,7 @@
{{-- FOOTER --}}
<livewire:frontend.footer/>
@feature('nostr.groups')
<div wire:ignore class="z-50 hidden md:block">
<script
src="{{ asset('dist/einundzwanzig.chat.js') }}"
@@ -202,4 +203,6 @@
></script>
<link rel="stylesheet" href="{{ asset('dist/einundzwanzig.chat.css') }}">
</div>
@endfeature
</div>

View File

@@ -72,6 +72,8 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/vegas/2.5.4/vegas.min.js"
integrity="sha512-lYAcY5E6LZVeNB3Pky37SxbYKzo8A68MzKFoPg5oTuolhRm36D+YRvkrAQS4JuKsaGYeJ5KA5taMEtpNlPUeOA=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
@feature('nostr.groups')
@push('modals')
<div wire:ignore class="z-50 hidden md:block">
<script
@@ -84,4 +86,6 @@
<link rel="stylesheet" href="{{ asset('dist/einundzwanzig.chat.css') }}">
</div>
@endpush
@endfeature
</div>