Refactor Quill handling as a separate database column

This commit is contained in:
Christopher C. Wells 2021-03-08 06:04:54 -08:00 committed by Christopher Charbonneau Wells
parent 99300d1b2d
commit 053c8305a1
7 changed files with 71 additions and 32 deletions

View File

@ -154,6 +154,7 @@ class RecipeController extends Controller
$input = $request->validate([
'name' => ['required', 'string'],
'description' => ['nullable', 'string'],
'description_delta' => ['nullable', 'string'],
'servings' => ['required', 'numeric'],
'time_prep' => ['nullable', 'numeric'],
'time_active' => ['nullable', 'numeric'],
@ -186,6 +187,7 @@ class RecipeController extends Controller
$recipe->fill([
'name' => Str::lower($input['name']),
'description' => $input['description'],
'description_delta' => $input['description_delta'],
'servings' => (int) $input['servings'],
'weight' => $input['weight'],
'time_prep' => (int) $input['time_prep'],

View File

@ -28,7 +28,7 @@ class RecipeSchema extends SchemaProvider
return [
'slug' => $resource->slug,
'name' => $resource->name,
'description' => $resource->description_html,
'description' => $resource->description,
'time_prep' => $resource->time_prep,
'time_active' => $resource->time_active,
'time_total' => $resource->time_total,

View File

@ -62,7 +62,8 @@ use Spatie\Tags\HasTags;
* @method static \Illuminate\Database\Eloquent\Builder|Recipe whereTimeActive($value)
* @method static \Illuminate\Database\Eloquent\Builder|Recipe whereTimePrep($value)
* @method static \Illuminate\Database\Eloquent\Builder|Recipe withUniqueSlugConstraints(\Illuminate\Database\Eloquent\Model $model, string $attribute, array $config, string $slug)
* @property-read string $description_html
* @property string|null $description_delta
* @method static \Illuminate\Database\Eloquent\Builder|Recipe whereDescriptionDelta($value)
*/
final class Recipe extends Model
{
@ -81,6 +82,7 @@ final class Recipe extends Model
protected $fillable = [
'name',
'description',
'description_delta',
'time_prep',
'time_active',
'source',
@ -114,7 +116,6 @@ final class Recipe extends Model
* @inheritdoc
*/
protected $appends = [
'description_html',
'serving_weight',
'time_total',
];
@ -127,30 +128,13 @@ final class Recipe extends Model
return [
'name' => $this->name,
'tags' => $this->tags->pluck('name')->toArray(),
'description' => $this->description_html,
'description' => $this->description,
'source' => $this->source,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
/**
* Get description as an HTML string.
*/
public function getDescriptionHtmlAttribute(): ?string {
$description = $this->description;
if (!empty($description)) {
try {
$quill = new Render($this->description);
$description = $quill->render();
} catch (\Exception $e) {
// TODO: Log this or something.
$description = null;
}
}
return $description;
}
/**
* Get total recipe time.
*/

View File

@ -18,6 +18,7 @@ class CreateRecipesTable extends Migration
$table->string('name');
$table->string('slug')->unique();
$table->longText('description')->nullable();
$table->longText('description_delta')->nullable();
$table->integer('time_prep')->nullable();
$table->integer('time_active')->nullable();
$table->string('source')->nullable();

View File

@ -0,0 +1,45 @@
<?php
use App\Models\Recipe;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddDescriptionDeltaToRecipes extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('recipes', function (Blueprint $table) {
$table->longText('description_delta')->nullable()->after('description');
});
foreach (Recipe::all() as $recipe) {
if (empty($recipe->description)) {
continue;
}
// Format as a basic Quill Delta.
// See: https://quilljs.com/docs/delta/
$delta = ['ops' => [['insert' => "{$recipe->description}\n"]]];
$recipe->description_delta = json_encode($delta);
$recipe->save();
}
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('recipes', function (Blueprint $table) {
$table->dropColumn('description_delta');
});
}
}

View File

@ -76,6 +76,10 @@
:value="old('description', $recipe->description)" />
<div class="quill-editor"></div>
<x-inputs.input name="description_delta"
type="hidden"
:value="old('description_delta', $recipe->description_delta)" />
</div>
<!-- Source -->
@ -152,7 +156,7 @@
theme: 'snow'
});
try {
description.setContents(JSON.parse(document.querySelector('input[name="description"]').value));
description.setContents(JSON.parse(document.querySelector('input[name="description_delta"]').value));
} catch (e) {}
new Draggable.Sortable(document.querySelector('.ingredients'), {
@ -195,8 +199,11 @@
// Remove any hidden templates before form submit.
document.querySelectorAll(':scope .entry-template').forEach(e => e.remove());
// Add description value to hidden field.
document.querySelector('input[name="description"]').value = JSON.stringify(description.getContents());
// Add description values to hidden fields.
document.querySelector('input[name="description_delta"]').value = JSON.stringify(description.getContents());
document.querySelector('input[name="description"]').value = description.root.innerHTML
// Remove extraneous spaces from rendered result.
.replaceAll('<p><br></p>', '');
}
</script>
@endpush

View File

@ -20,15 +20,9 @@
</x-slot>
<div class="flex flex-col-reverse justify-between pb-4 sm:flex-row">
<div x-data="{showNutrientsSummary: false}">
@if($recipe->description_html)
@if($recipe->description)
<section class="mb-2 prose prose-lg md:prose-xl">
{!! $recipe->description_html !!}
</section>
@endif
@if(!$recipe->tags->isEmpty())
<section class="mb-2 text-gray-700 text-sm">
<h1 class="font-extrabold inline">Tags:</h1>
{{ implode(', ', $recipe->tags->pluck('name')->all()) }}
{!! $recipe->description !!}
</section>
@endif
@if($recipe->time_total > 0)
@ -138,4 +132,10 @@
@endif
</footer>
@endif
@if(!$recipe->tags->isEmpty())
<section class="mb-2 text-gray-500 text-sm">
<h1 class="font-extrabold inline">Tags:</h1>
{{ implode(', ', $recipe->tags->pluck('name')->all()) }}
</section>
@endif
</x-app-layout>