@blokkli/editor 2.0.0-alpha.17 → 2.0.0-alpha.18
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 +380 -59
- package/dist/modules/drupal/graphql/base/fragment.paragraphsFieldItem.graphql +3 -1
- package/dist/modules/drupal/graphql/base/query.pbConfig.graphql +1 -10
- package/dist/modules/drupal/graphql/mutations/set_paragraph_schedule.graphql +15 -0
- package/dist/modules/drupal/index.mjs +33 -0
- package/dist/modules/drupal/runtime/adapter/index.js +10 -2
- package/dist/runtime/adapter/index.d.ts +21 -0
- package/dist/runtime/blokkliPlugins/ContextMenu/Menu/index.vue +3 -0
- package/dist/runtime/blokkliPlugins/ItemAction/index.vue +23 -13
- package/dist/runtime/blokkliPlugins/ItemAction/index.vue.d.ts +20 -44
- package/dist/runtime/blokkliPlugins/TourItem/index.vue +10 -5
- package/dist/runtime/components/BlokkliEditable.vue +13 -13
- package/dist/runtime/components/BlokkliField.vue +3 -0
- package/dist/runtime/components/BlokkliField.vue.d.ts +3 -3
- package/dist/runtime/components/BlokkliItem.vue +1 -1
- package/dist/runtime/components/BlokkliItem.vue.d.ts +4 -2
- package/dist/runtime/components/BlokkliProvider.vue +12 -8
- package/dist/runtime/components/Edit/Actions/index.vue +27 -16
- package/dist/runtime/components/Edit/AnimationCanvas/index.vue +26 -10
- package/dist/runtime/components/Edit/ArtboardTooltip/index.vue +3 -0
- package/dist/runtime/components/Edit/Dialog/index.vue +6 -4
- package/dist/runtime/components/Edit/DraggableList.vue +15 -7
- package/dist/runtime/components/Edit/DraggableList.vue.d.ts +5 -5
- package/dist/runtime/components/Edit/EditProvider.vue +29 -16
- package/dist/runtime/components/Edit/EditProvider.vue.d.ts +1 -0
- package/dist/runtime/components/Edit/Features/AddList/index.vue +9 -11
- package/dist/runtime/components/Edit/Features/Analyze/Overlay/index.vue +9 -6
- package/dist/runtime/components/Edit/Features/Analyze/Renderer.vue +1 -1
- package/dist/runtime/components/Edit/Features/Analyze/Results/ResultsItemNodesTarget.vue +15 -11
- package/dist/runtime/components/Edit/Features/Anchors/Renderer.vue +19 -102
- package/dist/runtime/components/Edit/Features/Artboard/Renderer.vue +3 -0
- package/dist/runtime/components/Edit/Features/BlockAddList/index.vue +28 -52
- package/dist/runtime/components/Edit/Features/BlockScheduler/Dialog/ScheduleSection.vue +154 -0
- package/dist/runtime/components/Edit/Features/BlockScheduler/Dialog/ScheduleSection.vue.d.ts +27 -0
- package/dist/runtime/components/Edit/Features/BlockScheduler/Dialog/index.vue +222 -0
- package/dist/runtime/components/Edit/Features/BlockScheduler/Dialog/index.vue.d.ts +11 -0
- package/dist/runtime/components/Edit/Features/BlockScheduler/index.vue +96 -0
- package/dist/runtime/components/Edit/Features/BlockScheduler/index.vue.d.ts +2 -0
- package/dist/runtime/components/Edit/Features/Clipboard/index.vue +15 -16
- package/dist/runtime/components/Edit/Features/CommandPalette/Palette/Item/index.vue +51 -0
- package/dist/runtime/components/Edit/Features/CommandPalette/Palette/{Group → Item}/index.vue.d.ts +9 -13
- package/dist/runtime/components/Edit/Features/CommandPalette/Palette/index.vue +46 -66
- package/dist/runtime/components/Edit/Features/Comments/index.vue +1 -1
- package/dist/runtime/components/Edit/Features/Conversions/index.vue +4 -7
- package/dist/runtime/components/Edit/Features/Debug/Rects/index.vue +2 -2
- package/dist/runtime/components/Edit/Features/Debug/index.vue +4 -1
- package/dist/runtime/components/Edit/Features/Delete/index.vue +1 -1
- package/dist/runtime/components/Edit/Features/DraggingOverlay/DragItems/index.vue +13 -5
- package/dist/runtime/components/Edit/Features/DraggingOverlay/DropTargets/index.vue +14 -11
- package/dist/runtime/components/Edit/Features/DraggingOverlay/index.vue +30 -18
- package/dist/runtime/components/Edit/Features/Duplicate/index.vue +6 -8
- package/dist/runtime/components/Edit/Features/Edit/index.vue +15 -21
- package/dist/runtime/components/Edit/Features/EditForm/index.vue +7 -6
- package/dist/runtime/components/Edit/Features/EditableField/Overlay/Frame/index.vue +8 -3
- package/dist/runtime/components/Edit/Features/EditableField/Overlay/Frame/index.vue.d.ts +2 -2
- package/dist/runtime/components/Edit/Features/EditableField/Overlay/index.vue +29 -12
- package/dist/runtime/components/Edit/Features/EditableField/Overlay/index.vue.d.ts +2 -2
- package/dist/runtime/components/Edit/Features/EditableField/index.vue +40 -42
- package/dist/runtime/components/Edit/Features/Fragments/Dialog/index.vue +11 -9
- package/dist/runtime/components/Edit/Features/Fragments/index.vue +3 -3
- package/dist/runtime/components/Edit/Features/Hover/Overlay/index.vue +16 -25
- package/dist/runtime/components/Edit/Features/Library/EditReusable/index.vue +5 -7
- package/dist/runtime/components/Edit/Features/Library/ReusableDialog/index.vue +5 -5
- package/dist/runtime/components/Edit/Features/Library/index.vue +27 -23
- package/dist/runtime/components/Edit/Features/MediaLibrary/Library/index.vue +6 -3
- package/dist/runtime/components/Edit/Features/MediaLibrary/index.vue +15 -12
- package/dist/runtime/components/Edit/Features/MultiSelect/Overlay/index.vue +2 -2
- package/dist/runtime/components/Edit/Features/Options/Form/index.vue +7 -6
- package/dist/runtime/components/Edit/Features/Options/index.vue +6 -6
- package/dist/runtime/components/Edit/Features/Publish/Dialog/index.vue +68 -15
- package/dist/runtime/components/Edit/Features/Search/Overlay/Results/Page/index.vue +15 -15
- package/dist/runtime/components/Edit/Features/Search/index.vue +4 -1
- package/dist/runtime/components/Edit/Features/Selection/AddButtons/Overlay/index.vue.d.ts +3 -3
- package/dist/runtime/components/Edit/Features/Selection/AddButtons/Renderer/index.vue +34 -11
- package/dist/runtime/components/Edit/Features/Selection/AddButtons/index.vue +21 -20
- package/dist/runtime/components/Edit/Features/Selection/AddButtons/index.vue.d.ts +2 -2
- package/dist/runtime/components/Edit/Features/Selection/Overlay/index.vue.d.ts +3 -3
- package/dist/runtime/components/Edit/Features/Selection/OverlayFallback/index.vue +2 -2
- package/dist/runtime/components/Edit/Features/Selection/index.vue +61 -27
- package/dist/runtime/components/Edit/Features/Structure/List/Field/index.vue +2 -2
- package/dist/runtime/components/Edit/Features/Structure/List/Item/index.vue +13 -6
- package/dist/runtime/components/Edit/Features/Tour/Overlay/index.vue +3 -0
- package/dist/runtime/components/Edit/Features/Transform/index.vue +2 -27
- package/dist/runtime/components/Edit/Features/Translations/index.vue +7 -7
- package/dist/runtime/components/Edit/Features/Validations/SidebarItem/index.vue +5 -5
- package/dist/runtime/components/Edit/Features/index.vue +17 -7
- package/dist/runtime/components/Edit/Form/Toggle/index.vue +4 -3
- package/dist/runtime/components/Edit/Form/Toggle/index.vue.d.ts +12 -2
- package/dist/runtime/components/Edit/InfoBox/index.vue +6 -2
- package/dist/runtime/components/Edit/InfoBox/index.vue.d.ts +12 -2
- package/dist/runtime/components/Edit/{Features/Publish/Dialog/ScheduleDate.vue → ScheduleDate/index.vue} +6 -58
- package/dist/runtime/components/Edit/{Features/Publish/Dialog/ScheduleDate.vue.d.ts → ScheduleDate/index.vue.d.ts} +11 -1
- package/dist/runtime/components/Edit/ShortcutIndicator/index.vue +3 -0
- package/dist/runtime/components/Edit/Transition/Height.vue +95 -0
- package/dist/runtime/components/Edit/Transition/Height.vue.d.ts +36 -0
- package/dist/runtime/components/Edit/index.d.ts +3 -1
- package/dist/runtime/components/Edit/index.js +5 -1
- package/dist/runtime/css/output.css +1 -1
- package/dist/runtime/helpers/animationProvider.d.ts +2 -1
- package/dist/runtime/helpers/animationProvider.js +6 -2
- package/dist/runtime/helpers/composables/useStateBasedCache.d.ts +4 -0
- package/dist/runtime/helpers/composables/useStateBasedCache.js +13 -0
- package/dist/runtime/helpers/definitionProvider.d.ts +1 -1
- package/dist/runtime/helpers/dom/index.d.ts +1 -1
- package/dist/runtime/helpers/domProvider.d.ts +10 -16
- package/dist/runtime/helpers/domProvider.js +80 -135
- package/dist/runtime/helpers/index.d.ts +1 -8
- package/dist/runtime/helpers/index.js +1 -84
- package/dist/runtime/helpers/providers/blocks.d.ts +10 -0
- package/dist/runtime/helpers/providers/blocks.js +91 -0
- package/dist/runtime/helpers/providers/directive.d.ts +24 -0
- package/dist/runtime/helpers/{editableProvider.js → providers/directive.js} +90 -29
- package/dist/runtime/helpers/providers/element.d.ts +6 -0
- package/dist/runtime/helpers/providers/element.js +35 -0
- package/dist/runtime/helpers/providers/fields.d.ts +8 -0
- package/dist/runtime/helpers/providers/fields.js +47 -0
- package/dist/runtime/helpers/selectionProvider.d.ts +11 -11
- package/dist/runtime/helpers/selectionProvider.js +38 -45
- package/dist/runtime/helpers/stateProvider.d.ts +1 -0
- package/dist/runtime/helpers/stateProvider.js +21 -15
- package/dist/runtime/helpers/themeProvider.d.ts +2 -1
- package/dist/runtime/helpers/themeProvider.js +24 -14
- package/dist/runtime/helpers/typesProvider.js +10 -26
- package/dist/runtime/helpers/uiProvider.d.ts +3 -2
- package/dist/runtime/helpers/uiProvider.js +11 -15
- package/dist/runtime/icons/calendar.svg +1 -0
- package/dist/runtime/icons/clock.svg +1 -0
- package/dist/runtime/icons/comment_add.svg +1 -5
- package/dist/runtime/icons/delete.svg +1 -8
- package/dist/runtime/icons/duplicate.svg +1 -12
- package/dist/runtime/icons/edit.svg +1 -8
- package/dist/runtime/icons/reusable.svg +1 -5
- package/dist/runtime/plugins/{blokkliEditable.js → blokkliDirectives.js} +14 -20
- package/dist/runtime/types/index.d.ts +55 -36
- package/package.json +1 -1
- package/dist/runtime/components/Edit/Features/CommandPalette/Palette/Group/index.vue +0 -63
- package/dist/runtime/helpers/editableProvider.d.ts +0 -14
- /package/dist/runtime/plugins/{blokkliEditable.d.ts → blokkliDirectives.d.ts} +0 -0
|
@@ -59,7 +59,7 @@ import { ref, useBlokkli, onMounted } from "#imports";
|
|
|
59
59
|
import { DialogModal, InfoBox, FormText, FormItem } from "#blokkli/components";
|
|
60
60
|
import { realBackgroundColor } from "#blokkli/helpers";
|
|
61
61
|
defineEmits(["confirm", "cancel"]);
|
|
62
|
-
const { dom, $t } = useBlokkli();
|
|
62
|
+
const { dom, $t, blocks } = useBlokkli();
|
|
63
63
|
const props = defineProps({
|
|
64
64
|
uuid: { type: String, required: true },
|
|
65
65
|
backgroundClass: { type: String, required: false }
|
|
@@ -70,14 +70,14 @@ const previewEl = ref(null);
|
|
|
70
70
|
const backgroundColor = ref("");
|
|
71
71
|
onMounted(() => {
|
|
72
72
|
if (previewEl.value) {
|
|
73
|
-
const item =
|
|
73
|
+
const item = blocks.getBlock(props.uuid);
|
|
74
74
|
if (!item) {
|
|
75
75
|
return;
|
|
76
76
|
}
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
const element = dom.getDragElement(item);
|
|
78
|
+
if (!element) {
|
|
79
|
+
return;
|
|
79
80
|
}
|
|
80
|
-
const element = item.element();
|
|
81
81
|
const markup = dom.getDropElementMarkup(item);
|
|
82
82
|
width.value = element.getBoundingClientRect().width + 40;
|
|
83
83
|
const clone = document.createElement("div");
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
id="library_detach"
|
|
5
5
|
:title="$t('libraryDetach', 'Detach from library')"
|
|
6
6
|
icon="detach"
|
|
7
|
-
|
|
7
|
+
edit-only
|
|
8
8
|
multiple
|
|
9
9
|
:weight="-70"
|
|
10
10
|
@click="onDetach"
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
v-else-if="!isReusable"
|
|
14
14
|
id="library_make_reusable"
|
|
15
15
|
:title="$t('libraryAdd', 'Add to library...')"
|
|
16
|
-
:disabled="!canMakeReusable
|
|
16
|
+
:disabled="!canMakeReusable"
|
|
17
|
+
edit-only
|
|
17
18
|
icon="reusable"
|
|
18
19
|
:weight="-70"
|
|
19
20
|
@click="showReusableDialog = true"
|
|
@@ -41,8 +42,8 @@
|
|
|
41
42
|
<Teleport to="body">
|
|
42
43
|
<BlokkliTransition name="slide-up">
|
|
43
44
|
<ReusableDialog
|
|
44
|
-
v-if="showReusableDialog &&
|
|
45
|
-
:uuid="
|
|
45
|
+
v-if="showReusableDialog && selection.item.value"
|
|
46
|
+
:uuid="selection.item.value.uuid"
|
|
46
47
|
:background-class="definition?.editor?.previewBackgroundClass"
|
|
47
48
|
@confirm="onMakeReusable"
|
|
48
49
|
@cancel="showReusableDialog = false"
|
|
@@ -87,12 +88,6 @@ const { adapter } = defineBlokkliFeature({
|
|
|
87
88
|
});
|
|
88
89
|
const { selection, state, types, $t, eventBus, definitions } = useBlokkli();
|
|
89
90
|
const showReusableDialog = ref(false);
|
|
90
|
-
const selectedItem = computed(() => {
|
|
91
|
-
if (selection.blocks.value.length !== 1) {
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
return selection.blocks.value[0];
|
|
95
|
-
});
|
|
96
91
|
const onDetach = async () => {
|
|
97
92
|
if (!adapter.detachReusableBlock || !selection.uuids.value.length) {
|
|
98
93
|
return;
|
|
@@ -118,28 +113,37 @@ const onAddLibraryItem = async (uuid) => {
|
|
|
118
113
|
);
|
|
119
114
|
placedAction.value = null;
|
|
120
115
|
};
|
|
121
|
-
const definition = computed(
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
);
|
|
116
|
+
const definition = computed(() => {
|
|
117
|
+
const item = selection.item.value;
|
|
118
|
+
if (!item) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
return definitions.getBlockDefinition(
|
|
122
|
+
item.bundle,
|
|
123
|
+
item.fieldListType,
|
|
124
|
+
item.parentBlockBundle
|
|
125
|
+
);
|
|
126
|
+
});
|
|
127
|
+
const itemBundle = computed(() => {
|
|
128
|
+
const item = selection.item.value;
|
|
129
|
+
if (!item) {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
return types.getBlockBundleDefinition(item.bundle);
|
|
133
|
+
});
|
|
131
134
|
const isReusable = computed(
|
|
132
|
-
() => selection.
|
|
135
|
+
() => selection.bundles.value.every((bundle) => bundle === BUNDLE_FROM_LIBRARY)
|
|
133
136
|
);
|
|
134
137
|
async function onMakeReusable(label) {
|
|
135
138
|
showReusableDialog.value = false;
|
|
136
|
-
|
|
139
|
+
const item = selection.item.value;
|
|
140
|
+
if (!item) {
|
|
137
141
|
return;
|
|
138
142
|
}
|
|
139
143
|
await state.mutateWithLoadingState(
|
|
140
144
|
() => adapter.makeBlockReusable({
|
|
141
145
|
label,
|
|
142
|
-
uuid:
|
|
146
|
+
uuid: item.uuid
|
|
143
147
|
}),
|
|
144
148
|
$t("libraryError", "Failed to add block to library.")
|
|
145
149
|
);
|
|
@@ -88,7 +88,7 @@ defineProps({
|
|
|
88
88
|
isSortli: { type: Boolean, required: false },
|
|
89
89
|
modelValue: { type: String, required: false }
|
|
90
90
|
});
|
|
91
|
-
const { adapter, storage, $t } = useBlokkli();
|
|
91
|
+
const { adapter, storage, $t, element } = useBlokkli();
|
|
92
92
|
const selected = ref([]);
|
|
93
93
|
const listEl = ref(null);
|
|
94
94
|
const page = ref(0);
|
|
@@ -97,10 +97,13 @@ function getDragItems(activeItem) {
|
|
|
97
97
|
if (!selected.value.length || !listEl.value) {
|
|
98
98
|
return null;
|
|
99
99
|
}
|
|
100
|
+
const listElement = listEl.value;
|
|
100
101
|
const activeId = activeItem?.itemType === "media_library" ? activeItem.mediaId : null;
|
|
101
102
|
const items2 = selected.value.map((id) => {
|
|
102
|
-
const el =
|
|
103
|
-
|
|
103
|
+
const el = element.query(
|
|
104
|
+
listElement,
|
|
105
|
+
`[data-sortli-id="media_library_${id}"]`,
|
|
106
|
+
"Find media library drag item."
|
|
104
107
|
);
|
|
105
108
|
if (!(el instanceof HTMLElement)) {
|
|
106
109
|
return null;
|
|
@@ -32,6 +32,7 @@ import { PluginSidebar, PluginDroppableEdit } from "#blokkli/plugins";
|
|
|
32
32
|
import Library from "./Library/index.vue";
|
|
33
33
|
import defineDropAreas from "#blokkli/helpers/composables/defineDropAreas";
|
|
34
34
|
import { falsy } from "#blokkli/helpers";
|
|
35
|
+
import { itemEntityType } from "#blokkli-build/config";
|
|
35
36
|
defineBlokkliFeature({
|
|
36
37
|
id: "media-library",
|
|
37
38
|
icon: "image",
|
|
@@ -39,7 +40,7 @@ defineBlokkliFeature({
|
|
|
39
40
|
description: "Implements a media library to easily drag and drop media like images or videos.",
|
|
40
41
|
requiredAdapterMethods: ["mediaLibraryGetResults", "mediaLibraryAddBlock"]
|
|
41
42
|
});
|
|
42
|
-
const { $t,
|
|
43
|
+
const { $t, adapter, state, runtimeConfig, types, directive } = useBlokkli();
|
|
43
44
|
const selected = ref("");
|
|
44
45
|
const ERROR_MESSAGE = $t(
|
|
45
46
|
"mediaLibraryReplaceFailed",
|
|
@@ -49,11 +50,12 @@ const onDroppableEditSave = async (e) => {
|
|
|
49
50
|
if (!selected.value) {
|
|
50
51
|
return;
|
|
51
52
|
}
|
|
52
|
-
if ("
|
|
53
|
+
if ("itemType" in e.host && adapter.mediaLibraryReplaceMedia) {
|
|
54
|
+
const host = e.host;
|
|
53
55
|
await state.mutateWithLoadingState(
|
|
54
56
|
() => adapter.mediaLibraryReplaceMedia({
|
|
55
57
|
host: {
|
|
56
|
-
uuid:
|
|
58
|
+
uuid: host.block.uuid,
|
|
57
59
|
type: runtimeConfig.itemEntityType,
|
|
58
60
|
fieldName: e.fieldName
|
|
59
61
|
},
|
|
@@ -62,11 +64,12 @@ const onDroppableEditSave = async (e) => {
|
|
|
62
64
|
ERROR_MESSAGE
|
|
63
65
|
);
|
|
64
66
|
} else if ("type" in e.host && adapter.mediaLibraryReplaceEntityMedia) {
|
|
65
|
-
const
|
|
67
|
+
const host = e.host;
|
|
68
|
+
const type = host.type;
|
|
66
69
|
await state.mutateWithLoadingState(
|
|
67
70
|
() => adapter.mediaLibraryReplaceEntityMedia({
|
|
68
71
|
host: {
|
|
69
|
-
uuid:
|
|
72
|
+
uuid: host.uuid,
|
|
70
73
|
type,
|
|
71
74
|
fieldName: e.fieldName
|
|
72
75
|
},
|
|
@@ -87,18 +90,18 @@ defineDropAreas((dragItems) => {
|
|
|
87
90
|
if (item.itemType !== "media_library") {
|
|
88
91
|
return;
|
|
89
92
|
}
|
|
90
|
-
return
|
|
91
|
-
const config = types.getDroppableFieldConfig(field.fieldName, field
|
|
93
|
+
return directive.getDroppableElements().map((field) => {
|
|
94
|
+
const config = types.getDroppableFieldConfig(field.fieldName, field);
|
|
92
95
|
if (config.allowedEntityType !== "media") {
|
|
93
96
|
return;
|
|
94
97
|
}
|
|
95
98
|
if (!config.allowedBundles.includes(item.mediaBundle)) {
|
|
96
99
|
return;
|
|
97
100
|
}
|
|
98
|
-
const isBlock =
|
|
101
|
+
const isBlock = field.type === itemEntityType;
|
|
99
102
|
const draggableHost = {
|
|
100
|
-
uuid: field.
|
|
101
|
-
type:
|
|
103
|
+
uuid: field.uuid,
|
|
104
|
+
type: field.type,
|
|
102
105
|
fieldName: field.fieldName
|
|
103
106
|
};
|
|
104
107
|
const label = $t("mediaLibraryReplaceMedia", "Replace @field").replace(
|
|
@@ -107,7 +110,7 @@ defineDropAreas((dragItems) => {
|
|
|
107
110
|
);
|
|
108
111
|
if (adapter.mediaLibraryReplaceMedia && isBlock) {
|
|
109
112
|
return {
|
|
110
|
-
id: `replace-media:${field.
|
|
113
|
+
id: `replace-media:${field.uuid}:${field.fieldName}`,
|
|
111
114
|
label,
|
|
112
115
|
element: field.element,
|
|
113
116
|
icon: "swap-horizontal",
|
|
@@ -123,7 +126,7 @@ defineDropAreas((dragItems) => {
|
|
|
123
126
|
};
|
|
124
127
|
} else if (adapter.mediaLibraryReplaceEntityMedia && !isBlock) {
|
|
125
128
|
return {
|
|
126
|
-
id: `replace-entity-media:${field.
|
|
129
|
+
id: `replace-entity-media:${field.uuid}:${field.fieldName}`,
|
|
127
130
|
label,
|
|
128
131
|
element: field.element,
|
|
129
132
|
icon: "swap-horizontal",
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
} from "twgl.js";
|
|
18
18
|
import { RectangleBufferCollector } from "#blokkli/helpers/webgl";
|
|
19
19
|
import useDebugLogger from "#blokkli/helpers/composables/useDebugLogger";
|
|
20
|
-
const { eventBus, dom, theme, animation, ui } = useBlokkli();
|
|
20
|
+
const { eventBus, dom, theme, animation, ui, blocks } = useBlokkli();
|
|
21
21
|
const logger = useDebugLogger();
|
|
22
22
|
const props = defineProps({
|
|
23
23
|
startX: { type: Number, required: true },
|
|
@@ -39,7 +39,7 @@ class MultiSelectRectangleBufferCollector extends RectangleBufferCollector {
|
|
|
39
39
|
if (this.added.has(uuid)) {
|
|
40
40
|
continue;
|
|
41
41
|
}
|
|
42
|
-
const block =
|
|
42
|
+
const block = blocks.getBlock(uuid);
|
|
43
43
|
if (!block) {
|
|
44
44
|
continue;
|
|
45
45
|
}
|
|
@@ -56,6 +56,7 @@ import {
|
|
|
56
56
|
BK_VISIBLE_LANGUAGES
|
|
57
57
|
} from "#blokkli/helpers/symbols";
|
|
58
58
|
import { BUNDLE_FROM_LIBRARY } from "#blokkli/constants";
|
|
59
|
+
import { itemEntityType } from "#blokkli-build/config";
|
|
59
60
|
if (import.meta.hot) {
|
|
60
61
|
import.meta.hot.accept("#blokkli/runtime-helpers", () => {
|
|
61
62
|
});
|
|
@@ -94,11 +95,11 @@ const {
|
|
|
94
95
|
eventBus,
|
|
95
96
|
state,
|
|
96
97
|
selection,
|
|
97
|
-
runtimeConfig,
|
|
98
98
|
dom,
|
|
99
99
|
theme,
|
|
100
100
|
context,
|
|
101
|
-
definitions
|
|
101
|
+
definitions,
|
|
102
|
+
blocks
|
|
102
103
|
} = useBlokkli();
|
|
103
104
|
const props = defineProps({
|
|
104
105
|
uuids: { type: [Array, String], required: true },
|
|
@@ -136,7 +137,7 @@ function stopChangingOptions() {
|
|
|
136
137
|
if (Array.isArray(props.uuids)) {
|
|
137
138
|
props.uuids.forEach((uuid) => {
|
|
138
139
|
dom.refreshBlockRect(uuid);
|
|
139
|
-
const block =
|
|
140
|
+
const block = blocks.getBlock(uuid);
|
|
140
141
|
if (block) {
|
|
141
142
|
const el = dom.getDragElement(block);
|
|
142
143
|
if (el) {
|
|
@@ -248,11 +249,11 @@ const visibleOptions = computed(() => {
|
|
|
248
249
|
}
|
|
249
250
|
const uuid = props.uuids[0];
|
|
250
251
|
const item = state.getFieldListItem(uuid);
|
|
251
|
-
const block = selection.
|
|
252
|
+
const block = selection.items.value.find((v) => v.uuid === uuid);
|
|
252
253
|
if (!item) {
|
|
253
254
|
return [];
|
|
254
255
|
}
|
|
255
|
-
const parentType = block?.
|
|
256
|
+
const parentType = block?.host.type === itemEntityType ? block.parentBlockBundle : void 0;
|
|
256
257
|
const ctxProps = item?.bundle === BUNDLE_FROM_LIBRARY ? item?.props?.libraryItem?.block?.props : item?.props;
|
|
257
258
|
const visibleKeys = (
|
|
258
259
|
// We have to cast to any here because the types are guaranteed to be correct.
|
|
@@ -261,7 +262,7 @@ const visibleOptions = computed(() => {
|
|
|
261
262
|
parentType,
|
|
262
263
|
props: ctxProps,
|
|
263
264
|
entity: context.value,
|
|
264
|
-
fieldListType: block?.
|
|
265
|
+
fieldListType: block?.fieldListType ?? "default"
|
|
265
266
|
})
|
|
266
267
|
);
|
|
267
268
|
return availableOptions.value.filter(
|
|
@@ -24,7 +24,7 @@ defineBlokkliFeature({
|
|
|
24
24
|
});
|
|
25
25
|
const { selection, state, ui, definitions, context } = useBlokkli();
|
|
26
26
|
const uuids = computed(() => {
|
|
27
|
-
const uuids2 = selection.
|
|
27
|
+
const uuids2 = selection.items.value.map((v) => v.uuid);
|
|
28
28
|
if (uuids2.length) {
|
|
29
29
|
return uuids2;
|
|
30
30
|
} else if (selection.hasHostSelected.value) {
|
|
@@ -47,14 +47,14 @@ const definition = computed(() => {
|
|
|
47
47
|
context.value.entityBundle
|
|
48
48
|
);
|
|
49
49
|
}
|
|
50
|
-
const bundles = selection.
|
|
50
|
+
const bundles = selection.items.value.map((v) => v.library?.reusableBundle || v.bundle).filter(onlyUnique);
|
|
51
51
|
if (bundles.length !== 1) {
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
54
|
const bundle = bundles[0];
|
|
55
55
|
if (bundle === "blokkli_fragment") {
|
|
56
|
-
const fragments = selection.
|
|
57
|
-
(v) => v.
|
|
56
|
+
const fragments = selection.items.value.filter(
|
|
57
|
+
(v) => v.bundle === "blokkli_fragment"
|
|
58
58
|
);
|
|
59
59
|
const fragmentNames = fragments.map((v) => {
|
|
60
60
|
const props = state.getFieldListItem(v.uuid)?.props;
|
|
@@ -67,10 +67,10 @@ const definition = computed(() => {
|
|
|
67
67
|
}
|
|
68
68
|
return definitions.getFragmentDefinition(fragmentNames[0]);
|
|
69
69
|
}
|
|
70
|
-
return selection.
|
|
70
|
+
return selection.items.value.map((block) => {
|
|
71
71
|
return definitions.getBlockDefinition(
|
|
72
72
|
bundle,
|
|
73
|
-
block.
|
|
73
|
+
block.fieldListType,
|
|
74
74
|
block.parentBlockBundle
|
|
75
75
|
);
|
|
76
76
|
}).filter(falsy).at(0);
|
|
@@ -37,23 +37,24 @@
|
|
|
37
37
|
</label>
|
|
38
38
|
<div class="bk-publish-schedule-date-wrapper">
|
|
39
39
|
<div v-if="isAlreadyScheduled" class="bk-publish-scheduled-display">
|
|
40
|
-
{{
|
|
41
|
-
ui.formatDate(scheduleDate, {
|
|
42
|
-
weekday: "long",
|
|
43
|
-
year: "numeric",
|
|
44
|
-
month: "2-digit",
|
|
45
|
-
day: "2-digit",
|
|
46
|
-
hour: "2-digit",
|
|
47
|
-
minute: "2-digit"
|
|
48
|
-
})
|
|
49
|
-
}}
|
|
40
|
+
{{ formatScheduleDate(scheduleDate) }}
|
|
50
41
|
</div>
|
|
51
42
|
<ScheduleDate
|
|
52
43
|
v-else
|
|
53
44
|
v-model="scheduleDate"
|
|
54
45
|
:disabled="isLoading"
|
|
55
46
|
:error="scheduleDateError"
|
|
56
|
-
|
|
47
|
+
>
|
|
48
|
+
<div
|
|
49
|
+
class="bk-schedule-date-info"
|
|
50
|
+
v-text="
|
|
51
|
+
$t(
|
|
52
|
+
'publishScheduledInfo',
|
|
53
|
+
'You can still make changes until the scheduled publication date.'
|
|
54
|
+
)
|
|
55
|
+
"
|
|
56
|
+
/>
|
|
57
|
+
</ScheduleDate>
|
|
57
58
|
<button
|
|
58
59
|
v-if="isAlreadyScheduled"
|
|
59
60
|
type="button"
|
|
@@ -90,6 +91,16 @@
|
|
|
90
91
|
/>
|
|
91
92
|
</FormItem>
|
|
92
93
|
|
|
94
|
+
<FormItem v-if="publishMode !== 'save' && scheduledBlocks.length">
|
|
95
|
+
<InfoBox>
|
|
96
|
+
<p
|
|
97
|
+
v-for="(text, index) in scheduledBlocks"
|
|
98
|
+
:key="'infobox' + index"
|
|
99
|
+
v-html="text"
|
|
100
|
+
/>
|
|
101
|
+
</InfoBox>
|
|
102
|
+
</FormItem>
|
|
103
|
+
|
|
93
104
|
<FormItem v-if="successItems.length && showTable">
|
|
94
105
|
<h2 class="bk-heading-2">
|
|
95
106
|
{{ $t("publishSuccessfullyPublished", "Successfully published") }}
|
|
@@ -171,14 +182,29 @@ import {
|
|
|
171
182
|
onMounted,
|
|
172
183
|
onUnmounted
|
|
173
184
|
} from "#imports";
|
|
174
|
-
import {
|
|
185
|
+
import {
|
|
186
|
+
DialogModal,
|
|
187
|
+
FormTextarea,
|
|
188
|
+
FormItem,
|
|
189
|
+
ScheduleDate,
|
|
190
|
+
InfoBox
|
|
191
|
+
} from "#blokkli/components";
|
|
175
192
|
import { emitMessage } from "#blokkli/helpers/eventBus";
|
|
176
193
|
import Item from "./Item.vue";
|
|
177
194
|
import PublishOption, {} from "./PublishOption.vue";
|
|
178
195
|
import Summary from "./Summary.vue";
|
|
179
|
-
import ScheduleDate from "./ScheduleDate.vue";
|
|
180
196
|
const showTable = false;
|
|
181
197
|
const { adapter, $t, state, context, ui } = useBlokkli();
|
|
198
|
+
const formatScheduleDate = (date) => {
|
|
199
|
+
return ui.formatDate(date, {
|
|
200
|
+
weekday: "long",
|
|
201
|
+
year: "numeric",
|
|
202
|
+
month: "long",
|
|
203
|
+
day: "numeric",
|
|
204
|
+
hour: "2-digit",
|
|
205
|
+
minute: "2-digit"
|
|
206
|
+
});
|
|
207
|
+
};
|
|
182
208
|
const isMutating = ref(false);
|
|
183
209
|
const mutationStatusItems = ref({});
|
|
184
210
|
const publishedIds = ref([]);
|
|
@@ -205,6 +231,33 @@ const {
|
|
|
205
231
|
} = await useAsyncData(() => {
|
|
206
232
|
return adapter.getPublishOptions();
|
|
207
233
|
});
|
|
234
|
+
const scheduledBlocks = computed(() => {
|
|
235
|
+
const referenceTimestamp = publishMode.value === "scheduled" && scheduleDate.value ? new Date(scheduleDate.value).getTime() : currentTimestamp.value;
|
|
236
|
+
const grouped = state.getAllUuids().reduce((acc, uuid) => {
|
|
237
|
+
const item = state.getFieldListItem(uuid);
|
|
238
|
+
if (!item?.editContext?.publishOn) {
|
|
239
|
+
return acc;
|
|
240
|
+
}
|
|
241
|
+
const publishDate = new Date(item.editContext.publishOn).getTime();
|
|
242
|
+
if (publishDate <= referenceTimestamp) {
|
|
243
|
+
return acc;
|
|
244
|
+
}
|
|
245
|
+
const dateKey = item.editContext.publishOn;
|
|
246
|
+
acc[dateKey] = (acc[dateKey] || 0) + 1;
|
|
247
|
+
return acc;
|
|
248
|
+
}, {});
|
|
249
|
+
return Object.entries(grouped).map(([date, count]) => {
|
|
250
|
+
const formattedDate = formatScheduleDate(date);
|
|
251
|
+
const message = count === 1 ? $t(
|
|
252
|
+
"publishScheduledBlockSingular",
|
|
253
|
+
"1 block is scheduled to be published on @date"
|
|
254
|
+
) : $t(
|
|
255
|
+
"publishScheduledBlockPlural",
|
|
256
|
+
"@count blocks are scheduled to be published on @date"
|
|
257
|
+
);
|
|
258
|
+
return message.replace("@count", count.toString()).replace("@date", `<strong>${formattedDate}</strong>`);
|
|
259
|
+
});
|
|
260
|
+
});
|
|
208
261
|
const canSchedule = computed(() => !!publishOptions.value?.canSchedule);
|
|
209
262
|
const publishOn = computed(
|
|
210
263
|
() => publishOptions.value?.publishOn ?? null
|
|
@@ -403,7 +456,7 @@ const resultStateLabel = computed(() => {
|
|
|
403
456
|
);
|
|
404
457
|
}
|
|
405
458
|
if (publishMode.value === "scheduled" && scheduleDate.value) {
|
|
406
|
-
const formattedDate =
|
|
459
|
+
const formattedDate = formatScheduleDate(scheduleDate.value);
|
|
407
460
|
if (isCurrentlyPublished.value) {
|
|
408
461
|
return $t(
|
|
409
462
|
"publishResultScheduledChanges",
|
|
@@ -500,7 +553,7 @@ async function onSubmit() {
|
|
|
500
553
|
return;
|
|
501
554
|
}
|
|
502
555
|
if (publishMode.value === "scheduled") {
|
|
503
|
-
const formattedDate =
|
|
556
|
+
const formattedDate = formatScheduleDate(scheduleDate.value);
|
|
504
557
|
const message = $t(
|
|
505
558
|
"publishScheduleSuccess",
|
|
506
559
|
"Publication scheduled for @date"
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
@mouseenter="index = i"
|
|
11
11
|
>
|
|
12
12
|
<div class="bk-search-item-icon">
|
|
13
|
-
<ItemIcon :bundle="item.item.
|
|
13
|
+
<ItemIcon :bundle="item.item.bundle" />
|
|
14
14
|
</div>
|
|
15
15
|
<div class="bk-search-item-content">
|
|
16
16
|
<Highlight
|
|
@@ -49,7 +49,7 @@ const props = defineProps({
|
|
|
49
49
|
search: { type: String, required: true },
|
|
50
50
|
tab: { type: String, required: true }
|
|
51
51
|
});
|
|
52
|
-
const { eventBus, state, types, dom } = useBlokkli();
|
|
52
|
+
const { eventBus, state, types, dom, blocks, element } = useBlokkli();
|
|
53
53
|
const buildForKey = ref("");
|
|
54
54
|
const items = ref([]);
|
|
55
55
|
const index = ref(0);
|
|
@@ -92,28 +92,28 @@ const scrollItemIntoView = () => {
|
|
|
92
92
|
}
|
|
93
93
|
};
|
|
94
94
|
const buildSearchText = (el) => {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
text += " " + img.title;
|
|
95
|
+
if (!el) {
|
|
96
|
+
return "";
|
|
97
|
+
}
|
|
98
|
+
const altTexts = element.queryAll(el, "img", "buildSearchText", (el2) => {
|
|
99
|
+
if (el2 instanceof HTMLImageElement) {
|
|
100
|
+
return [el2.alt, el2.title].filter(Boolean).join("");
|
|
102
101
|
}
|
|
103
|
-
});
|
|
104
|
-
return
|
|
102
|
+
}).join(" ");
|
|
103
|
+
return (el.textContent ?? "") + altTexts;
|
|
105
104
|
};
|
|
106
105
|
const buildIndex = () => {
|
|
107
106
|
if (buildForKey.value === state.refreshKey.value) {
|
|
108
107
|
return;
|
|
109
108
|
}
|
|
110
|
-
const newItems =
|
|
111
|
-
const title = types.getBlockBundleDefinition(item.
|
|
109
|
+
const newItems = blocks.getAllBlocks().map((item) => {
|
|
110
|
+
const title = types.getBlockBundleDefinition(item.bundle)?.label || item.bundle;
|
|
111
|
+
const element2 = dom.getDragElement(item);
|
|
112
112
|
return {
|
|
113
113
|
item,
|
|
114
|
-
title
|
|
114
|
+
title,
|
|
115
115
|
context: title,
|
|
116
|
-
text: buildSearchText(
|
|
116
|
+
text: buildSearchText(element2)
|
|
117
117
|
};
|
|
118
118
|
}).filter(falsy);
|
|
119
119
|
items.value = newItems;
|
|
@@ -46,7 +46,7 @@ defineBlokkliFeature({
|
|
|
46
46
|
label: "Search",
|
|
47
47
|
description: "Provides an overlay with shortcut to search for blocks on the current page or existing content to add as blocks."
|
|
48
48
|
});
|
|
49
|
-
const { $t, selection } = useBlokkli();
|
|
49
|
+
const { $t, selection, ui } = useBlokkli();
|
|
50
50
|
const isRendered = ref(false);
|
|
51
51
|
const isVisible = ref(false);
|
|
52
52
|
const overlay = ref(null);
|
|
@@ -60,6 +60,9 @@ function onClick() {
|
|
|
60
60
|
});
|
|
61
61
|
}
|
|
62
62
|
onBlokkliEvent("keyPressed", (e) => {
|
|
63
|
+
if (ui.hasDialogOpen.value) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
63
66
|
if (e.code === "Escape") {
|
|
64
67
|
isVisible.value = false;
|
|
65
68
|
}
|
|
@@ -6,12 +6,12 @@ type __VLS_Props = {
|
|
|
6
6
|
label: string;
|
|
7
7
|
};
|
|
8
8
|
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
9
|
-
select: (id: string) => void;
|
|
10
9
|
action: (id: string) => void;
|
|
10
|
+
select: (id: string) => void;
|
|
11
11
|
close: () => void;
|
|
12
12
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
13
|
-
onClose?: (() => any) | undefined;
|
|
14
|
-
onSelect?: ((id: string) => any) | undefined;
|
|
15
13
|
onAction?: ((id: string) => any) | undefined;
|
|
14
|
+
onSelect?: ((id: string) => any) | undefined;
|
|
15
|
+
onClose?: (() => any) | undefined;
|
|
16
16
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
17
17
|
export default _default;
|
|
@@ -30,7 +30,19 @@ import {
|
|
|
30
30
|
determineCanAddChildren
|
|
31
31
|
} from "#blokkli/helpers/dropTargets";
|
|
32
32
|
import { isInternalBundle } from "#blokkli/helpers/bundles";
|
|
33
|
-
|
|
33
|
+
import { itemEntityType } from "#blokkli-build/config";
|
|
34
|
+
const {
|
|
35
|
+
animation,
|
|
36
|
+
theme,
|
|
37
|
+
dom,
|
|
38
|
+
selection,
|
|
39
|
+
state,
|
|
40
|
+
types,
|
|
41
|
+
ui,
|
|
42
|
+
$t,
|
|
43
|
+
blocks,
|
|
44
|
+
fields
|
|
45
|
+
} = useBlokkli();
|
|
34
46
|
const emptyFieldTooltips = ref([]);
|
|
35
47
|
const currentUuid = ref("");
|
|
36
48
|
const currentBundleLabel = ref("");
|
|
@@ -146,9 +158,9 @@ const blockStateCache = /* @__PURE__ */ new Map();
|
|
|
146
158
|
function getOrientationForUuid(uuid) {
|
|
147
159
|
let cached = orientationCache.get(uuid);
|
|
148
160
|
if (!cached) {
|
|
149
|
-
const
|
|
150
|
-
if (
|
|
151
|
-
const field =
|
|
161
|
+
const item = blocks.getBlock(uuid);
|
|
162
|
+
if (item) {
|
|
163
|
+
const field = fields.find(item.host.uuid, item.host.fieldName);
|
|
152
164
|
if (field) {
|
|
153
165
|
cached = getChildrenOrientation(field.element);
|
|
154
166
|
orientationCache.set(uuid, cached);
|
|
@@ -162,7 +174,7 @@ function getBlockState(uuid) {
|
|
|
162
174
|
if (!cached) {
|
|
163
175
|
let canShowBeforeAfter = false;
|
|
164
176
|
let singleAllowedBundleLabel = null;
|
|
165
|
-
const block =
|
|
177
|
+
const block = blocks.getBlock(uuid);
|
|
166
178
|
if (!block) {
|
|
167
179
|
return {
|
|
168
180
|
canShowBeforeAfter: false,
|
|
@@ -173,7 +185,7 @@ function getBlockState(uuid) {
|
|
|
173
185
|
};
|
|
174
186
|
}
|
|
175
187
|
if (block) {
|
|
176
|
-
const field =
|
|
188
|
+
const field = fields.find(block.host.uuid, block.host.fieldName);
|
|
177
189
|
if (!field) {
|
|
178
190
|
return {
|
|
179
191
|
canShowBeforeAfter: false,
|
|
@@ -208,13 +220,13 @@ function getBlockState(uuid) {
|
|
|
208
220
|
}
|
|
209
221
|
}
|
|
210
222
|
}
|
|
211
|
-
const bundleLabel = block ? types.getBlockBundleDefinition(block.
|
|
223
|
+
const bundleLabel = block ? types.getBlockBundleDefinition(block.bundle)?.label || block.bundle : "";
|
|
212
224
|
const emptyFieldKeys = [];
|
|
213
225
|
const emptyFieldTooltips2 = [];
|
|
214
226
|
if (block) {
|
|
215
227
|
const fieldConfigs = types.fieldConfig.forEntityTypeAndBundle(
|
|
216
|
-
|
|
217
|
-
block.
|
|
228
|
+
itemEntityType,
|
|
229
|
+
block.bundle
|
|
218
230
|
);
|
|
219
231
|
for (const fieldConfig of fieldConfigs) {
|
|
220
232
|
const key = getFieldKey(uuid, fieldConfig.name);
|
|
@@ -222,7 +234,7 @@ function getBlockState(uuid) {
|
|
|
222
234
|
if (count === 0) {
|
|
223
235
|
emptyFieldKeys.push(key);
|
|
224
236
|
const fieldLabel = fieldConfig.label || fieldConfig.name;
|
|
225
|
-
const fieldElement =
|
|
237
|
+
const fieldElement = fields.find(uuid, fieldConfig.name);
|
|
226
238
|
if (fieldElement) {
|
|
227
239
|
const allowedBundles = fieldElement.allowedBundles.filter(
|
|
228
240
|
(bundle) => !isInternalBundle(bundle)
|
|
@@ -301,7 +313,18 @@ function getCircleAtPoint(x, y) {
|
|
|
301
313
|
if (gl && programInfo && bufferInfo) {
|
|
302
314
|
defineRenderer("add-buttons", {
|
|
303
315
|
zIndex: 1e3,
|
|
304
|
-
enabled: () =>
|
|
316
|
+
enabled: () => {
|
|
317
|
+
if (selection.uuids.value.length !== 1) {
|
|
318
|
+
return false;
|
|
319
|
+
}
|
|
320
|
+
if (ui.openTooltip.value && ui.openTooltip.value !== "add-buttons") {
|
|
321
|
+
return false;
|
|
322
|
+
}
|
|
323
|
+
if (ui.hasTransformOverlayOpen.value) {
|
|
324
|
+
return false;
|
|
325
|
+
}
|
|
326
|
+
return true;
|
|
327
|
+
},
|
|
305
328
|
cursor: () => hoveredCircle.value >= 0 ? "pointer" : null,
|
|
306
329
|
onClick: ({ mouseArtboard }) => {
|
|
307
330
|
if (selection.uuids.value.length !== 1) {
|