Skip to content

Commit 1aa18cc

Browse files
committed
feat: Models picker dialogs + Vue components
1 parent 8283999 commit 1aa18cc

29 files changed

+635
-908
lines changed

config/fields/files.php

Lines changed: 44 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
<?php
22

33
use Kirby\Cms\ModelWithContent;
4-
use Kirby\Data\Data;
5-
use Kirby\Toolkit\A;
4+
use Kirby\Panel\Controller\Dialog\FilesPickerDialogController;
65

76
return [
87
'mixins' => [
9-
'filepicker',
108
'layout',
119
'min',
1210
'picker',
@@ -23,7 +21,8 @@
2321
'placeholder' => null,
2422

2523
/**
26-
* Sets the file(s), which are selected by default when a new page is created
24+
* Sets the file(s), which are selected by default
25+
* when a new page is created
2726
*/
2827
'default' => function ($default = null) {
2928
return $default;
@@ -50,89 +49,57 @@
5049
'parent' => function () {
5150
return $this->parentModel->apiUrl(true);
5251
},
53-
'query' => function () {
54-
return $this->query ?? $this->parentModel::CLASS_ALIAS . '.files';
55-
},
5652
'default' => function () {
57-
return $this->toFiles($this->default);
53+
return $this->toFormValues($this->default);
5854
},
5955
'value' => function () {
60-
return $this->toFiles($this->value);
56+
return $this->toFormValues($this->value);
6157
},
6258
],
6359
'methods' => [
64-
'fileResponse' => function ($file) {
65-
return $file->panel()->pickerData([
66-
'image' => $this->image,
67-
'info' => $this->info ?? false,
68-
'layout' => $this->layout,
69-
'model' => $this->model(),
70-
'text' => $this->text,
71-
]);
72-
},
73-
'toFiles' => function ($value = null) {
74-
$files = [];
75-
76-
foreach (Data::decode($value, 'yaml') as $id) {
77-
if (is_array($id) === true) {
78-
$id = $id['uuid'] ?? $id['id'] ?? null;
79-
}
80-
81-
if (
82-
$id !== null &&
83-
($file = $this->kirby()->file($id, $this->model()))
84-
) {
85-
$files[] = $this->fileResponse($file);
86-
}
87-
}
88-
89-
return $files;
60+
'toModel' => function (string $id) {
61+
return $this->kirby()->file($id, $this->model);
9062
}
9163
],
92-
'api' => function () {
93-
return [
94-
[
95-
'pattern' => '/',
96-
'action' => function () {
97-
$field = $this->field();
64+
'api' => fn () => [
65+
[
66+
'pattern' => 'items',
67+
'method' => 'GET',
68+
'action' => fn () => $this->field()->itemsFromRequest()
69+
],
70+
[
71+
'pattern' => 'upload',
72+
'method' => 'POST',
73+
'action' => function () {
74+
$field = $this->field();
9875

99-
return $field->filepicker([
100-
'image' => $field->image(),
101-
'info' => $field->info(),
102-
'layout' => $field->layout(),
103-
'limit' => $field->limit(),
104-
'page' => $this->requestQuery('page'),
105-
'query' => $field->query(),
106-
'search' => $this->requestQuery('search'),
107-
'text' => $field->text()
108-
]);
109-
}
110-
],
111-
[
112-
'pattern' => 'upload',
113-
'method' => 'POST',
114-
'action' => function () {
115-
$field = $this->field();
116-
$uploads = $field->uploads();
117-
118-
// move_uploaded_file() not working with unit test
119-
// @codeCoverageIgnoreStart
120-
return $field->upload($this, $uploads, function ($file, $parent) use ($field) {
121-
return $file->panel()->pickerData([
122-
'image' => $field->image(),
123-
'info' => $field->info(),
124-
'layout' => $field->layout(),
125-
'model' => $field->model(),
126-
'text' => $field->text(),
127-
]);
128-
});
129-
// @codeCoverageIgnoreEnd
130-
}
131-
]
132-
];
133-
},
76+
// move_uploaded_file() not working with unit test
77+
// @codeCoverageIgnoreStart
78+
return $field->upload(
79+
$this,
80+
$field->uploads(),
81+
fn ($file, $parent) => $field->toItem($file)
82+
);
83+
// @codeCoverageIgnoreEnd
84+
}
85+
]
86+
],
87+
'dialogs' => fn () => [
88+
'picker' => fn () => new FilesPickerDialogController(...[
89+
'model' => $this->model(),
90+
'hasSearch' => $this->search,
91+
'image' => $this->image,
92+
'info' => $this->info ?? false,
93+
'limit' => $this->limit,
94+
'max' => $this->max,
95+
'multiple' => $this->multiple,
96+
'query' => $this->query,
97+
'text' => $this->text,
98+
...$this->picker
99+
])
100+
],
134101
'save' => function ($value = null) {
135-
return A::pluck($value, $this->store);
102+
return $this->toStoredValues($value);
136103
},
137104
'validations' => [
138105
'max',

config/fields/mixins/filepicker.php

Lines changed: 0 additions & 14 deletions
This file was deleted.

config/fields/mixins/pagepicker.php

Lines changed: 0 additions & 14 deletions
This file was deleted.

config/fields/mixins/picker.php

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
use Kirby\Data\Data;
4+
use Kirby\Toolkit\A;
35
use Kirby\Toolkit\I18n;
46
use Kirby\Toolkit\Str;
57
use Kirby\Uuid\Uuids;
@@ -55,6 +57,15 @@
5557
return $multiple;
5658
},
5759

60+
/**
61+
* Additional picker dialog props
62+
* @since 6.0.0
63+
* @values { image, layout, size }
64+
*/
65+
'picker' => function (array $picker = []) {
66+
return $picker;
67+
},
68+
5869
/**
5970
* Query for the items to be included in the picker
6071
*/
@@ -90,4 +101,62 @@
90101
return $text;
91102
},
92103
],
104+
'methods' => [
105+
'itemsFromRequest' => function () {
106+
$ids = $this->kirby()->request()->get('items');
107+
$ids = Str::split($ids);
108+
$models = $this->toModels($ids);
109+
return $this->toItems($models);
110+
},
111+
'toItem' => function ($model) {
112+
return $model->panel()->pickerData([
113+
'image' => $this->image,
114+
'info' => $this->info,
115+
'layout' => $this->layout,
116+
'text' => $this->text,
117+
]);
118+
},
119+
'toItems' => function (array $models) {
120+
return A::map(
121+
$models,
122+
fn ($model) => $this->toItem($model)
123+
);
124+
},
125+
'toFormValues' => function ($value = null) {
126+
$ids = [];
127+
128+
foreach (Data::decode($value, 'yaml') as $id) {
129+
if (is_array($id) === true) {
130+
$id = $id['uuid'] ?? $id['id'] ?? null;
131+
}
132+
133+
if (
134+
$id !== null &&
135+
($model = $this->toModel($id))
136+
) {
137+
$ids[] = $model->id();
138+
}
139+
}
140+
141+
return $ids;
142+
},
143+
'toStoredValues' => function ($value = null) {
144+
return A::map(
145+
$value ?? [],
146+
fn (string $id) => (string)$this->toModel($id)?->{$this->store}()
147+
);
148+
},
149+
'toModel' => function (string $id) {
150+
return $this->kirby()->file($id, $this->model);
151+
},
152+
'toModel' => function (string $id) {
153+
throw new Exception('toModel is not implemented for ' . $this->type() . ' field');
154+
},
155+
'toModels' => function (array $ids) {
156+
return A::map(
157+
$ids,
158+
fn (string $id) => $this->toModel($id)
159+
);
160+
}
161+
]
93162
];

config/fields/mixins/userpicker.php

Lines changed: 0 additions & 13 deletions
This file was deleted.

config/fields/pages.php

Lines changed: 27 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
<?php
22

3-
use Kirby\Cms\App;
4-
use Kirby\Data\Data;
3+
use Kirby\Panel\Controller\Dialog\PagesPickerDialogController;
54
use Kirby\Toolkit\A;
65

76
return [
87
'mixins' => [
98
'layout',
109
'min',
11-
'pagepicker',
1210
'picker',
1311
],
1412
'props' => [
@@ -43,7 +41,7 @@
4341
},
4442

4543
'value' => function ($value = null) {
46-
return $this->toPages($value);
44+
return $this->toFormValues($value);
4745
},
4846
],
4947
'computed' => [
@@ -53,56 +51,34 @@
5351
'default' => null
5452
],
5553
'methods' => [
56-
'pageResponse' => function ($page) {
57-
return $page->panel()->pickerData([
58-
'image' => $this->image,
59-
'info' => $this->info,
60-
'layout' => $this->layout,
61-
'text' => $this->text,
62-
]);
63-
},
64-
'toPages' => function ($value = null) {
65-
$pages = [];
66-
$kirby = App::instance();
67-
68-
foreach (Data::decode($value, 'yaml') as $id) {
69-
if (is_array($id) === true) {
70-
$id = $id['uuid'] ?? $id['id'] ?? null;
71-
}
72-
73-
if ($id !== null && ($page = $kirby->page($id))) {
74-
$pages[] = $this->pageResponse($page);
75-
}
76-
}
77-
78-
return $pages;
54+
'toModel' => function (string $id) {
55+
return $this->kirby()->page($id);
7956
}
8057
],
81-
'api' => function () {
82-
return [
83-
[
84-
'pattern' => '/',
85-
'action' => function () {
86-
$field = $this->field();
87-
88-
return $field->pagepicker([
89-
'image' => $field->image(),
90-
'info' => $field->info(),
91-
'layout' => $field->layout(),
92-
'limit' => $field->limit(),
93-
'page' => $this->requestQuery('page'),
94-
'parent' => $this->requestQuery('parent'),
95-
'query' => $field->query(),
96-
'search' => $this->requestQuery('search'),
97-
'subpages' => $field->subpages(),
98-
'text' => $field->text()
99-
]);
100-
}
101-
]
102-
];
103-
},
58+
'api' => fn () => [
59+
[
60+
'pattern' => 'items',
61+
'method' => 'GET',
62+
'action' => fn () => $this->field()->itemsFromRequest()
63+
],
64+
],
65+
'dialogs' => fn () => [
66+
'picker' => fn () => new PagesPickerDialogController(...[
67+
'model' => $this->model(),
68+
'hasSearch' => $this->search,
69+
'image' => $this->image,
70+
'info' => $this->info ?? false,
71+
'limit' => $this->limit,
72+
'max' => $this->max,
73+
'multiple' => $this->multiple,
74+
'query' => $this->query,
75+
'subpages' => $this->subpages,
76+
'text' => $this->text,
77+
...$this->picker
78+
])
79+
],
10480
'save' => function ($value = null) {
105-
return A::pluck($value, $this->store);
81+
return $this->toStoredValues($value);
10682
},
10783
'validations' => [
10884
'max',

0 commit comments

Comments
 (0)