Skip to content

Commit b86bdc3

Browse files
committed
Add support for primary field and media field references
1 parent cf1204a commit b86bdc3

File tree

3 files changed

+140
-10
lines changed

3 files changed

+140
-10
lines changed

docs/docs/SDK/10-creating-dataviews.md

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ To create a `DataView` you need to call any of the named constructors available:
1212
- `DataView::list()` - Creates a DataView with a `list` view type.
1313
- `DataView::grid()` - Creates a DataView with a `grid` view type.
1414

15-
The view type used will be the default view type, but you can add support for other view types by declaring the other view types that are supported:
15+
The view type used will be the default view type, but you can add support for other view types by declaring the other
16+
view types that are supported:
1617

1718
```php
1819
$dataview = DataView::table( ... )->supports( View::Grid(), View::List() );
@@ -31,6 +32,32 @@ named constructors will have all the required parameters, and make for a fluent
3132

3233
A DataView has a public API for applying some default settings to the component.
3334

35+
### Primary Field
36+
37+
A DataView can have a primary field. This field is highlighted in each layout type; and can not be hidden. To set this
38+
primary field, you call the `primary_field( Field $field )` method on the instance, and reference the field object you
39+
want to use.
40+
41+
```php
42+
$fields = [
43+
TextField::create( 'author' , 'Author' ),
44+
$title_field => TextField( 'title', 'Title' ), // Store the field instance in a separate variable.
45+
];
46+
47+
$dataview = DataView::table( 'table', $data_source, $fields )
48+
->primary_field( $title_field ); // Set the reference to the field instance.
49+
```
50+
51+
### Media Field
52+
53+
Both the `Grid` and `List` layout try to show a media object for every result. By default, it will look for the first
54+
media field available on the fields; but you can also specify a specific field in case you have multiple images.
55+
56+
```php
57+
$dataview = DataView::table( ... )
58+
->media_field( $media_field ); // Set the reference to the field instance.
59+
```
60+
3461
### Searching
3562

3663
By default, search is enabled on the DataView component. To disable this, you can call the `disable_search()` method on
@@ -126,8 +153,8 @@ the `->deletable( string $label, ?callable $callback = null)` method on the Data
126153
127154
:::note
128155
129-
This functionality requires the DataView to have a `MutableDataSource` which `can_delete()`. This data source is
130-
responsible for deleting the results. If the data source can not delete results, calling the `deleteable()` method will
156+
This functionality requires the DataView to have a `MutableDataSource` which `can_delete()`. This data source is
157+
responsible for deleting the results. If the data source can not delete results, calling the `deleteable()` method will
131158
not do anything.
132159
133160
:::

src/DataView/DataView.php

Lines changed: 76 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,24 @@ final class DataView {
104104
*/
105105
private Pagination $pagination;
106106

107+
/**
108+
* The field used as a media field.
109+
*
110+
* @since $ver$
111+
*
112+
* @var Field|null
113+
*/
114+
private ?Field $media_field = null;
115+
116+
/**
117+
* The field used as the primary field.
118+
*
119+
* @since $ver$
120+
*
121+
* @var Field|null
122+
*/
123+
private ?Field $primary_field = null;
124+
107125
/**
108126
* Whether the DataView supports searching.
109127
*
@@ -428,17 +446,17 @@ private function default_layouts(): array {
428446
* @return string[] The field IDs.
429447
*/
430448
private function get_field_ids( ?callable $filter = null ): array {
431-
$hidden_fields = [];
449+
$field_ids = [];
432450

433451
foreach ( $this->directory_fields as $field ) {
434452
if ( $filter && ! $filter( $field ) ) {
435453
continue;
436454
}
437455

438-
$hidden_fields[] = $field->uuid();
456+
$field_ids[] = $field->uuid();
439457
}
440458

441-
return $hidden_fields;
459+
return $field_ids;
442460
}
443461

444462
/**
@@ -651,17 +669,69 @@ private function add_view_fields( Field ...$fields ): void {
651669
*/
652670
private function layout( View $view ): array {
653671
$output = [];
672+
673+
if ( $this->primary_field ) {
674+
$output['primaryField'] = $this->primary_field->uuid();
675+
}
676+
654677
if ( $view->equals( View::Grid() ) ) {
655678
$output['badgeFields'] = $this->get_field_ids( static fn( Field $field ): bool => $field->is_badge() );
656679
$output['columnFields'] = $this->get_field_ids( static fn( Field $field ): bool => $field->is_column() );
657680
}
658681

682+
if ( ! $view->equals( View::Table() ) ) {
683+
$output['mediaField'] = $this->get_media_field_id();
684+
}
685+
686+
return array_filter( $output );
687+
}
688+
689+
/**
690+
* Returns an instance of the DataView with a primary field.
691+
*
692+
* @since $ver$
693+
*
694+
* @param Field|null $field The primary field.
695+
*
696+
* @return self The DataView.
697+
*/
698+
public function primary_field( ?Field $field ): self {
699+
$this->primary_field = $field;
700+
701+
return $this;
702+
}
703+
704+
/**
705+
* Returns an instance of the DataView with a media field.
706+
*
707+
* @since $ver$
708+
*
709+
* @param Field|null $field The media field.
710+
*
711+
* @return self The DataView.
712+
*/
713+
public function media_field( ?Field $field ): self {
714+
$this->media_field = $field && $field->is_media_field() ? $field : null;
715+
716+
return $this;
717+
}
718+
719+
/**
720+
* Returns the id of the media field.
721+
*
722+
* If no media field is provided, it will assume the first media field it comes across.
723+
*
724+
* @return string The media field id.
725+
*/
726+
private function get_media_field_id(): string {
727+
if ( $this->media_field ) {
728+
return $this->media_field->uuid();
729+
}
730+
659731
$image_fields = $this->get_field_ids(
660732
static fn( Field $field ): bool => $field->is_media_field(),
661733
);
662734

663-
$output['mediaField'] = reset( $image_fields );
664-
665-
return array_filter( $output );
735+
return $image_fields ? reset( $image_fields ) : '';
666736
}
667737
}

tests/DataView/DataViewTest.php

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
use DataKit\DataViews\Data\ArrayDataSource;
66
use DataKit\DataViews\DataView\DataView;
77
use DataKit\DataViews\Field\EnumField;
8+
use DataKit\DataViews\Field\ImageField;
9+
use DataKit\DataViews\Field\TextField;
810
use PHPUnit\Framework\TestCase;
911

1012
/**
@@ -18,7 +20,7 @@ final class DataViewTest extends TestCase {
1820
*
1921
* @since $ver$
2022
*/
21-
public function test_to_js() : void {
23+
public function test_to_js(): void {
2224
$view = DataView::table(
2325
'test',
2426
new ArrayDataSource(
@@ -39,4 +41,35 @@ public function test_to_js() : void {
3941

4042
self::assertStringContainsString( $expected, $view->to_js() );
4143
}
44+
45+
/**
46+
* Test case for {@see DataView::media_field()} and {@see DataView::primary_field()}.
47+
*
48+
* @since $ver$
49+
*/
50+
public function test_primary_and_media_fields(): void {
51+
$data_source = new ArrayDataSource( 'array', [] );
52+
$fields = [
53+
$primary_field = TextField::create( 'primary', 'Primary' ),
54+
$image_field = ImageField::create( 'image', 'Normal image field' ),
55+
$media_field = ImageField::create( 'media', 'Media field' ),
56+
];
57+
58+
$table = DataView::table( 'table', $data_source, $fields )->media_field( $media_field );
59+
$table_2 = DataView::table( 'table-2', $data_source, $fields )->primary_field( $primary_field );
60+
$grid = DataView::grid( 'grid', $data_source, $fields );
61+
$grid_2 = DataView::grid( 'grid-2', $data_source, $fields )
62+
->primary_field( $primary_field )
63+
->media_field( $media_field );
64+
65+
self::assertArrayNotHasKey( 'primaryField', $table->to_array()['view']['layout'] );
66+
self::assertArrayNotHasKey( 'mediaField', $table->to_array()['view']['layout'] );
67+
self::assertArrayHasKey( 'primaryField', $table_2->to_array()['view']['layout'] );
68+
69+
self::assertArrayNotHasKey( 'primaryField', $grid->to_array()['view']['layout'] );
70+
self::assertArrayHasKey( 'primaryField', $grid_2->to_array()['view']['layout'] );
71+
72+
self::assertSame( $image_field->uuid(), $grid->to_array()['view']['layout']['mediaField'] );
73+
self::assertSame( $media_field->uuid(), $grid_2->to_array()['view']['layout']['mediaField'] );
74+
}
4275
}

0 commit comments

Comments
 (0)