Skip to content

Commit

Permalink
Fix bucket morph map
Browse files Browse the repository at this point in the history
Improve buckets doc
  • Loading branch information
Tofandel committed Mar 12, 2024
1 parent ce0fbf1 commit ae1d637
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 127 deletions.
8 changes: 5 additions & 3 deletions docs/content/1_docs/9_buckets/1_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Then, define your buckets' configuration:
'name' => 'Home primary feature',
'bucketables' => [
[
'repository' => GuidesRepository::class,
'module' => 'guides',
'name' => 'Guides',
'scopes' => ['published' => true],
Expand All @@ -32,6 +33,7 @@ Then, define your buckets' configuration:
'name' => 'Home secondary features',
'bucketables' => [
[
'repository' => GuidesRepository::class,
'module' => 'guides',
'name' => 'Guides',
'scopes' => ['published' => true],
Expand All @@ -45,7 +47,7 @@ Then, define your buckets' configuration:
```

You can allow mixing modules in a single bucket by adding more modules to the `bucketables` array.
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.
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.

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

Expand All @@ -55,7 +57,7 @@ use Illuminate\Database\Eloquent\Relations\Relation;
public function boot()
{
Relation::morphMap([
'guides' => 'App\Models\Guide',
'guides' => App\Models\Guide::class,
]);
}
```
Expand All @@ -66,7 +68,7 @@ Finally, add a link to your buckets page in your CMS navigation:
return [
'featured' => [
'title' => 'Features',
'route' => 'admin.featured.homepage',
'route' => 'twill.featured.homepage',
'primary_navigation' => [
'homepage' => [
'title' => 'Homepage',
Expand Down
50 changes: 29 additions & 21 deletions frontend/js/components/buckets/Bucket.vue
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
<transition-group name="fade_scale_list" tag='tbody'>
<a17-bucket-item v-for="(child, index) in bucket.children" :key="`${child.id}_${index}`" :item="child"
:restricted="restricted" :draggable="bucket.children.length > 1"
:sourceLabels="sourceLabels"
:singleBucket="singleBucket" :singleSource="singleSource" :bucket="bucket.id"
:buckets="buckets" v-on:add-to-bucket="addToBucket"
v-on:remove-from-bucket="deleteFromBucket"
Expand Down Expand Up @@ -120,7 +121,7 @@
// Optionnal additionnal actions showing up after the Publish button
extraActions: {
type: Array,
default: function () { return [] }
default() { return [] }
}
},
components: {
Expand All @@ -132,7 +133,7 @@
'a17-vselect': VSelect,
draggable
},
data: function () {
data() {
return {
currentBucketID: '',
currentItem: '',
Expand All @@ -152,13 +153,20 @@
...mapGetters([
'currentSource'
]),
singleBucket: function () {
sourceLabels() {
const labels = {};
this.dataSources.forEach((source) => {
labels[source.type] = source.label;
})
return labels;
},
singleBucket() {
return this.buckets.length === 1
},
singleSource: function () {
singleSource() {
return this.dataSources.length === 1
},
overrideBucketText: function () {
overrideBucketText() {
const bucket = this.buckets.find(b => b.id === this.currentBucketID)
let bucketName = ''
let bucketSize = ''
Expand All @@ -170,7 +178,7 @@
}
},
methods: {
addToBucket: function (item, bucket) {
addToBucket(item, bucket) {
const index = this.buckets.findIndex(b => b.id === bucket)
if (!item && index === -1) return
Expand All @@ -188,22 +196,22 @@
if (count > -1 && count < this.buckets[index].max) {
// Commit before dispatch to prevent ui visual effect timeout
this.checkRestriced(item)
this.checkRestricted(item)
this.$store.commit(BUCKETS.ADD_TO_BUCKET, data)
} else if (this.overridableMax || this.overrideItem) {
this.checkRestriced(item)
this.checkRestricted(item)
this.$store.commit(BUCKETS.ADD_TO_BUCKET, data)
this.$store.commit(BUCKETS.DELETE_FROM_BUCKET, { index, itemIndex: 0 })
this.overrideItem = false
} else {
this.$refs.overrideBucket.open()
}
},
deleteFromBucket: function (item, bucket) {
deleteFromBucket(item, bucket) {
const bucketIndex = this.buckets.findIndex(b => b.id === bucket)
if (bucketIndex === -1) return
const itemIndex = this.buckets[bucketIndex].children.findIndex(c => c.id === item.id && c.content_type.value === item.content_type.value)
const itemIndex = this.buckets[bucketIndex].children.findIndex(c => c.id === item.id && c.type === item.type)
if (itemIndex === -1) return
Expand All @@ -213,11 +221,11 @@
}
this.$store.commit(BUCKETS.DELETE_FROM_BUCKET, data)
},
toggleFeaturedInBucket: function (item, bucket) {
toggleFeaturedInBucket(item, bucket) {
const bucketIndex = this.buckets.findIndex(b => b.id === bucket)
if (bucketIndex === -1) return
const itemIndex = this.buckets[bucketIndex].children.findIndex(c => c.id === item.id && c.content_type.value === item.content_type.value)
const itemIndex = this.buckets[bucketIndex].children.findIndex(c => c.id === item.id && c.type === item.type)
if (itemIndex === -1) return
Expand All @@ -228,55 +236,55 @@
this.$store.commit(BUCKETS.TOGGLE_FEATURED_IN_BUCKET, data)
},
checkRestriced: function (item) {
checkRestricted(item) {
// Remove item from each bucket if option restricted to one bucket is active
if (this.restricted) {
this.buckets.forEach((bucket) => {
bucket.children.forEach((child) => {
if (child.id === item.id && child.content_type.value === item.content_type.value) {
if (child.id === item.id && child.type === item.type) {
this.deleteFromBucket(item, bucket.id)
}
})
})
}
},
sortBucket: function (evt, index) {
sortBucket(evt, index) {
const data = {
bucketIndex: index,
oldIndex: evt.moved.oldIndex,
newIndex: evt.moved.newIndex
}
this.$store.commit(BUCKETS.REORDER_BUCKET_LIST, data)
},
changeDataSource: function (value) {
changeDataSource(value) {
this.$store.commit(BUCKETS.UPDATE_BUCKETS_DATASOURCE, value)
this.$store.commit(BUCKETS.UPDATE_BUCKETS_DATA_PAGE, 1)
this.$store.dispatch(ACTIONS.GET_BUCKETS)
},
filterBucketsData: function (formData) {
filterBucketsData(formData) {
this.$store.commit(BUCKETS.UPDATE_BUCKETS_DATA_PAGE, 1)
this.$store.commit(BUCKETS.UPDATE_BUCKETS_FILTER, formData || { search: '' })
// reload datas
this.$store.dispatch(ACTIONS.GET_BUCKETS)
},
updateOffset: function (value) {
updateOffset(value) {
this.$store.commit(BUCKETS.UPDATE_BUCKETS_DATA_PAGE, 1)
this.$store.commit(BUCKETS.UPDATE_BUCKETS_DATA_OFFSET, value)
// reload datas
this.$store.dispatch(ACTIONS.GET_BUCKETS)
},
updatePage: function (value) {
updatePage(value) {
this.$store.commit(BUCKETS.UPDATE_BUCKETS_DATA_PAGE, value)
// reload datas
this.$store.dispatch(ACTIONS.GET_BUCKETS)
},
override: function () {
override() {
this.overrideItem = true
this.addToBucket(this.currentItem, this.currentBucketID)
this.$refs.overrideBucket.close()
},
save: function () {
save() {
this.$store.dispatch(ACTIONS.SAVE_BUCKETS)
}
}
Expand Down
39 changes: 18 additions & 21 deletions frontend/js/components/buckets/BucketItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
<span v-else>{{ item.name }}</span>
</h4>
</td>
<td class="buckets__itemContentType" v-if="item.content_type &&!singleSource">
{{ item.content_type.label }}
<td class="buckets__itemContentType" v-if="item.type && !singleSource">
{{ sourceLabels[item.type] }}
</td>
<td class="buckets__itemOptions">
<a17-dropdown v-if="!singleBucket" ref="bucketDropdown" class="item__dropdown bucket__action" position="bottom-right" title="Featured in" :clickable="true">
Expand Down Expand Up @@ -75,29 +75,26 @@
toggleFeaturedLabels: {
type: Array,
default: () => []
}
},
sourceLabels: Object,
},
mixins: [bucketMixin],
computed: {
inBuckets: function () {
const self = this
let find = false
self.buckets.forEach(function (bucket) {
if (bucket.children.find(function (b) {
return b.id === self.item.id && b.content_type.value === self.item.content_type.value
})) {
find = true
inBuckets() {
for(const bucket in this.buckets) {
if (bucket.children.some((b) => b.id === self.item.id && b.type === self.item.type)) {
return true
}
})
return find
}
return false
},
customClasses: function () {
customClasses() {
return {
...this.bucketClasses,
draggable: this.draggable
}
},
dropDownBuckets: function () {
dropDownBuckets() {
const checkboxes = []
const self = this
let index = 1
Expand All @@ -116,13 +113,13 @@
}
},
methods: {
removeFromBucket: function (bucketId = this.bucket) {
removeFromBucket(bucketId = this.bucket) {
this.$emit('remove-from-bucket', this.item, bucketId)
},
toggleFeatured: function () {
toggleFeatured() {
this.$emit('toggle-featured-in-bucket', this.item, this.bucket)
},
selectedBuckets: function () {
selectedBuckets() {
const selected = []
const self = this
if (this.buckets.length > 0) {
Expand All @@ -135,11 +132,11 @@
}
return []
},
slug: function (id) {
slug(id) {
// Current Bucket ID + item id + bucket id
return 'bucket-' + this.bucket + '_item-' + this.item.id + '_type-' + this.item.content_type.value + '_inb-' + id
return 'bucket-' + this.bucket + '_item-' + this.item.id + '_type-' + this.item.type + '_inb-' + id
},
updateBucket: function (value) {
updateBucket(value) {
const pattern = 'inb-'
const self = this
Expand Down
23 changes: 13 additions & 10 deletions frontend/js/mixins/buckets.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { mapState } from 'vuex'

export default {
props: {
buckets: {
Expand All @@ -13,38 +15,39 @@ export default {
}
},
computed: {
bucketClasses: function () {
...mapState({
dataSources: state => state.buckets.dataSources.content_types
}),
bucketClasses() {
return {
selected: this.type !== 'bucket' && this.inBuckets,
single: this.singleBucket
}
}
},
methods: {
addToBucket: function (bucketId = this.bucket) {
addToBucket(bucketId = this.bucket) {
this.$emit('add-to-bucket', this.item, bucketId)
},
inBucketById: function (id) {
inBucketById(id) {
const index = this.buckets.findIndex(b => b.id === id)

if (index === -1) return

const find = this.buckets[index].children.find((c) => {
return c.id === this.item.id && c.content_type.value === this.item.content_type.value
return this.buckets[index].children.some((c) => {
return c.id === this.item.id && c.type === this.item.type
})

return !!find
},
restrictedBySource: function (id) {
restrictedBySource(id) {
const bucket = this.buckets.find((b) => b.id === id)
if (!bucket) return false

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

const currentSource = this.item.content_type.value
return bucket.acceptedSources.findIndex((source) => source === currentSource) !== -1
const currentSource = this.dataSources.find((source) => source.type === this.item.type);
return bucket.acceptedSources.findIndex((source) => source === currentSource.value) !== -1
}
}
}
4 changes: 2 additions & 2 deletions frontend/js/store/modules/buckets.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const state = {
}

const getters = {
currentSource: state => state.source.content_type
currentSource: state => state.dataSources.selected
}

const mutations = {
Expand Down Expand Up @@ -80,7 +80,7 @@ const actions = {
bucket.children.forEach((child) => {
children.push({
id: child.id,
type: child.content_type.value,
type: child.type,
starred: child.starred
})
})
Expand Down
9 changes: 8 additions & 1 deletion src/Helpers/modules_helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,18 @@ function getRepositoryByModuleName($moduleName)
if (!function_exists('getModelRepository')) {
function getModelRepository($relation, $model = null)
{
if ($relation instanceof TwillModelContract) {
$model = get_class($relation);

Check warning on line 69 in src/Helpers/modules_helpers.php

View check run for this annotation

Codecov / codecov/patch

src/Helpers/modules_helpers.php#L69

Added line #L69 was not covered by tests
}
if (!$model) {
$model = ucfirst(Str::singular($relation));
}
if ($model instanceof TwillModelContract) {
$model = get_class($model);

Check warning on line 75 in src/Helpers/modules_helpers.php

View check run for this annotation

Codecov / codecov/patch

src/Helpers/modules_helpers.php#L75

Added line #L75 was not covered by tests
}
$model = class_basename($model);

$repository = config('twill.namespace') . '\\Repositories\\' . ucfirst($model) . 'Repository';
$repository = config('twill.namespace') . '\\Repositories\\' . $model . 'Repository';

if (!class_exists($repository)) {
try {
Expand Down

0 comments on commit ae1d637

Please sign in to comment.