From 6fe3601aa745bb314ac00ee6c6b5039c3467ba92 Mon Sep 17 00:00:00 2001 From: LT Date: Sat, 15 Jul 2023 21:29:59 +0200 Subject: [PATCH] feat(fields): Json Only values mode --- src/Fields/Json.php | 69 ++++++++++++++++++++++------- src/Traits/Fields/HasOneOrMany.php | 6 +-- tests/Unit/Fields/JsonFieldTest.php | 23 ++++++++++ 3 files changed, 78 insertions(+), 20 deletions(-) diff --git a/src/Fields/Json.php b/src/Fields/Json.php index df7912f10..a2f4782c2 100644 --- a/src/Fields/Json.php +++ b/src/Fields/Json.php @@ -7,7 +7,6 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Collection; use MoonShine\Contracts\Fields\DefaultValueTypes\DefaultCanBeArray; -use MoonShine\Contracts\Fields\Fileable; use MoonShine\Contracts\Fields\HasDefaultValue; use MoonShine\Contracts\Fields\HasFields; use MoonShine\Contracts\Fields\HasFullPageMode; @@ -40,6 +39,8 @@ class Json extends Field implements protected bool $keyValue = false; + protected bool $onlyValue = false; + protected bool $group = true; /** @@ -50,6 +51,7 @@ public function keyValue( string $value = 'Value' ): static { $this->keyValue = true; + $this->onlyValue = false; $this->fields([ Text::make($key, 'key') @@ -62,6 +64,23 @@ public function keyValue( return $this; } + /** + * @throws Throwable + */ + public function onlyValue( + string $value = 'Value' + ): static { + $this->keyValue = false; + $this->onlyValue = true; + + $this->fields([ + Text::make($value, 'value') + ->customAttributes($this->attributes()->getAttributes()), + ]); + + return $this; + } + /** * @throws Throwable */ @@ -76,16 +95,14 @@ public function save(Model $item): Model $requestValues = $this->requestValue(); foreach ($requestValues as $index => $values) { - foreach ($this->getFields() as $field) { - if ($field instanceof Fileable) { - $field->setParentRequestValueKey( - $this->field() . "." . $index - ); - - $requestValues[$index][$field->field()] = $field->hasManyOrOneSave( - $values[$field->field()] ?? null - ); - } + foreach ($this->getFields()->onlyFileFields() as $field) { + $field->setParentRequestValueKey( + $this->field() . "." . $index + ); + + $requestValues[$index][$field->field()] = $field->hasManyOrOneSave( + $values[$field->field()] ?? null + ); } } @@ -103,7 +120,7 @@ protected function mapKeyValue(Collection $collection): array $fields = $this->getFields()->formFields(); $collection = $collection->map(function ($data) use ($fields) { foreach ($fields as $field) { - if ($field instanceof Json && $field->isKeyValue()) { + if ($field instanceof Json && $field->isKeyOrOnlyValue()) { $data[$field->field()] = $field->mapKeyValue( collect($data[$field->field()] ?? []) ); @@ -115,9 +132,11 @@ protected function mapKeyValue(Collection $collection): array } return $collection->when( - $this->isKeyValue(), - static fn ($data): Collection => $data->mapWithKeys( - static fn ($data): array => [$data['key'] => $data['value']] + $this->isKeyOrOnlyValue(), + fn ($data): Collection => $data->mapWithKeys( + fn ($data, $key): array => $this->isOnlyValue() + ? [$key => $data['value']] + : [$data['key'] => $data['value']] ) )->toArray(); } @@ -127,13 +146,23 @@ public function isKeyValue(): bool return $this->keyValue; } + public function isOnlyValue(): bool + { + return $this->onlyValue; + } + + public function isKeyOrOnlyValue(): bool + { + return $this->keyValue || $this->onlyValue; + } + public function formViewValue(Model $item): mixed { - if ($this->isKeyValue()) { + if ($this->isKeyOrOnlyValue()) { return collect(parent::formViewValue($item)) ->map( fn ($data, $index): array => $this->extractValues( - [$index => $data] + $this->isOnlyValue() ? [$data] : [$index => $data] ) ) ->values() @@ -152,6 +181,12 @@ public function extractValues(array $data): array ]; } + if ($this->isOnlyValue()) { + return [ + 'value' => $data[key($data)] ?? '', + ]; + } + return $data; } } diff --git a/src/Traits/Fields/HasOneOrMany.php b/src/Traits/Fields/HasOneOrMany.php index 26ec332e3..51b544989 100644 --- a/src/Traits/Fields/HasOneOrMany.php +++ b/src/Traits/Fields/HasOneOrMany.php @@ -75,14 +75,14 @@ public function save(Model $item): Model unset($values[$field->field()]); } - if ($field instanceof Json && $field->isKeyValue()) { + if ($field instanceof Json && $field->isKeyOrOnlyValue()) { $values[$field->field()] = collect( $values[$field->field()] ?? [] ) ->mapWithKeys( static fn ( - $data - ): array => [$data['key'] => $data['value']] + $data, $key + ): array => $field->isOnlyValue() ? [$key => $data['value']] : [$data['key'] => $data['value']] ) ->filter(); } diff --git a/tests/Unit/Fields/JsonFieldTest.php b/tests/Unit/Fields/JsonFieldTest.php index 14656d546..ef55d1188 100644 --- a/tests/Unit/Fields/JsonFieldTest.php +++ b/tests/Unit/Fields/JsonFieldTest.php @@ -16,12 +16,19 @@ ->fields(exampleFields()->toArray()); $this->fieldKeyValue = Json::make('Key value') ->keyValue(); + $this->fieldOnlyValue = Json::make('Only value') + ->onlyValue(); $this->item = new class () extends Model { public array $key_value = [ 'key1' => 'value1', 'key2' => 'value2', ]; + public array $only_value = [ + 'value1', + 'value2', + ]; + public array $json = [ ['field1' => 'field1_value', 'field2' => 'field2_value'], ]; @@ -136,3 +143,19 @@ ]) ; }); + +it('json values only value', function (): void { + expect($this->fieldOnlyValue->jsonValues()) + ->toBeArray() + ->toBe( + exampleFields() + ->mapWithKeys(fn ($f, $k) => ['value' => '']) + ->toArray() + ) + ->and($this->fieldOnlyValue->jsonValues($this->item)) + ->toBe([ + ['value' => 'value1'], + ['value' => 'value2'], + ]) + ; +});