Skip to content

Commit

Permalink
Merge pull request #390 from lee-to/only-value-json
Browse files Browse the repository at this point in the history
feat(fields): Json
  • Loading branch information
lee-to authored Jul 15, 2023
2 parents d23c9ea + 6fe3601 commit 9285acd
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 20 deletions.
69 changes: 52 additions & 17 deletions src/Fields/Json.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -40,6 +39,8 @@ class Json extends Field implements

protected bool $keyValue = false;

protected bool $onlyValue = false;

protected bool $group = true;

/**
Expand All @@ -50,6 +51,7 @@ public function keyValue(
string $value = 'Value'
): static {
$this->keyValue = true;
$this->onlyValue = false;

$this->fields([
Text::make($key, 'key')
Expand All @@ -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
*/
Expand All @@ -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
);
}
}

Expand All @@ -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()] ?? [])
);
Expand All @@ -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();
}
Expand All @@ -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()
Expand All @@ -152,6 +181,12 @@ public function extractValues(array $data): array
];
}

if ($this->isOnlyValue()) {
return [
'value' => $data[key($data)] ?? '',
];
}

return $data;
}
}
6 changes: 3 additions & 3 deletions src/Traits/Fields/HasOneOrMany.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
23 changes: 23 additions & 0 deletions tests/Unit/Fields/JsonFieldTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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'],
];
Expand Down Expand Up @@ -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'],
])
;
});

0 comments on commit 9285acd

Please sign in to comment.