@blokkli/editor 1.1.3 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module.json +1 -1
- package/dist/module.mjs +16 -1
- package/dist/runtime/adapter/drupal/graphql/base.graphql +26 -0
- package/dist/runtime/adapter/drupal/graphqlMiddleware.js +18 -0
- package/dist/runtime/adapter/index.d.ts +9 -0
- package/dist/runtime/components/Edit/Features/DraggingOverlay/index.vue +20 -6
- package/dist/runtime/components/Edit/Features/MediaLibrary/Library/Item.vue +44 -0
- package/dist/runtime/components/Edit/Features/MediaLibrary/Library/index.vue +66 -34
- package/dist/runtime/components/Edit/Sortli/index.vue +6 -1
- package/dist/runtime/css/output.css +1 -1
- package/dist/runtime/types/generatedModuleTypes.d.ts +4 -4
- package/package.json +1 -1
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -7,7 +7,7 @@ import MagicString from 'magic-string';
|
|
|
7
7
|
import { walk } from 'estree-walker-ts';
|
|
8
8
|
import { BK_VISIBLE_LANGUAGES, BK_HIDDEN_GLOBALLY } from '../dist/runtime/helpers/symbols.js';
|
|
9
9
|
|
|
10
|
-
const version = "1.
|
|
10
|
+
const version = "1.2.0";
|
|
11
11
|
|
|
12
12
|
function sortObjectKeys(obj) {
|
|
13
13
|
if (Array.isArray(obj)) {
|
|
@@ -850,6 +850,10 @@ const cancel$2 = {
|
|
|
850
850
|
source: "Cancel",
|
|
851
851
|
translation: "Abbrechen"
|
|
852
852
|
};
|
|
853
|
+
const cancelSelection$2 = {
|
|
854
|
+
source: "Cancel selection",
|
|
855
|
+
translation: "Auswahl abbrechen"
|
|
856
|
+
};
|
|
853
857
|
const clipboard$2 = {
|
|
854
858
|
source: "Clipboard",
|
|
855
859
|
translation: "Zwischenablage"
|
|
@@ -1689,6 +1693,7 @@ const de = {
|
|
|
1689
1693
|
blockOption_bkHiddenGlobally_label: blockOption_bkHiddenGlobally_label$2,
|
|
1690
1694
|
blockOption_bkVisibleLanguages_label: blockOption_bkVisibleLanguages_label$2,
|
|
1691
1695
|
cancel: cancel$2,
|
|
1696
|
+
cancelSelection: cancelSelection$2,
|
|
1692
1697
|
clipboard: clipboard$2,
|
|
1693
1698
|
clipboardCopyShortcutHelp: clipboardCopyShortcutHelp$2,
|
|
1694
1699
|
clipboardEmpty: clipboardEmpty$2,
|
|
@@ -2093,6 +2098,10 @@ const cancel$1 = {
|
|
|
2093
2098
|
source: "Cancel",
|
|
2094
2099
|
translation: "Annuler"
|
|
2095
2100
|
};
|
|
2101
|
+
const cancelSelection$1 = {
|
|
2102
|
+
source: "Cancel selection",
|
|
2103
|
+
translation: ""
|
|
2104
|
+
};
|
|
2096
2105
|
const clipboard$1 = {
|
|
2097
2106
|
source: "Clipboard",
|
|
2098
2107
|
translation: "Presse-papiers"
|
|
@@ -2932,6 +2941,7 @@ const fr = {
|
|
|
2932
2941
|
blockOption_bkHiddenGlobally_label: blockOption_bkHiddenGlobally_label$1,
|
|
2933
2942
|
blockOption_bkVisibleLanguages_label: blockOption_bkVisibleLanguages_label$1,
|
|
2934
2943
|
cancel: cancel$1,
|
|
2944
|
+
cancelSelection: cancelSelection$1,
|
|
2935
2945
|
clipboard: clipboard$1,
|
|
2936
2946
|
clipboardCopyShortcutHelp: clipboardCopyShortcutHelp$1,
|
|
2937
2947
|
clipboardEmpty: clipboardEmpty$1,
|
|
@@ -3336,6 +3346,10 @@ const cancel = {
|
|
|
3336
3346
|
source: "Cancel",
|
|
3337
3347
|
translation: "Annulla"
|
|
3338
3348
|
};
|
|
3349
|
+
const cancelSelection = {
|
|
3350
|
+
source: "Cancel selection",
|
|
3351
|
+
translation: ""
|
|
3352
|
+
};
|
|
3339
3353
|
const clipboard = {
|
|
3340
3354
|
source: "Clipboard",
|
|
3341
3355
|
translation: "Appunti"
|
|
@@ -4175,6 +4189,7 @@ const it = {
|
|
|
4175
4189
|
blockOption_bkHiddenGlobally_label: blockOption_bkHiddenGlobally_label,
|
|
4176
4190
|
blockOption_bkVisibleLanguages_label: blockOption_bkVisibleLanguages_label,
|
|
4177
4191
|
cancel: cancel,
|
|
4192
|
+
cancelSelection: cancelSelection,
|
|
4178
4193
|
clipboard: clipboard,
|
|
4179
4194
|
clipboardCopyShortcutHelp: clipboardCopyShortcutHelp,
|
|
4180
4195
|
clipboardEmpty: clipboardEmpty,
|
|
@@ -700,6 +700,32 @@ mutation pbAddEntityReference(
|
|
|
700
700
|
}
|
|
701
701
|
}
|
|
702
702
|
|
|
703
|
+
mutation pbAddEntityReferenceMultiple(
|
|
704
|
+
$langcode: String
|
|
705
|
+
$entityType: EntityType!
|
|
706
|
+
$entityUuid: String!
|
|
707
|
+
$references: [ParagraphsBlokkliAddEntityReferenceMultipleInput]!
|
|
708
|
+
$hostType: String!
|
|
709
|
+
$hostUuid: String!
|
|
710
|
+
$hostFieldName: String!
|
|
711
|
+
$afterUuid: String
|
|
712
|
+
) {
|
|
713
|
+
state: paragraphsEditMutationState(
|
|
714
|
+
entityType: $entityType
|
|
715
|
+
entityUuid: $entityUuid
|
|
716
|
+
) {
|
|
717
|
+
action: add_entity_reference_multiple(
|
|
718
|
+
references: $references
|
|
719
|
+
afterUuid: $afterUuid
|
|
720
|
+
hostType: $hostType
|
|
721
|
+
hostUuid: $hostUuid
|
|
722
|
+
hostFieldName: $hostFieldName
|
|
723
|
+
) {
|
|
724
|
+
...paragraphsBlokkliMutationResult
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
|
|
703
729
|
query pbConfig($entityType: String!, $entityBundle: String!) {
|
|
704
730
|
clipboards: pbGetSupportedClipboards {
|
|
705
731
|
...paragraphsBlokkliSupportedClipboard
|
|
@@ -491,6 +491,23 @@ export default defineBlokkliEditAdapter(
|
|
|
491
491
|
afterUuid: e.preceedingUuid
|
|
492
492
|
}).then(mapMutation);
|
|
493
493
|
};
|
|
494
|
+
const mediaLibraryAddBlocks = (e) => {
|
|
495
|
+
return useGraphqlMutation("pbAddEntityReferenceMultiple", {
|
|
496
|
+
...ctx.value,
|
|
497
|
+
references: e.items.map((item) => {
|
|
498
|
+
return {
|
|
499
|
+
targetId: item.mediaId,
|
|
500
|
+
targetType: "media",
|
|
501
|
+
targetBundle: item.mediaBundle,
|
|
502
|
+
paragraphBundle: item.itemBundle
|
|
503
|
+
};
|
|
504
|
+
}),
|
|
505
|
+
hostType: e.host.type,
|
|
506
|
+
hostUuid: e.host.uuid,
|
|
507
|
+
hostFieldName: e.host.fieldName,
|
|
508
|
+
afterUuid: e.preceedingUuid
|
|
509
|
+
}).then(mapMutation);
|
|
510
|
+
};
|
|
494
511
|
const getContentSearchTabs = () => {
|
|
495
512
|
return useGraphqlQuery("pbSearchTabs").then((v) => {
|
|
496
513
|
return (v.data.tabs || []).reduce(
|
|
@@ -642,6 +659,7 @@ export default defineBlokkliEditAdapter(
|
|
|
642
659
|
getDroppableFieldConfig,
|
|
643
660
|
mediaLibraryGetResults,
|
|
644
661
|
mediaLibraryAddBlock,
|
|
662
|
+
mediaLibraryAddBlocks,
|
|
645
663
|
getContentSearchTabs,
|
|
646
664
|
getContentSearchResults,
|
|
647
665
|
addContentSearchItem,
|
|
@@ -26,6 +26,11 @@ export type MediaLibraryAddBlockEvent = {
|
|
|
26
26
|
preceedingUuid?: string;
|
|
27
27
|
item: DraggableMediaLibraryItem;
|
|
28
28
|
};
|
|
29
|
+
export type MediaLibraryAddBlocksEvent = {
|
|
30
|
+
host: DraggableHostData;
|
|
31
|
+
preceedingUuid?: string;
|
|
32
|
+
items: DraggableMediaLibraryItem[];
|
|
33
|
+
};
|
|
29
34
|
export type MediaLibraryReplaceMediaEvent = {
|
|
30
35
|
/**
|
|
31
36
|
* The UUID of the block on which the media was dropped.
|
|
@@ -343,6 +348,10 @@ export interface BlokkliAdapter<T> {
|
|
|
343
348
|
* Create a new block from the given media library item.
|
|
344
349
|
*/
|
|
345
350
|
mediaLibraryAddBlock?: (e: MediaLibraryAddBlockEvent) => Promise<MutationResponseLike<T>> | undefined;
|
|
351
|
+
/**
|
|
352
|
+
* Create new blocks from the given media library items.
|
|
353
|
+
*/
|
|
354
|
+
mediaLibraryAddBlocks?: (e: MediaLibraryAddBlocksEvent) => Promise<MutationResponseLike<T>> | undefined;
|
|
346
355
|
/**
|
|
347
356
|
* Replace an existing media from a block with a new one.
|
|
348
357
|
*
|
|
@@ -90,7 +90,9 @@ type FilteredItemType<T extends DraggableItem> = T extends {
|
|
|
90
90
|
? { itemType: 'existing'; items: T[] }
|
|
91
91
|
: T extends { itemType: 'existing_structure' }
|
|
92
92
|
? { itemType: 'existing_structure'; items: T[] }
|
|
93
|
-
: { itemType:
|
|
93
|
+
: T extends { itemType: 'media_library' }
|
|
94
|
+
? { itemType: 'media_library'; items: T[] }
|
|
95
|
+
: { itemType: T['itemType']; item: T }
|
|
94
96
|
|
|
95
97
|
function filterItemType<T extends DraggableItem>(
|
|
96
98
|
items: T[],
|
|
@@ -105,7 +107,11 @@ function filterItemType<T extends DraggableItem>(
|
|
|
105
107
|
|
|
106
108
|
const itemType = items[0].itemType
|
|
107
109
|
|
|
108
|
-
if (
|
|
110
|
+
if (
|
|
111
|
+
itemType === 'existing' ||
|
|
112
|
+
itemType === 'existing_structure' ||
|
|
113
|
+
itemType === 'media_library'
|
|
114
|
+
) {
|
|
109
115
|
return { itemType, items } as any
|
|
110
116
|
}
|
|
111
117
|
|
|
@@ -211,16 +217,24 @@ const onDropClipboardItem = async (
|
|
|
211
217
|
}
|
|
212
218
|
|
|
213
219
|
const onDropMediaLibraryItem = async (
|
|
214
|
-
|
|
220
|
+
items: DraggableMediaLibraryItem[],
|
|
215
221
|
host: DraggableHostData,
|
|
216
222
|
afterUuid?: string,
|
|
217
223
|
) => {
|
|
218
|
-
if (adapter.mediaLibraryAddBlock) {
|
|
224
|
+
if (adapter.mediaLibraryAddBlock && items.length === 1) {
|
|
219
225
|
await state.mutateWithLoadingState(() =>
|
|
220
226
|
adapter.mediaLibraryAddBlock({
|
|
221
227
|
preceedingUuid: afterUuid,
|
|
222
228
|
host,
|
|
223
|
-
item,
|
|
229
|
+
item: items[0],
|
|
230
|
+
}),
|
|
231
|
+
)
|
|
232
|
+
} else if (adapter.mediaLibraryAddBlocks && items.length > 1) {
|
|
233
|
+
await state.mutateWithLoadingState(() =>
|
|
234
|
+
adapter.mediaLibraryAddBlocks({
|
|
235
|
+
preceedingUuid: afterUuid,
|
|
236
|
+
host,
|
|
237
|
+
items,
|
|
224
238
|
}),
|
|
225
239
|
)
|
|
226
240
|
}
|
|
@@ -279,7 +293,7 @@ const onDrop = (e: DropTargetEvent) => {
|
|
|
279
293
|
} else if (typed.itemType === 'action') {
|
|
280
294
|
onDropAction(typed.item, host, e.field, afterUuid)
|
|
281
295
|
} else if (typed.itemType === 'media_library') {
|
|
282
|
-
await onDropMediaLibraryItem(typed.
|
|
296
|
+
await onDropMediaLibraryItem(typed.items, host, afterUuid)
|
|
283
297
|
}
|
|
284
298
|
|
|
285
299
|
eventBus.emit('dragging:end')
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
:key="mediaId"
|
|
4
|
+
class="bk-media-library-items-item"
|
|
5
|
+
:class="{ 'bk-is-selected': isSelected }"
|
|
6
|
+
:data-sortli-id="'media_library_' + mediaId"
|
|
7
|
+
data-element-type="media_library"
|
|
8
|
+
:data-item-bundle="targetBundles[0]"
|
|
9
|
+
:data-media-id="mediaId"
|
|
10
|
+
:data-media-bundle="mediaBundle"
|
|
11
|
+
>
|
|
12
|
+
<div class="bk-media-library-items-item-box">
|
|
13
|
+
<label @click.stop>
|
|
14
|
+
<input v-model="selected" type="checkbox" :value="mediaId" />
|
|
15
|
+
</label>
|
|
16
|
+
<div class="bk-media-library-items-item-image">
|
|
17
|
+
<img :src="thumbnail" />
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
<div class="bk-media-library-items-item-text">
|
|
21
|
+
<h3>{{ label }}</h3>
|
|
22
|
+
<p>{{ context }}</p>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
</template>
|
|
26
|
+
|
|
27
|
+
<script setup lang="ts">
|
|
28
|
+
import type { BlokkliIcon } from '#blokkli/icons'
|
|
29
|
+
import { computed } from '#imports'
|
|
30
|
+
|
|
31
|
+
const props = defineProps<{
|
|
32
|
+
mediaId: string
|
|
33
|
+
label: string
|
|
34
|
+
context: string
|
|
35
|
+
targetBundles: string[]
|
|
36
|
+
thumbnail?: string
|
|
37
|
+
icon?: BlokkliIcon
|
|
38
|
+
mediaBundle?: string
|
|
39
|
+
}>()
|
|
40
|
+
|
|
41
|
+
const selected = defineModel<string[]>()
|
|
42
|
+
|
|
43
|
+
const isSelected = computed(() => selected.value?.includes(props.mediaId))
|
|
44
|
+
</script>
|
|
@@ -50,30 +50,24 @@
|
|
|
50
50
|
class="bk-media-library-items bk-scrollbar-light"
|
|
51
51
|
:class="[{ 'bk-is-sortli': isSortli }, 'bk-is-' + listView]"
|
|
52
52
|
>
|
|
53
|
-
<
|
|
54
|
-
<
|
|
53
|
+
<Sortli v-if="isSortli" no-transition :get-drag-items="getDragItems">
|
|
54
|
+
<Item
|
|
55
55
|
v-for="item in items"
|
|
56
56
|
:key="item.mediaId"
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
<div class="bk-media-library-items-item-text">
|
|
72
|
-
<h3>{{ item.label }}</h3>
|
|
73
|
-
<p>{{ item.context }}</p>
|
|
74
|
-
</div>
|
|
75
|
-
</div>
|
|
76
|
-
</Component>
|
|
57
|
+
v-bind="item"
|
|
58
|
+
v-model="selected"
|
|
59
|
+
/>
|
|
60
|
+
</Sortli>
|
|
61
|
+
|
|
62
|
+
<div v-else>
|
|
63
|
+
<Item v-for="item in items" :key="item.mediaId" v-bind="item" />
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
<div v-if="selected.length" class="bk-media-library-cancel">
|
|
68
|
+
<button class="bk-button bk-is-primary" @click.prevent="selected = []">
|
|
69
|
+
{{ $t('cancelSelection', 'Cancel selection') }}
|
|
70
|
+
</button>
|
|
77
71
|
</div>
|
|
78
72
|
|
|
79
73
|
<div class="bk-pagination">
|
|
@@ -100,20 +94,60 @@ import {
|
|
|
100
94
|
import { Sortli, Icon } from '#blokkli/components'
|
|
101
95
|
import type { MediaLibraryFilter, MediaLibraryGetResults } from './../types'
|
|
102
96
|
import type { BlokkliIcon } from '#blokkli/icons'
|
|
97
|
+
import Item from './Item.vue'
|
|
98
|
+
import type { DraggableItem, DraggableMediaLibraryItem } from '#blokkli/types'
|
|
99
|
+
import { buildDraggableItem, falsy } from '#blokkli/helpers'
|
|
100
|
+
import onBlokkliEvent from '#blokkli/helpers/composables/onBlokkliEvent'
|
|
103
101
|
|
|
104
|
-
|
|
102
|
+
defineProps<{
|
|
105
103
|
isSortli?: boolean
|
|
106
104
|
modelValue?: string
|
|
107
105
|
}>()
|
|
108
106
|
|
|
109
|
-
const
|
|
107
|
+
const { adapter, storage, $t } = useBlokkli()
|
|
108
|
+
|
|
109
|
+
const selected = ref<string[]>([])
|
|
110
|
+
const listEl = ref<HTMLDivElement | null>(null)
|
|
111
|
+
const page = ref(0)
|
|
112
|
+
const key = computed(() => Object.values(filterValues.value).join(','))
|
|
113
|
+
|
|
114
|
+
function getDragItems(activeItem?: DraggableItem): DraggableItem[] | null {
|
|
115
|
+
if (!selected.value.length || !listEl.value) {
|
|
116
|
+
return null
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const activeId =
|
|
120
|
+
activeItem?.itemType === 'media_library' ? activeItem.mediaId : null
|
|
121
|
+
|
|
122
|
+
const items: DraggableMediaLibraryItem[] = selected.value
|
|
123
|
+
.map((id) => {
|
|
124
|
+
const el = listEl.value?.querySelector(
|
|
125
|
+
`[data-sortli-id="media_library_${id}"]`,
|
|
126
|
+
)
|
|
127
|
+
if (!(el instanceof HTMLElement)) {
|
|
128
|
+
return null
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const item = buildDraggableItem(el)
|
|
132
|
+
if (item?.itemType === 'media_library') {
|
|
133
|
+
return item
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return null
|
|
137
|
+
})
|
|
138
|
+
.filter(falsy)
|
|
139
|
+
|
|
140
|
+
if (!activeId) {
|
|
141
|
+
return items
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const activeIsInSelection = items.find((v) => v.mediaId === activeId)
|
|
110
145
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
return
|
|
146
|
+
if (activeIsInSelection) {
|
|
147
|
+
return items
|
|
114
148
|
}
|
|
115
149
|
|
|
116
|
-
|
|
150
|
+
return null
|
|
117
151
|
}
|
|
118
152
|
|
|
119
153
|
type RenderedFilter = {
|
|
@@ -121,8 +155,6 @@ type RenderedFilter = {
|
|
|
121
155
|
filter: MediaLibraryFilter
|
|
122
156
|
}
|
|
123
157
|
|
|
124
|
-
const { adapter, storage } = useBlokkli()
|
|
125
|
-
|
|
126
158
|
const listView = storage.use<'horizontal' | 'grid'>(
|
|
127
159
|
'mediaLibraryListView',
|
|
128
160
|
'grid',
|
|
@@ -142,10 +174,6 @@ const toggleListView = () => {
|
|
|
142
174
|
|
|
143
175
|
const filterValues = ref<Record<string, any>>({})
|
|
144
176
|
|
|
145
|
-
const listEl = ref<HTMLDivElement | null>(null)
|
|
146
|
-
const page = ref(0)
|
|
147
|
-
const key = computed(() => Object.values(filterValues.value).join(','))
|
|
148
|
-
|
|
149
177
|
watch(key, () => {
|
|
150
178
|
page.value = 0
|
|
151
179
|
})
|
|
@@ -182,4 +210,8 @@ const perPage = computed(() => data.value?.perPage || 0)
|
|
|
182
210
|
const totalPages = computed(() => {
|
|
183
211
|
return Math.ceil(total.value / perPage.value)
|
|
184
212
|
})
|
|
213
|
+
|
|
214
|
+
onBlokkliEvent('item:dropped', function () {
|
|
215
|
+
selected.value = []
|
|
216
|
+
})
|
|
185
217
|
</script>
|
|
@@ -19,6 +19,10 @@ import {
|
|
|
19
19
|
|
|
20
20
|
const { eventBus } = useBlokkli()
|
|
21
21
|
|
|
22
|
+
const props = defineProps<{
|
|
23
|
+
getDragItems?: (activeItem?: DraggableItem) => DraggableItem[] | null
|
|
24
|
+
}>()
|
|
25
|
+
|
|
22
26
|
let pointerStartCoords: Coord | null = null
|
|
23
27
|
let activeItem: DraggableItem | null = null
|
|
24
28
|
|
|
@@ -55,8 +59,9 @@ function onPointerMove(e: PointerEvent) {
|
|
|
55
59
|
const distance = getDistance(coords, pointerStartCoords)
|
|
56
60
|
|
|
57
61
|
if (distance > 7) {
|
|
62
|
+
const dragItems = props.getDragItems ? props.getDragItems(activeItem) : null
|
|
58
63
|
eventBus.emit('dragging:start', {
|
|
59
|
-
items: [activeItem],
|
|
64
|
+
items: dragItems && dragItems.length ? dragItems : [activeItem],
|
|
60
65
|
coords,
|
|
61
66
|
mode: 'mouse',
|
|
62
67
|
})
|