Skip to content

Commit 53710b7

Browse files
authored
Merge branch '3.x' into fix-slugs
2 parents 8ec65c3 + 3bc9fe3 commit 53710b7

File tree

58 files changed

+684
-204
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+684
-204
lines changed

Diff for: .github/workflows/main.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ jobs:
108108
id: composer-cache
109109
run: |
110110
echo "::set-output name=dir::$(composer config cache-files-dir)"
111-
- uses: actions/cache@v2
111+
- uses: actions/cache@v4
112112
with:
113113
path: ${{ steps.composer-cache.outputs.dir }}
114114
key: ${{ matrix.os }}-${{ matrix.laravel }}-${{ matrix.php }}-${{ matrix.dbal }}-composer-${{ hashFiles('**/composer.lock') }}

Diff for: CHANGELOG.md

+30
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,36 @@
22

33
All notable changes to `twill` will be documented in this file.
44

5+
## 3.5.0
6+
7+
### Added
8+
9+
- Add a `ModuleController::setPreviewView()` method by @zachgarwood in https://github.com/area17/twill/pull/2724
10+
- Add a `disableCrop()` method to `medias` fields by @ifox in https://github.com/area17/twill/pull/2686
11+
12+
### Fixed
13+
14+
- Fix position management in `medias` and `files` fields by @zeezo887 in https://github.com/area17/twill/pull/2694
15+
- Fix issues with touch actions by @13twelve in https://github.com/area17/twill/pull/2713
16+
- Fix issue with `Relation` column by @zachgarwood in https://github.com/area17/twill/pull/2720
17+
- Fix endpoints initialization for `Browser` component by @zeezo887 in https://github.com/area17/twill/pull/2722
18+
- Fix image cropper for erroneous EXIF orientation: Use JS to read image dimensions on upload by @13twelve in https://github.com/area17/twill/pull/2705
19+
- Fix square crops having mismatching width/height values by @13twelve in https://github.com/area17/twill/pull/2706
20+
- Fix `hideActiveCrop()` not working for medias form field when max is greater than 1 by @zeezo887 in https://github.com/area17/twill/pull/2686
21+
- Fix #2641: `InlineRepeater` updates by @13twelve in https://github.com/area17/twill/pull/2714
22+
- Fix Vue dropdown console warnings: update useCapture param for removeEventListener to match addEventListener by @zeezo887 in https://github.com/area17/twill/pull/2687
23+
- Fix #2657: adds missing Vue draggable deprecations by @13twelve in https://github.com/area17/twill/pull/2707
24+
25+
### Docs
26+
27+
- Added instructions to disable publish switch in create modal by @ordigital in https://github.com/area17/twill/pull/2698
28+
- Added instructions for `MultiSelect` field with dynamic values in form builder by @ordigital in https://github.com/area17/twill/pull/2699
29+
- Added instructions for free cropping with `null` or `0` ratio value by @LucaRed in https://github.com/area17/twill/pull/2715
30+
31+
### Translations
32+
33+
- Fix #2619: adds missing iso languages by @13twelve in https://github.com/area17/twill/pull/2708
34+
535
## 3.4.1
636

737
### Improved

Diff for: composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@
4848
"area17/phptorch": "dev-main",
4949
"chillerlan/php-qrcode": "~4.0",
5050
"friendsofphp/php-cs-fixer": "^3.0",
51+
"larastan/larastan": "^2.9",
5152
"nette/php-generator": "^4.0.3",
5253
"nunomaduro/collision": "^6.0 || ^7.0 || ^8.0",
53-
"nunomaduro/larastan": "^2.0",
5454
"orchestra/testbench": "^7.8 || ^8.0 || ^9.0",
5555
"orchestra/testbench-dusk": "^7.8 || ^8.0 || ^9.0",
5656
"phpunit/php-invoker": "^3.1 || ^4.0",

Diff for: docs/content/1_docs/4_form-fields/06_multi-select.md

+22-2
Original file line numberDiff line numberDiff line change
@@ -200,21 +200,38 @@ public function sectors() {
200200
- In your repository, make sure to sync the association when saving:
201201

202202
```php
203-
public function afterSave($object, $fields)
203+
public function afterSave($object, $fields): void
204204
{
205205
$object->sectors()->sync($fields['sectors'] ?? []);
206206

207207
parent::afterSave($object, $fields);
208208
}
209209
```
210210

211+
:::tabs=currenttab.FormBuilder&items.FormBuilder|FormView:::
212+
:::tab=name.FormBuilder:::
213+
214+
```php
215+
$form->add(
216+
MultiSelect::make()
217+
->name('sectors')
218+
->options(
219+
Options::fromArray(app()->make(SectorsRepository::class)->listAll()->toArray())
220+
)
221+
);
222+
```
223+
224+
:::#tab:::
225+
226+
:::tab=name.FormView:::
227+
211228
- In your controller, add to the formData the collection of options:
212229

213230
```php
214231
protected function formData($request)
215232
{
216233
return [
217-
'sectors' => app()->make(SectorRepository::class)->listAll()
234+
'sectors' => app()->make(SectorRepository::class)->listAll()->toArray()
218235
];
219236
}
220237
```
@@ -229,6 +246,9 @@ protected function formData($request)
229246
/>
230247
```
231248

249+
:::#tab:::
250+
:::#tabs:::
251+
232252
When used in a [block](../5_block-editor), no migration is needed.
233253

234254
## Multi Select Inline

Diff for: docs/content/1_docs/4_form-fields/11_repeater.md

+11
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,17 @@ class ProjectController extends BaseModuleController
163163
}
164164
```
165165

166+
| Option | Description | Type | Default value |
167+
|:---------------|:---------------------------------------------|:--------|:-----------------|
168+
| type | Type of repeater items | string | |
169+
| name | Name of the field | string | same as `type` |
170+
| max | Maximum amount that can be created | number | null (unlimited) |
171+
| buttonAsLink | Displays the `Add` button as a centered link | boolean | false |
172+
| disableCreate | Disables ability to add new items | boolean | false |
173+
| disableActions | Removes row item actions | boolean | false |
174+
| disableReorder | Disables reordering of repeater items | boolean | false |
175+
176+
166177
## Blade repeater fields
167178

168179
The following example demonstrates how to define a relationship between `Team` and `TeamMember` modules to implement

Diff for: docs/content/1_docs/7_media-library/03_role-crop-params.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ A _role_ is a way to define different contexts in which an image might be placed
66

77
_Crops_ are more self-explanatory. Twill comes with some pre-defined crop settings to allow you to set different variants of a given image, so crops can be used in combination with _roles,_ or they can be used on their own with a single role to define multiple cropping ratios on the same image.
88

9-
Using the Person example, your `cover` image could have a `square` crop for mobile screens, but could use a `16/9` crop on larger screens. Those values are editable at your convenience for each model, even if there are already some crops created in the CMS.
9+
Using the Person example, your `cover` image could have a `square` crop for mobile screens, but could use a `16/9` crop on larger screens. Those values are editable at your convenience for each model in the `ratio` option, even if there are already some crops created in the CMS. By specifying `null` or `0` as a `ratio`, no automatic crop will happen and you'll be able to crop freely.
1010

1111
The only thing you have to do to make it work is to compose your model and repository with the appropriate traits, respectively `HasMedias` and `HandleMedias`, set up your `$mediasParams` configuration and use the `medias` form partial in your form view (more info in the CRUD section).
1212

Diff for: docs/content/2_guides/3_adding-fields-to-the-create-modal.md

+86-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Often you might want to add some mandatory fields to the create modal of your mo
1616
In our module controller we can override the `getCreateForm` method and add the fields to render:
1717

1818
:::filename:::
19-
`app/Http/Controllers/Twill/YourModuleController.php`
19+
`app/Http/Controllers/Twill/BlogController.php`
2020
:::#filename:::
2121

2222
```phptorch
@@ -168,3 +168,88 @@ Result:
168168

169169
:::#tab:::
170170
:::#tabs:::
171+
172+
# Removing publish switch from create modal
173+
174+
In our module controller we can override the `indexData` to remove publish switch from modal. We can also override `setUpController` method to disable language select box used for making a translation active.
175+
176+
:::filename:::
177+
`app/Http/Controllers/Twill/BlogController.php`
178+
:::#filename:::
179+
180+
```phptorch
181+
##CODE##
182+
<?php
183+
184+
namespace App\Http\Controllers\Twill;
185+
186+
use A17\Twill\Http\Controllers\Admin\NestedModuleController as BaseModuleController;
187+
use A17\Twill\Services\Forms\Fields\Input;
188+
use A17\Twill\Services\Forms\Fields\Wysiwyg;
189+
use A17\Twill\Services\Forms\Form;
190+
191+
class BlogController extends BaseModuleController
192+
{
193+
protected $moduleName = 'blogs';
194+
195+
public function getCreateForm(): Form
196+
{
197+
...
198+
}
199+
200+
protected function setUpController(): void
201+
{
202+
$this->disablePublish();
203+
$this->disableBulkPublish();
204+
// $this->disableEditor(); # uncomment this to disable full editor
205+
// $this->enableEditInModal(); # uncomment this to enable editing in modal
206+
207+
}
208+
209+
protected function formData($request)
210+
{
211+
return [ 'controlLanguagesPublication' => false ]; # disable select box to make language active
212+
}
213+
}
214+
```
215+
216+
If we also want to make all languages active by default, we can override `prepareFieldsBeforeCreate` function in our module repository:
217+
218+
:::filename:::
219+
`app/Repositories/BlogRepository.php`
220+
:::#filename:::
221+
222+
```phptorch
223+
##CODE##
224+
<?php
225+
226+
namespace App\Repositories;
227+
228+
use A17\Twill\Repositories\Behaviors\HandleTranslations;
229+
use A17\Twill\Repositories\Behaviors\HandleSlugs;
230+
use A17\Twill\Repositories\ModuleRepository;
231+
use App\Models\Category;
232+
233+
class BlogRepository extends ModuleRepository
234+
{
235+
use HandleTranslations, HandleSlugs;
236+
237+
public function __construct(Category $model)
238+
{
239+
$this->model = $model;
240+
}
241+
242+
### make all languages active for this model
243+
public function prepareFieldsBeforeCreate($fields): array
244+
{
245+
foreach ($fields['languages'] as $key => $language) {
246+
$fields['languages'][$key]['published'] = true;
247+
}
248+
249+
return parent::prepareFieldsBeforeCreate($fields); // @phpstan-ignore-line
250+
}
251+
252+
}
253+
```
254+
255+
![Customized create modal without publish switch](./assets/customized-without-publish-switch.png)
Loading

Diff for: frontend/js/components/Dropdown.vue

+11-4
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@
161161
}
162162
},
163163
closeFromDoc: function (event) {
164+
if (!this.active) return
165+
164166
const target = event.target
165167
166168
if (event.type === 'scroll') {
@@ -172,8 +174,13 @@
172174
}
173175
}
174176
175-
if (!this.clickable) this.close()
176-
else if (!this.$el.querySelector('[data-dropdown-content]').contains(target) && this.clickable) this.close()
177+
// timeout so the click is not triggered directly
178+
this.timer = setTimeout(() => {
179+
this.timer = null
180+
181+
if (!this.clickable) this.close()
182+
else if (!this.$el.querySelector('[data-dropdown-content]').contains(target) && this.clickable) this.close()
183+
}, 1)
177184
},
178185
open: function (onShow) {
179186
if (this.active) return
@@ -207,8 +214,8 @@
207214
if (!this.active) return
208215
209216
clearTimeout(this.timer)
210-
document.removeEventListener('click', this.closeFromDoc, true)
211-
document.removeEventListener('touchend', this.closeFromDoc, true)
217+
document.removeEventListener('click', this.closeFromDoc, false)
218+
document.removeEventListener('touchend', this.closeFromDoc, false)
212219
213220
if (this.fixed) {
214221
window.removeEventListener('scroll', this.closeFromDoc, true)

Diff for: frontend/js/components/MediaField.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -763,7 +763,7 @@
763763
}
764764
765765
.media__actions {
766-
min-width:45px * 3;
766+
flex-shrink: 0;
767767
768768
@media screen and (max-width: 1140px) {
769769
display: none !important;

Diff for: frontend/js/components/Repeater.vue

+12-3
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@
77
ref="blockList"
88
:block="block"
99
:index="index"
10-
:withHandle="draggable"
10+
:withHandle="reorder && draggable"
11+
:withActions="displayActions"
1112
:size="blockSize"
1213
:opened="opened"
1314
>
1415
<a17-button slot="block-actions" variant="icon" data-action @click="duplicateBlock(index)"
15-
v-if="hasRemainingBlocks">
16+
v-if="hasRemainingBlocks && allowCreate">
1617
<span v-svg symbol="add"></span>
1718
</a17-button>
1819
<div slot="dropdown-action">
@@ -110,11 +111,19 @@
110111
type: Boolean,
111112
default: true
112113
},
114+
displayActions: {
115+
type: Boolean,
116+
default: true
117+
},
113118
max: {
114119
type: [Number, null],
115120
required: false,
116121
default: null
117-
}
122+
},
123+
reorder: {
124+
type: Boolean,
125+
default: true
126+
},
118127
},
119128
data: function () {
120129
return {

Diff for: frontend/js/components/Slideshow.vue

+5
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
:index="index"
1616
:mediaContext="name"
1717
:cropContext="cropContext"
18+
:activeCrop="activeCrop"
1819
:hover="hoverable"
1920
:isSlide="true"
2021
:withAddInfo="withAddInfo"
@@ -70,6 +71,10 @@
7071
disabled: {
7172
type: Boolean,
7273
default: false
74+
},
75+
activeCrop: {
76+
type: Boolean,
77+
default: true
7378
}
7479
},
7580
data: function () {

Diff for: frontend/js/components/editor/EditorSidebarBlockList.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<draggable class="editorSidebar__blocks"
55
:class="editorSidebarClasses"
66
v-model="blocks"
7-
:options="{
7+
v-bind="{
88
group: {
99
name: 'editorBlocks',
1010
pull: 'clone',

0 commit comments

Comments
 (0)