Skip to content

Commit a2ec7ae

Browse files
committed
Fix bucket morph map
Improve buckets doc
1 parent ce0fbf1 commit a2ec7ae

File tree

7 files changed

+137
-126
lines changed

7 files changed

+137
-126
lines changed

docs/content/1_docs/9_buckets/1_index.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Then, define your buckets' configuration:
2121
'name' => 'Home primary feature',
2222
'bucketables' => [
2323
[
24+
'repository' => GuidesRepository::class,
2425
'module' => 'guides',
2526
'name' => 'Guides',
2627
'scopes' => ['published' => true],
@@ -32,6 +33,7 @@ Then, define your buckets' configuration:
3233
'name' => 'Home secondary features',
3334
'bucketables' => [
3435
[
36+
'repository' => GuidesRepository::class,
3537
'module' => 'guides',
3638
'name' => 'Guides',
3739
'scopes' => ['published' => true],
@@ -45,7 +47,7 @@ Then, define your buckets' configuration:
4547
```
4648

4749
You can allow mixing modules in a single bucket by adding more modules to the `bucketables` array.
48-
Each `bucketable` should have its [model morph map](https://laravel.com/docs/10.x/eloquent-relationships#polymorphic-relationships) defined because features are stored in a polymorphic table.
50+
We recommend that each `bucketable` model be in the [morph map](https://laravel.com/docs/10.x/eloquent-relationships#polymorphic-relationships) because features are stored in a polymorphic table.
4951

5052
In your AppServiceProvider, you can do it like the following:
5153

@@ -55,7 +57,7 @@ use Illuminate\Database\Eloquent\Relations\Relation;
5557
public function boot()
5658
{
5759
Relation::morphMap([
58-
'guides' => 'App\Models\Guide',
60+
'guides' => App\Models\Guide::class,
5961
]);
6062
}
6163
```
@@ -66,7 +68,7 @@ Finally, add a link to your buckets page in your CMS navigation:
6668
return [
6769
'featured' => [
6870
'title' => 'Features',
69-
'route' => 'admin.featured.homepage',
71+
'route' => 'twill.featured.homepage',
7072
'primary_navigation' => [
7173
'homepage' => [
7274
'title' => 'Homepage',

frontend/js/components/buckets/Bucket.vue

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
<transition-group name="fade_scale_list" tag='tbody'>
5151
<a17-bucket-item v-for="(child, index) in bucket.children" :key="`${child.id}_${index}`" :item="child"
5252
:restricted="restricted" :draggable="bucket.children.length > 1"
53+
:sourceLabels="sourceLabels"
5354
:singleBucket="singleBucket" :singleSource="singleSource" :bucket="bucket.id"
5455
:buckets="buckets" v-on:add-to-bucket="addToBucket"
5556
v-on:remove-from-bucket="deleteFromBucket"
@@ -120,7 +121,7 @@
120121
// Optionnal additionnal actions showing up after the Publish button
121122
extraActions: {
122123
type: Array,
123-
default: function () { return [] }
124+
default() { return [] }
124125
}
125126
},
126127
components: {
@@ -132,7 +133,7 @@
132133
'a17-vselect': VSelect,
133134
draggable
134135
},
135-
data: function () {
136+
data() {
136137
return {
137138
currentBucketID: '',
138139
currentItem: '',
@@ -152,13 +153,20 @@
152153
...mapGetters([
153154
'currentSource'
154155
]),
155-
singleBucket: function () {
156+
sourceLabels() {
157+
const labels = {};
158+
this.dataSources.forEach((source) => {
159+
labels[source.type] = source.label;
160+
})
161+
return labels;
162+
},
163+
singleBucket() {
156164
return this.buckets.length === 1
157165
},
158-
singleSource: function () {
166+
singleSource() {
159167
return this.dataSources.length === 1
160168
},
161-
overrideBucketText: function () {
169+
overrideBucketText() {
162170
const bucket = this.buckets.find(b => b.id === this.currentBucketID)
163171
let bucketName = ''
164172
let bucketSize = ''
@@ -170,7 +178,7 @@
170178
}
171179
},
172180
methods: {
173-
addToBucket: function (item, bucket) {
181+
addToBucket(item, bucket) {
174182
const index = this.buckets.findIndex(b => b.id === bucket)
175183
176184
if (!item && index === -1) return
@@ -188,22 +196,22 @@
188196
189197
if (count > -1 && count < this.buckets[index].max) {
190198
// Commit before dispatch to prevent ui visual effect timeout
191-
this.checkRestriced(item)
199+
this.checkRestricted(item)
192200
this.$store.commit(BUCKETS.ADD_TO_BUCKET, data)
193201
} else if (this.overridableMax || this.overrideItem) {
194-
this.checkRestriced(item)
202+
this.checkRestricted(item)
195203
this.$store.commit(BUCKETS.ADD_TO_BUCKET, data)
196204
this.$store.commit(BUCKETS.DELETE_FROM_BUCKET, { index, itemIndex: 0 })
197205
this.overrideItem = false
198206
} else {
199207
this.$refs.overrideBucket.open()
200208
}
201209
},
202-
deleteFromBucket: function (item, bucket) {
210+
deleteFromBucket(item, bucket) {
203211
const bucketIndex = this.buckets.findIndex(b => b.id === bucket)
204212
if (bucketIndex === -1) return
205213
206-
const itemIndex = this.buckets[bucketIndex].children.findIndex(c => c.id === item.id && c.content_type.value === item.content_type.value)
214+
const itemIndex = this.buckets[bucketIndex].children.findIndex(c => c.id === item.id && c.type === item.type)
207215
208216
if (itemIndex === -1) return
209217
@@ -213,11 +221,11 @@
213221
}
214222
this.$store.commit(BUCKETS.DELETE_FROM_BUCKET, data)
215223
},
216-
toggleFeaturedInBucket: function (item, bucket) {
224+
toggleFeaturedInBucket(item, bucket) {
217225
const bucketIndex = this.buckets.findIndex(b => b.id === bucket)
218226
if (bucketIndex === -1) return
219227
220-
const itemIndex = this.buckets[bucketIndex].children.findIndex(c => c.id === item.id && c.content_type.value === item.content_type.value)
228+
const itemIndex = this.buckets[bucketIndex].children.findIndex(c => c.id === item.id && c.type === item.type)
221229
222230
if (itemIndex === -1) return
223231
@@ -228,55 +236,55 @@
228236
229237
this.$store.commit(BUCKETS.TOGGLE_FEATURED_IN_BUCKET, data)
230238
},
231-
checkRestriced: function (item) {
239+
checkRestricted(item) {
232240
// Remove item from each bucket if option restricted to one bucket is active
233241
if (this.restricted) {
234242
this.buckets.forEach((bucket) => {
235243
bucket.children.forEach((child) => {
236-
if (child.id === item.id && child.content_type.value === item.content_type.value) {
244+
if (child.id === item.id && child.type === item.type) {
237245
this.deleteFromBucket(item, bucket.id)
238246
}
239247
})
240248
})
241249
}
242250
},
243-
sortBucket: function (evt, index) {
251+
sortBucket(evt, index) {
244252
const data = {
245253
bucketIndex: index,
246254
oldIndex: evt.moved.oldIndex,
247255
newIndex: evt.moved.newIndex
248256
}
249257
this.$store.commit(BUCKETS.REORDER_BUCKET_LIST, data)
250258
},
251-
changeDataSource: function (value) {
259+
changeDataSource(value) {
252260
this.$store.commit(BUCKETS.UPDATE_BUCKETS_DATASOURCE, value)
253261
this.$store.commit(BUCKETS.UPDATE_BUCKETS_DATA_PAGE, 1)
254262
this.$store.dispatch(ACTIONS.GET_BUCKETS)
255263
},
256-
filterBucketsData: function (formData) {
264+
filterBucketsData(formData) {
257265
this.$store.commit(BUCKETS.UPDATE_BUCKETS_DATA_PAGE, 1)
258266
this.$store.commit(BUCKETS.UPDATE_BUCKETS_FILTER, formData || { search: '' })
259267
// reload datas
260268
this.$store.dispatch(ACTIONS.GET_BUCKETS)
261269
},
262-
updateOffset: function (value) {
270+
updateOffset(value) {
263271
this.$store.commit(BUCKETS.UPDATE_BUCKETS_DATA_PAGE, 1)
264272
this.$store.commit(BUCKETS.UPDATE_BUCKETS_DATA_OFFSET, value)
265273
266274
// reload datas
267275
this.$store.dispatch(ACTIONS.GET_BUCKETS)
268276
},
269-
updatePage: function (value) {
277+
updatePage(value) {
270278
this.$store.commit(BUCKETS.UPDATE_BUCKETS_DATA_PAGE, value)
271279
// reload datas
272280
this.$store.dispatch(ACTIONS.GET_BUCKETS)
273281
},
274-
override: function () {
282+
override() {
275283
this.overrideItem = true
276284
this.addToBucket(this.currentItem, this.currentBucketID)
277285
this.$refs.overrideBucket.close()
278286
},
279-
save: function () {
287+
save() {
280288
this.$store.dispatch(ACTIONS.SAVE_BUCKETS)
281289
}
282290
}

frontend/js/components/buckets/BucketItem.vue

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
<span v-else>{{ item.name }}</span>
1919
</h4>
2020
</td>
21-
<td class="buckets__itemContentType" v-if="item.content_type &&!singleSource">
22-
{{ item.content_type.label }}
21+
<td class="buckets__itemContentType" v-if="item.type && !singleSource">
22+
{{ sourceLabels[item.type] }}
2323
</td>
2424
<td class="buckets__itemOptions">
2525
<a17-dropdown v-if="!singleBucket" ref="bucketDropdown" class="item__dropdown bucket__action" position="bottom-right" title="Featured in" :clickable="true">
@@ -75,29 +75,26 @@
7575
toggleFeaturedLabels: {
7676
type: Array,
7777
default: () => []
78-
}
78+
},
79+
sourceLabels: Object,
7980
},
8081
mixins: [bucketMixin],
8182
computed: {
82-
inBuckets: function () {
83-
const self = this
84-
let find = false
85-
self.buckets.forEach(function (bucket) {
86-
if (bucket.children.find(function (b) {
87-
return b.id === self.item.id && b.content_type.value === self.item.content_type.value
88-
})) {
89-
find = true
83+
inBuckets() {
84+
for(const bucket in this.buckets) {
85+
if (bucket.children.some((b) => b.id === self.item.id && b.type === self.item.type)) {
86+
return true
9087
}
91-
})
92-
return find
88+
}
89+
return false
9390
},
94-
customClasses: function () {
91+
customClasses() {
9592
return {
9693
...this.bucketClasses,
9794
draggable: this.draggable
9895
}
9996
},
100-
dropDownBuckets: function () {
97+
dropDownBuckets() {
10198
const checkboxes = []
10299
const self = this
103100
let index = 1
@@ -116,13 +113,13 @@
116113
}
117114
},
118115
methods: {
119-
removeFromBucket: function (bucketId = this.bucket) {
116+
removeFromBucket(bucketId = this.bucket) {
120117
this.$emit('remove-from-bucket', this.item, bucketId)
121118
},
122-
toggleFeatured: function () {
119+
toggleFeatured() {
123120
this.$emit('toggle-featured-in-bucket', this.item, this.bucket)
124121
},
125-
selectedBuckets: function () {
122+
selectedBuckets() {
126123
const selected = []
127124
const self = this
128125
if (this.buckets.length > 0) {
@@ -135,11 +132,11 @@
135132
}
136133
return []
137134
},
138-
slug: function (id) {
135+
slug(id) {
139136
// Current Bucket ID + item id + bucket id
140-
return 'bucket-' + this.bucket + '_item-' + this.item.id + '_type-' + this.item.content_type.value + '_inb-' + id
137+
return 'bucket-' + this.bucket + '_item-' + this.item.id + '_type-' + this.item.type + '_inb-' + id
141138
},
142-
updateBucket: function (value) {
139+
updateBucket(value) {
143140
const pattern = 'inb-'
144141
const self = this
145142

frontend/js/mixins/buckets.js

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { mapState } from 'vuex'
2+
13
export default {
24
props: {
35
buckets: {
@@ -13,38 +15,39 @@ export default {
1315
}
1416
},
1517
computed: {
16-
bucketClasses: function () {
18+
...mapState({
19+
dataSources: state => state.buckets.dataSources.content_types
20+
}),
21+
bucketClasses() {
1722
return {
1823
selected: this.type !== 'bucket' && this.inBuckets,
1924
single: this.singleBucket
2025
}
2126
}
2227
},
2328
methods: {
24-
addToBucket: function (bucketId = this.bucket) {
29+
addToBucket(bucketId = this.bucket) {
2530
this.$emit('add-to-bucket', this.item, bucketId)
2631
},
27-
inBucketById: function (id) {
32+
inBucketById(id) {
2833
const index = this.buckets.findIndex(b => b.id === id)
2934

3035
if (index === -1) return
3136

32-
const find = this.buckets[index].children.find((c) => {
33-
return c.id === this.item.id && c.content_type.value === this.item.content_type.value
37+
return this.buckets[index].children.some((c) => {
38+
return c.id === this.item.id && c.type === this.item.type
3439
})
35-
36-
return !!find
3740
},
38-
restrictedBySource: function (id) {
41+
restrictedBySource(id) {
3942
const bucket = this.buckets.find((b) => b.id === id)
4043
if (!bucket) return false
4144

4245
// In this case all sources are accepted by the bucket
4346
if (!bucket.hasOwnProperty('acceptedSources')) return true
4447
if (bucket.acceptedSources.length === 0) return true
4548

46-
const currentSource = this.item.content_type.value
47-
return bucket.acceptedSources.findIndex((source) => source === currentSource) !== -1
49+
const currentSource = this.dataSources.find((source) => source.type === this.item.type);
50+
return bucket.acceptedSources.findIndex((source) => source === currentSource.value) !== -1
4851
}
4952
}
5053
}

frontend/js/store/modules/buckets.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const state = {
2121
}
2222

2323
const getters = {
24-
currentSource: state => state.source.content_type
24+
currentSource: state => state.dataSources.selected
2525
}
2626

2727
const mutations = {
@@ -80,7 +80,7 @@ const actions = {
8080
bucket.children.forEach((child) => {
8181
children.push({
8282
id: child.id,
83-
type: child.content_type.value,
83+
type: child.type,
8484
starred: child.starred
8585
})
8686
})

src/Helpers/modules_helpers.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,18 @@ function getRepositoryByModuleName($moduleName)
6565
if (!function_exists('getModelRepository')) {
6666
function getModelRepository($relation, $model = null)
6767
{
68+
if ($relation instanceof TwillModelContract) {
69+
$model = get_class($relation);
70+
}
6871
if (!$model) {
6972
$model = ucfirst(Str::singular($relation));
7073
}
74+
if ($model instanceof TwillModelContract) {
75+
$model = get_class($model);
76+
}
77+
$model = class_basename($model);
7178

72-
$repository = config('twill.namespace') . '\\Repositories\\' . ucfirst($model) . 'Repository';
79+
$repository = config('twill.namespace') . '\\Repositories\\' . $model . 'Repository';
7380

7481
if (!class_exists($repository)) {
7582
try {

0 commit comments

Comments
 (0)