Skip to content

Commit 3e8e351

Browse files
authored
Merge branch '3.x' into bugfix/get-table
2 parents 241e3fb + 8bf7b2f commit 3e8e351

30 files changed

+408
-182
lines changed

Diff for: .github/workflows/main.yml

-4
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,6 @@ jobs:
129129
run: |
130130
npm ci
131131
132-
- name: Create blocks dir
133-
run: |
134-
mkdir ./frontend/js/components/blocks/customs
135-
136132
- name: Build twill.
137133
run: ./vendor/bin/testbench twill:build --forTesting
138134
env:

Diff for: .github/workflows/release.yml

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
name: Release
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version_bump_type:
7+
description: 'Type of version bump (patch, minor, major)'
8+
required: true
9+
default: 'patch'
10+
11+
jobs:
12+
build-and-pr:
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- name: Checkout repository
17+
uses: actions/checkout@v3
18+
with:
19+
ref: 3.x
20+
21+
- name: Setup Node.js
22+
uses: actions/setup-node@v3
23+
with:
24+
node-version: '20'
25+
cache: 'npm'
26+
27+
- name: Install dependencies
28+
run: npm ci
29+
30+
- name: Build project
31+
run: npm run build
32+
33+
- name: Copy build artifacts
34+
run: |
35+
mkdir -p twill-assets/assets
36+
rm -rf twill-assets/assets/*
37+
cp -r dist/assets/* twill-assets/assets/
38+
39+
- name: Bump version
40+
id: bump_version
41+
run: |
42+
npm version ${{ github.event.inputs.version_bump_type }} --no-git-tag-version
43+
echo "::set-output name=new_version::$(node -p "require('./package.json').version")"
44+
45+
- name: Update version in PHP file
46+
run: |
47+
NEW_VERSION="${{ steps.bump_version.outputs.new_version }}"
48+
sed -i "s/\(public const VERSION = '\)[^']*\(';\)/\1${NEW_VERSION}\2/" src/TwillServiceProvider.php
49+
50+
- name: Create Pull Request
51+
uses: peter-evans/create-pull-request@v5
52+
with:
53+
token: ${{ secrets.GITHUB_TOKEN }}
54+
commit-message: |
55+
Update assets and bump version to ${{ steps.bump_version.outputs.new_version }}
56+
title: |
57+
Twill ${{ steps.bump_version.outputs.new_version }} release
58+
body: |
59+
This PR updates the build and bumps the version number to ${{ steps.bump_version.outputs.new_version }}.
60+
branch: release-${{ steps.bump_version.outputs.new_version }}
61+
base: 3.x

Diff for: CHANGELOG.md

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

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

5+
## 3.5.2
6+
7+
### Fixed
8+
9+
- Fix cropper regression (likely a from a recent browser update) by [@13twelve](https://github.com/13twelve) in [#2744](https://github.com/area17/twill/pull/2744)
10+
11+
12+
## 3.5.1
13+
14+
### Fixed
15+
16+
- Fix file library uploader regression by [@joyceverheije](https://github.com/joyceverheije) in https://github.com/area17/twill/pull/2740
17+
- Fix `timeOnly` variant of the `Datepicker` field by [@MamlukiSn](https://github.com/MamlukiSn) in https://github.com/area17/twill/pull/2739
18+
19+
### Improved
20+
21+
- Add a warning during the `twill:update` and `twill:build` commands for developers that have `twill.load_default_migrations` set to false by [@ifox](https://github.com/ifox) in [de274175](https://github.com/area17/twill/commit/de274175)
22+
23+
## 3.5.0
24+
25+
### Added
26+
27+
- Add a `ModuleController::setPreviewView()` method by @zachgarwood in https://github.com/area17/twill/pull/2724
28+
- Add a `disableCrop()` method to `medias` fields by @ifox in https://github.com/area17/twill/pull/2686
29+
30+
### Fixed
31+
32+
- Fix position management in `medias` and `files` fields by @zeezo887 in https://github.com/area17/twill/pull/2694
33+
- Fix issues with touch actions by @13twelve in https://github.com/area17/twill/pull/2713
34+
- Fix issue with `Relation` column by @zachgarwood in https://github.com/area17/twill/pull/2720
35+
- Fix endpoints initialization for `Browser` component by @zeezo887 in https://github.com/area17/twill/pull/2722
36+
- 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
37+
- Fix square crops having mismatching width/height values by @13twelve in https://github.com/area17/twill/pull/2706
38+
- Fix `hideActiveCrop()` not working for medias form field when max is greater than 1 by @zeezo887 in https://github.com/area17/twill/pull/2686
39+
- Fix #2641: `InlineRepeater` updates by @13twelve in https://github.com/area17/twill/pull/2714
40+
- Fix Vue dropdown console warnings: update useCapture param for removeEventListener to match addEventListener by @zeezo887 in https://github.com/area17/twill/pull/2687
41+
- Fix #2657: adds missing Vue draggable deprecations by @13twelve in https://github.com/area17/twill/pull/2707
42+
43+
### Docs
44+
45+
- Added instructions to disable publish switch in create modal by @ordigital in https://github.com/area17/twill/pull/2698
46+
- Added instructions for `MultiSelect` field with dynamic values in form builder by @ordigital in https://github.com/area17/twill/pull/2699
47+
- Added instructions for free cropping with `null` or `0` ratio value by @LucaRed in https://github.com/area17/twill/pull/2715
48+
49+
### Translations
50+
51+
- Fix #2619: adds missing iso languages by @13twelve in https://github.com/area17/twill/pull/2708
52+
553
## 3.4.1
654

755
### Improved
@@ -66,6 +114,12 @@ All notable changes to `twill` will be documented in this file.
66114
- Bump body-parser and express by [@dependabot](https://github.com/dependabot) in https://github.com/area17/twill/pull/2659
67115
- Bump cookie and express by [@dependabot](https://github.com/dependabot) in https://github.com/area17/twill/pull/2664
68116

117+
## 3.3.2
118+
119+
### Fixed
120+
121+
- Backport fix from 3.5.1: `timeOnly` variant of the `Datepicker` field by [@MamlukiSn](https://github.com/MamlukiSn) in https://github.com/area17/twill/pull/2739
122+
69123
## 3.3.1
70124

71125
### Fixed

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

+18-9
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,13 @@ Repeater::make()
2929
:::#tab:::
3030
:::#tabs:::
3131

32-
| Option | Description | Type | Default value |
33-
|:---------------|:---------------------------------------------|:--------|:-----------------|
34-
| type | Type of repeater items | string | |
35-
| name | Name of the field | string | same as `type` |
36-
| max | Maximum amount that can be created | number | null (unlimited) |
37-
| buttonAsLink | Displays the `Add` button as a centered link | boolean | false |
38-
| disableCreate | Disables ability to add new items | boolean | true |
39-
| disableActions | Removes row item actions | boolean | true |
40-
| disableReorder | Disables reordering of repeater items | boolean | true |
32+
| Option | Description | Type | Default value |
33+
|:-------------|:---------------------------------------------|:--------|:-----------------|
34+
| type | Type of repeater items | string | |
35+
| name | Name of the field | string | same as `type` |
36+
| max | Maximum amount that can be created | number | null (unlimited) |
37+
| buttonAsLink | Displays the `Add` button as a centered link | boolean | false |
38+
| reorder | Allow reordering of repeater items | boolean | true |
4139

4240
<br/>
4341

@@ -165,6 +163,17 @@ class ProjectController extends BaseModuleController
165163
}
166164
```
167165

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+
168177
## Blade repeater fields
169178

170179
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: frontend/js/components/Cropper.vue

+2-3
Original file line numberDiff line numberDiff line change
@@ -189,13 +189,12 @@
189189
//
190190
// from my testing it seems to be a little inconsistent and unpredictable
191191
// I guess you just need for the rounding error to happen
192-
// But, it seems setting the properties individually avoids this...
192+
// But, it seems re-setting the properties individually avoids this...
193193
//
194194
// -- Mike ([email protected])
195+
this.cropper.setData(crop)
195196
this.cropper.setData({ x: crop.x })
196197
this.cropper.setData({ y: crop.y })
197-
this.cropper.setData({ width: crop.width })
198-
this.cropper.setData({ height: crop.height })
199198
},
200199
test: function () {
201200
const crop = this.toNaturalCrop({ x: 0, y: 0, width: 380, height: 475 })

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

+3-2
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@
132132
wrap: true,
133133
altInput: true,
134134
altFormat: self.altFormatComputed,
135-
dateFormat: self.enableTime ? 'Z' : 'Y-m-d', // This is the universal format that will be parsed by the back-end.
135+
dateFormat: (self.enableTime && self.noCalendar) ? 'H:i:S' : (self.enableTime ? 'Z' : 'Y-m-d'), // This is the universal format that will be parsed by the back-end.
136136
static: self.staticMode,
137137
appendTo: self.staticMode ? self.$refs[self.refs.flatPicker] : undefined,
138138
enableTime: self.enableTime,
@@ -217,7 +217,8 @@
217217
},
218218
isValidTime: function (string) {
219219
const timeRegex = /^(0?[1-9]|1[0-2]):[0-5][0-9](?: (AM|PM))?$/i;
220-
return timeRegex.test(string);
220+
const time24HrRegex = /^([01]\d|2[0-3]):[0-5]\d(?::[0-5]\d)?$/;
221+
return timeRegex.test(string) || time24HrRegex.test(string);
221222
}
222223
},
223224
mounted: function () {

Diff for: frontend/js/components/blocks/customs/.keep

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

Diff for: frontend/js/components/media-library/Uploader.vue

+42-34
Original file line numberDiff line numberDiff line change
@@ -197,53 +197,61 @@
197197
this.uploadProgress(0)
198198
},
199199
_onSubmitCallback (id, name) {
200+
const file = this._uploader.methods.getFile(id)
201+
202+
if (!file.type.startsWith('image/')) {
203+
this.prepareUpload(id, name)
204+
return
205+
}
206+
200207
return new Promise((resolve, reject) => {
201208
// halt fine uploader upload until image is loaded
202209
// so we can send image dimensions with the upload
203210
const img = new Image()
204211
img.onload = () => {
205-
this.$emit('clear')
206-
// each upload session will add upload files with original filenames in a folder named using a uuid
207-
this.unique_folder_name = this.unique_folder_name || (this.uploaderConfig.endpointRoot + qq.getUniqueId())
208-
209-
// determine the image dimensions and add it to params sent on upload success
210-
this._uploader.methods.setParams({
212+
this.prepareUpload(id, name, {
211213
width: img.width,
212-
height: img.height,
213-
unique_folder_name: this.unique_folder_name,
214-
media_to_replace_id: this.media_to_replace_id
215-
}, id)
216-
217-
this.media_to_replace_id = null
218-
219-
const media = {
220-
id: this._uploader.methods.getUuid(id),
221-
name: sanitizeFilename(name),
222-
progress: 0,
223-
error: false,
224-
errorMessage: null,
225-
isReplacement: !!this.media_to_replace_id,
226-
replacementId: this.media_to_replace_id
227-
}
228-
229-
if (this.type.value === 'file') {
230-
this.media_to_replace_id = null
231-
}
232-
233-
this.loadingMedias.push(media)
234-
this.loadingProgress(media)
235-
214+
height: img.height
215+
})
236216
// resolve the promise, allow the upload to continue
237217
resolve(img)
238218
}
239-
240219
img.onerror = (err) => {
241220
console.error(err) // eslint-disable-line
242-
reject(err);
221+
reject(err)
243222
}
223+
img.src = URL.createObjectURL(file)
224+
})
225+
},
226+
227+
prepareUpload(id, name, additionalParams = {}) {
228+
this.$emit('clear')
229+
230+
// each upload session will place uploaded files with original
231+
// filenames in a single folder named using a uuid
232+
this.unique_folder_name = this.unique_folder_name ||
233+
(this.uploaderConfig.endpointRoot + qq.getUniqueId())
234+
235+
this._uploader.methods.setParams({
236+
unique_folder_name: this.unique_folder_name,
237+
media_to_replace_id: this.media_to_replace_id,
238+
...additionalParams
239+
}, id)
240+
241+
const media = {
242+
id: this._uploader.methods.getUuid(id),
243+
name: sanitizeFilename(name),
244+
progress: 0,
245+
error: false,
246+
errorMessage: null,
247+
isReplacement: !!this.media_to_replace_id,
248+
replacementId: this.media_to_replace_id
249+
}
250+
251+
this.media_to_replace_id = null
244252
245-
img.src = URL.createObjectURL(this._uploader.methods.getFile(id))
246-
});
253+
this.loadingMedias.push(media)
254+
this.loadingProgress(media)
247255
},
248256
_onProgressCallback (id, name, uploadedBytes, totalBytes) {
249257
const index = this.loadingMedias.findIndex((m) => m.id === this._uploader.methods.getUuid(id))

0 commit comments

Comments
 (0)