@blokkli/editor 2.0.0-alpha.16 → 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.
Files changed (194) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +640 -137
  3. package/dist/modules/drupal/graphql/base/fragment.blokkliProps.graphql +1 -1
  4. package/dist/modules/drupal/graphql/base/fragment.paragraphsFieldItem.graphql +3 -1
  5. package/dist/modules/drupal/graphql/base/query.pbConfig.graphql +1 -10
  6. package/dist/modules/drupal/graphql/features/comments.graphql +11 -8
  7. package/dist/modules/drupal/graphql/mutations/set_paragraph_schedule.graphql +15 -0
  8. package/dist/modules/drupal/index.mjs +33 -0
  9. package/dist/modules/drupal/runtime/adapter/index.js +12 -4
  10. package/dist/runtime/adapter/index.d.ts +21 -0
  11. package/dist/runtime/blokkliPlugins/ContextMenu/Menu/index.vue +3 -0
  12. package/dist/runtime/blokkliPlugins/ItemAction/index.vue +23 -15
  13. package/dist/runtime/blokkliPlugins/ItemAction/index.vue.d.ts +20 -44
  14. package/dist/runtime/blokkliPlugins/TourItem/index.vue +10 -5
  15. package/dist/runtime/components/Blocks/FromLibrary/index.vue +4 -2
  16. package/dist/runtime/components/BlokkliEditable.vue +32 -14
  17. package/dist/runtime/components/BlokkliField.vue +3 -0
  18. package/dist/runtime/components/BlokkliField.vue.d.ts +3 -3
  19. package/dist/runtime/components/BlokkliItem.vue +1 -1
  20. package/dist/runtime/components/BlokkliItem.vue.d.ts +4 -2
  21. package/dist/runtime/components/BlokkliProvider.vue +41 -28
  22. package/dist/runtime/components/BlokkliProvider.vue.d.ts +2 -1
  23. package/dist/runtime/components/Edit/Actions/index.vue +36 -20
  24. package/dist/runtime/components/Edit/AnimationCanvas/index.vue +436 -25
  25. package/dist/runtime/components/Edit/ArtboardTooltip/index.vue +83 -0
  26. package/dist/runtime/components/Edit/ArtboardTooltip/index.vue.d.ts +32 -0
  27. package/dist/runtime/components/Edit/Banner/index.vue +51 -0
  28. package/dist/runtime/components/Edit/Banner/index.vue.d.ts +18 -0
  29. package/dist/runtime/components/Edit/Dialog/index.vue +6 -4
  30. package/dist/runtime/components/Edit/DraggableList.vue +15 -7
  31. package/dist/runtime/components/Edit/DraggableList.vue.d.ts +5 -5
  32. package/dist/runtime/components/Edit/EditIndicator.vue +118 -44
  33. package/dist/runtime/components/Edit/EditIndicator.vue.d.ts +3 -0
  34. package/dist/runtime/components/Edit/EditProvider.vue +101 -31
  35. package/dist/runtime/components/Edit/EditProvider.vue.d.ts +3 -0
  36. package/dist/runtime/components/Edit/Features/AddList/index.vue +9 -11
  37. package/dist/runtime/components/Edit/Features/Analyze/Overlay/index.vue +28 -26
  38. package/dist/runtime/components/Edit/Features/Analyze/Renderer.vue +1 -1
  39. package/dist/runtime/components/Edit/Features/Analyze/Results/ResultsItemNodesTarget.vue +15 -11
  40. package/dist/runtime/components/Edit/Features/Anchors/Renderer.vue +19 -102
  41. package/dist/runtime/components/Edit/Features/Artboard/Renderer.vue +3 -0
  42. package/dist/runtime/components/Edit/Features/BlockAddList/index.vue +29 -53
  43. package/dist/runtime/components/Edit/Features/BlockScheduler/Dialog/ScheduleSection.vue +154 -0
  44. package/dist/runtime/components/Edit/Features/BlockScheduler/Dialog/ScheduleSection.vue.d.ts +27 -0
  45. package/dist/runtime/components/Edit/Features/BlockScheduler/Dialog/index.vue +222 -0
  46. package/dist/runtime/components/Edit/Features/{Selection/AddButtons/AddButtonsField.vue.d.ts → BlockScheduler/Dialog/index.vue.d.ts} +6 -9
  47. package/dist/runtime/components/Edit/Features/BlockScheduler/index.vue +96 -0
  48. package/dist/runtime/components/Edit/Features/Clipboard/index.vue +15 -16
  49. package/dist/runtime/components/Edit/Features/CommandPalette/Palette/Item/index.vue +51 -0
  50. package/dist/runtime/components/Edit/Features/CommandPalette/Palette/{Group → Item}/index.vue.d.ts +9 -13
  51. package/dist/runtime/components/Edit/Features/CommandPalette/Palette/index.vue +46 -66
  52. package/dist/runtime/components/Edit/Features/CommandPalette/index.vue +2 -0
  53. package/dist/runtime/components/Edit/Features/Comments/AddForm/index.vue +35 -20
  54. package/dist/runtime/components/Edit/Features/Comments/AddForm/index.vue.d.ts +5 -3
  55. package/dist/runtime/components/Edit/Features/Comments/CommentInput/index.vue +29 -0
  56. package/dist/runtime/components/Edit/Features/{Publish/Dialog/ScheduleDate.vue.d.ts → Comments/CommentInput/index.vue.d.ts} +2 -2
  57. package/dist/runtime/components/Edit/Features/Comments/Overlay/Item/index.vue +22 -16
  58. package/dist/runtime/components/Edit/Features/Comments/Overlay/Item/index.vue.d.ts +1 -0
  59. package/dist/runtime/components/Edit/Features/Comments/Overlay/index.vue +15 -6
  60. package/dist/runtime/components/Edit/Features/Comments/index.vue +21 -9
  61. package/dist/runtime/components/Edit/Features/Conversions/index.vue +4 -7
  62. package/dist/runtime/components/Edit/Features/Debug/Rects/index.vue +26 -35
  63. package/dist/runtime/components/Edit/Features/Debug/Renderer.vue +240 -0
  64. package/dist/runtime/components/Edit/Features/Debug/Renderer.vue.d.ts +6 -0
  65. package/dist/runtime/components/Edit/Features/Debug/index.vue +7 -165
  66. package/dist/runtime/components/Edit/Features/Delete/index.vue +1 -1
  67. package/dist/runtime/components/Edit/Features/DraggingOverlay/DragItems/index.vue +14 -6
  68. package/dist/runtime/components/Edit/Features/DraggingOverlay/DropTargets/index.vue +55 -48
  69. package/dist/runtime/components/Edit/Features/DraggingOverlay/index.vue +30 -18
  70. package/dist/runtime/components/Edit/Features/Duplicate/index.vue +6 -8
  71. package/dist/runtime/components/Edit/Features/Edit/index.vue +16 -22
  72. package/dist/runtime/components/Edit/Features/EditForm/index.vue +7 -6
  73. package/dist/runtime/components/Edit/Features/EditableField/Overlay/Frame/index.vue +69 -4
  74. package/dist/runtime/components/Edit/Features/EditableField/Overlay/Frame/index.vue.d.ts +2 -2
  75. package/dist/runtime/components/Edit/Features/EditableField/Overlay/Plaintext/index.vue +13 -9
  76. package/dist/runtime/components/Edit/Features/EditableField/Overlay/index.vue +45 -87
  77. package/dist/runtime/components/Edit/Features/EditableField/Overlay/index.vue.d.ts +2 -2
  78. package/dist/runtime/components/Edit/Features/EditableField/index.vue +41 -43
  79. package/dist/runtime/components/Edit/Features/Fragments/Dialog/index.vue +11 -9
  80. package/dist/runtime/components/Edit/Features/Fragments/index.vue +3 -3
  81. package/dist/runtime/components/Edit/Features/History/index.vue +5 -2
  82. package/dist/runtime/components/Edit/Features/Hover/Overlay/fragment.glsl +139 -0
  83. package/dist/runtime/components/Edit/Features/Hover/Overlay/index.vue +261 -0
  84. package/dist/runtime/components/Edit/Features/Hover/Overlay/index.vue.d.ts +6 -0
  85. package/dist/runtime/components/Edit/Features/Hover/Overlay/vertex.glsl +117 -0
  86. package/dist/runtime/components/Edit/Features/Hover/index.vue +25 -0
  87. package/dist/runtime/components/Edit/Features/Hover/index.vue.d.ts +2 -0
  88. package/dist/runtime/components/Edit/Features/Library/EditReusable/index.vue +5 -7
  89. package/dist/runtime/components/Edit/Features/Library/LibraryDialog/index.vue +19 -27
  90. package/dist/runtime/components/Edit/Features/Library/ReusableDialog/index.vue +32 -28
  91. package/dist/runtime/components/Edit/Features/Library/index.vue +28 -23
  92. package/dist/runtime/components/Edit/Features/MediaLibrary/Library/index.vue +6 -3
  93. package/dist/runtime/components/Edit/Features/MediaLibrary/index.vue +15 -12
  94. package/dist/runtime/components/Edit/Features/MultiSelect/Overlay/index.vue +36 -29
  95. package/dist/runtime/components/Edit/Features/MultiSelect/index.vue +2 -4
  96. package/dist/runtime/components/Edit/Features/Options/Form/Item.vue +6 -1
  97. package/dist/runtime/components/Edit/Features/Options/Form/index.vue +8 -6
  98. package/dist/runtime/components/Edit/Features/Options/index.vue +6 -6
  99. package/dist/runtime/components/Edit/Features/Ownership/Renderer.vue +35 -0
  100. package/dist/runtime/components/Edit/Features/Ownership/Renderer.vue.d.ts +6 -0
  101. package/dist/runtime/components/Edit/Features/Ownership/index.vue +7 -25
  102. package/dist/runtime/components/Edit/Features/ProxyView/index.vue +5 -1
  103. package/dist/runtime/components/Edit/Features/Publish/Dialog/index.vue +68 -15
  104. package/dist/runtime/components/Edit/Features/Search/Overlay/Results/Page/index.vue +15 -15
  105. package/dist/runtime/components/Edit/Features/Search/index.vue +4 -1
  106. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Overlay/index.vue +39 -74
  107. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Overlay/index.vue.d.ts +7 -5
  108. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Renderer/fragment.glsl +106 -0
  109. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Renderer/index.vue +440 -0
  110. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Renderer/index.vue.d.ts +32 -0
  111. package/dist/runtime/components/Edit/Features/Selection/AddButtons/Renderer/vertex.glsl +102 -0
  112. package/dist/runtime/components/Edit/Features/Selection/AddButtons/index.vue +53 -125
  113. package/dist/runtime/components/Edit/Features/Selection/AddButtons/index.vue.d.ts +2 -2
  114. package/dist/runtime/components/Edit/Features/Selection/Overlay/index.vue +88 -29
  115. package/dist/runtime/components/Edit/Features/Selection/Overlay/index.vue.d.ts +5 -3
  116. package/dist/runtime/components/Edit/Features/Selection/Overlay/vertex.glsl +11 -2
  117. package/dist/runtime/components/Edit/Features/Selection/OverlayFallback/index.vue +2 -2
  118. package/dist/runtime/components/Edit/Features/Selection/index.vue +66 -39
  119. package/dist/runtime/components/Edit/Features/Structure/List/Field/index.vue +2 -2
  120. package/dist/runtime/components/Edit/Features/Structure/List/Item/index.vue +13 -6
  121. package/dist/runtime/components/Edit/Features/Tour/Overlay/index.vue +3 -0
  122. package/dist/runtime/components/Edit/Features/Transform/index.vue +2 -27
  123. package/dist/runtime/components/Edit/Features/Translations/Banner/index.vue +17 -11
  124. package/dist/runtime/components/Edit/Features/Translations/index.vue +20 -23
  125. package/dist/runtime/components/Edit/Features/Validations/SidebarItem/index.vue +5 -5
  126. package/dist/runtime/components/Edit/Features/index.vue +17 -7
  127. package/dist/runtime/components/Edit/Form/Text/index.vue +2 -1
  128. package/dist/runtime/components/Edit/Form/Text/index.vue.d.ts +1 -0
  129. package/dist/runtime/components/Edit/Form/Toggle/index.vue +4 -3
  130. package/dist/runtime/components/Edit/Form/Toggle/index.vue.d.ts +12 -2
  131. package/dist/runtime/components/Edit/Indicators/index.vue +1 -1
  132. package/dist/runtime/components/Edit/InfoBox/index.vue +6 -2
  133. package/dist/runtime/components/Edit/InfoBox/index.vue.d.ts +12 -2
  134. package/dist/runtime/components/Edit/Konami/Game/index.vue +5 -5
  135. package/dist/runtime/components/Edit/{Features/Publish/Dialog/ScheduleDate.vue → ScheduleDate/index.vue} +6 -58
  136. package/dist/runtime/components/Edit/ScheduleDate/index.vue.d.ts +23 -0
  137. package/dist/runtime/components/Edit/ShortcutIndicator/index.vue +3 -0
  138. package/dist/runtime/components/Edit/Transition/Height.vue +95 -0
  139. package/dist/runtime/components/Edit/Transition/Height.vue.d.ts +36 -0
  140. package/dist/runtime/components/Edit/index.d.ts +7 -3
  141. package/dist/runtime/components/Edit/index.js +12 -4
  142. package/dist/runtime/composables/defineBlokkli.js +4 -2
  143. package/dist/runtime/css/output.css +1 -1
  144. package/dist/runtime/helpers/animationProvider.d.ts +35 -1
  145. package/dist/runtime/helpers/animationProvider.js +179 -48
  146. package/dist/runtime/helpers/composables/defineRenderer.d.ts +8 -0
  147. package/dist/runtime/helpers/composables/defineRenderer.js +8 -0
  148. package/dist/runtime/helpers/composables/useStateBasedCache.d.ts +4 -0
  149. package/dist/runtime/helpers/composables/useStateBasedCache.js +13 -0
  150. package/dist/runtime/helpers/composables/useStickyToolbar.d.ts +4 -1
  151. package/dist/runtime/helpers/composables/useStickyToolbar.js +53 -35
  152. package/dist/runtime/helpers/definitionProvider.d.ts +1 -1
  153. package/dist/runtime/helpers/dom/index.d.ts +1 -0
  154. package/dist/runtime/helpers/domProvider.d.ts +54 -14
  155. package/dist/runtime/helpers/domProvider.js +168 -134
  156. package/dist/runtime/helpers/index.d.ts +1 -8
  157. package/dist/runtime/helpers/index.js +1 -84
  158. package/dist/runtime/helpers/providers/blocks.d.ts +10 -0
  159. package/dist/runtime/helpers/providers/blocks.js +91 -0
  160. package/dist/runtime/helpers/providers/directive.d.ts +24 -0
  161. package/dist/runtime/helpers/providers/directive.js +205 -0
  162. package/dist/runtime/helpers/providers/element.d.ts +6 -0
  163. package/dist/runtime/helpers/providers/element.js +35 -0
  164. package/dist/runtime/helpers/providers/fields.d.ts +8 -0
  165. package/dist/runtime/helpers/providers/fields.js +47 -0
  166. package/dist/runtime/helpers/selectionProvider.d.ts +11 -11
  167. package/dist/runtime/helpers/selectionProvider.js +38 -45
  168. package/dist/runtime/helpers/stateProvider.d.ts +7 -2
  169. package/dist/runtime/helpers/stateProvider.js +83 -14
  170. package/dist/runtime/helpers/storageProvider.d.ts +3 -2
  171. package/dist/runtime/helpers/storageProvider.js +6 -2
  172. package/dist/runtime/helpers/symbols.d.ts +1 -0
  173. package/dist/runtime/helpers/symbols.js +1 -0
  174. package/dist/runtime/helpers/themeProvider.d.ts +2 -1
  175. package/dist/runtime/helpers/themeProvider.js +24 -14
  176. package/dist/runtime/helpers/typesProvider.js +10 -26
  177. package/dist/runtime/helpers/uiProvider.d.ts +11 -3
  178. package/dist/runtime/helpers/uiProvider.js +45 -17
  179. package/dist/runtime/icons/calendar.svg +1 -0
  180. package/dist/runtime/icons/clock.svg +1 -0
  181. package/dist/runtime/icons/comment_add.svg +1 -5
  182. package/dist/runtime/icons/delete.svg +1 -8
  183. package/dist/runtime/icons/duplicate.svg +1 -12
  184. package/dist/runtime/icons/edit.svg +1 -8
  185. package/dist/runtime/icons/reusable.svg +1 -5
  186. package/dist/runtime/plugins/blokkliDirectives.js +96 -0
  187. package/dist/runtime/types/index.d.ts +66 -35
  188. package/package.json +1 -1
  189. package/dist/runtime/components/Edit/DragInteractions/index.vue +0 -401
  190. package/dist/runtime/components/Edit/Features/CommandPalette/Palette/Group/index.vue +0 -63
  191. package/dist/runtime/components/Edit/Features/Selection/AddButtons/AddButtonsField.vue +0 -54
  192. package/dist/runtime/plugins/blokkliEditable.js +0 -31
  193. /package/dist/runtime/components/Edit/{DragInteractions → Features/BlockScheduler}/index.vue.d.ts +0 -0
  194. /package/dist/runtime/plugins/{blokkliEditable.d.ts → blokkliDirectives.d.ts} +0 -0
@@ -19,7 +19,6 @@
19
19
  :key="item.uuid + fieldListType + definitions.renderKey.value"
20
20
  :uuid="item.uuid"
21
21
  :bundle="item.bundle"
22
- :is-new="item.isNew"
23
22
  :options="item.options"
24
23
  :props="item.props"
25
24
  is-editing
@@ -36,7 +35,6 @@
36
35
  :data-host-field-name="name"
37
36
  :data-host-field-list-type="fieldListType"
38
37
  :data-is-nested="isNested"
39
- :data-is-new="item.isNew"
40
38
  :data-entity-type="runtimeConfig.itemEntityType"
41
39
  :data-bk-is-muted="isMuted(item)"
42
40
  />
@@ -54,7 +52,6 @@
54
52
  :key="item.uuid + fieldListType"
55
53
  :uuid="item.uuid"
56
54
  :bundle="item.bundle"
57
- :is-new="item.isNew"
58
55
  :options="item.options"
59
56
  :props="item.props"
60
57
  is-editing
@@ -71,7 +68,6 @@
71
68
  :data-host-field-name="name"
72
69
  :data-host-field-list-type="fieldListType"
73
70
  :data-is-nested="isNested"
74
- :data-is-new="item.isNew"
75
71
  :data-entity-type="runtimeConfig.itemEntityType"
76
72
  :data-bk-is-muted="isMuted(item)"
77
73
  />
@@ -105,7 +101,7 @@ const props = defineProps({
105
101
  language: { type: String, required: false, default: void 0 },
106
102
  tag: { type: String, required: false, default: "div" },
107
103
  isNested: { type: Boolean, required: true },
108
- fieldListType: { type: String, required: true },
104
+ fieldListType: { type: null, required: true },
109
105
  allowedFragments: { type: Array, required: false, default: void 0 },
110
106
  dropAlignment: { type: String, required: false, default: void 0 },
111
107
  proxyMode: { type: Boolean, required: false },
@@ -162,18 +158,30 @@ function isMuted(item) {
162
158
  if (!item) {
163
159
  return true;
164
160
  }
161
+ if (!item.editContext?.isPublished) {
162
+ return true;
163
+ }
165
164
  const isVisible = isVisibleByOptions(item, props.language);
166
165
  const isVisibleCustom = props.shouldRenderItem ? props.shouldRenderItem(item) : true;
167
166
  return !(isVisible && isVisibleCustom);
168
167
  }
168
+ const data = computed(() => {
169
+ return {
170
+ fieldListType: props.fieldListType,
171
+ allowedFragments: props.allowedFragments ?? [],
172
+ isNested: props.isNested,
173
+ nestingLevel: props.nestingLevel,
174
+ dropAlignment: props.dropAlignment ?? null
175
+ };
176
+ });
169
177
  watch(root, function(newRoot) {
170
178
  if (newRoot) {
171
- dom.updateFieldElement(props.entity, props.name, newRoot);
179
+ dom.updateFieldElement(props.entity, props.name, newRoot, data.value);
172
180
  }
173
181
  });
174
182
  onMounted(() => {
175
183
  if (root.value) {
176
- dom.registerField(props.entity, props.name, root.value);
184
+ dom.registerField(props.entity, props.name, root.value, data.value);
177
185
  }
178
186
  });
179
187
  onBeforeUnmount(() => {
@@ -1,6 +1,6 @@
1
- import type { FieldListItem, EntityContext } from '#blokkli/types';
1
+ import type { FieldListItem, EntityContext, FieldDropAlignment } from '#blokkli/types';
2
2
  import type { BlokkliFragmentName } from '#blokkli-build/definitions';
3
- import type { FieldListItemTyped } from '#blokkli-build/generated-types';
3
+ import type { FieldListItemTyped, ValidFieldListTypes } from '#blokkli-build/generated-types';
4
4
  type __VLS_Props = {
5
5
  name: string;
6
6
  fieldKey: string;
@@ -9,9 +9,9 @@ type __VLS_Props = {
9
9
  language?: string;
10
10
  tag?: string;
11
11
  isNested: boolean;
12
- fieldListType: string;
12
+ fieldListType: ValidFieldListTypes;
13
13
  allowedFragments?: BlokkliFragmentName[];
14
- dropAlignment?: 'vertical' | 'horizontal';
14
+ dropAlignment?: FieldDropAlignment;
15
15
  proxyMode?: boolean;
16
16
  globalProxyMode?: boolean;
17
17
  nestingLevel: number;
@@ -19,9 +19,9 @@ type __VLS_Props = {
19
19
  };
20
20
  declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
21
21
  allowedFragments: BlokkliFragmentName[];
22
+ dropAlignment: FieldDropAlignment;
22
23
  tag: string;
23
24
  language: string;
24
- dropAlignment: "vertical" | "horizontal";
25
25
  shouldRenderItem: (item: FieldListItem | FieldListItemTyped) => boolean;
26
26
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
27
27
  export default _default;
@@ -1,21 +1,19 @@
1
1
  <template>
2
2
  <Teleport to="body">
3
- <div v-show="isVisible" class="bk">
4
- <div class="bk-edit-indicator" :style="style">
5
- <button
6
- ref="button"
7
- class="bk-button bk-is-primary"
8
- @mouseenter="isHovering = true"
9
- @mouseleave="isHovering = false"
10
- @click="$emit('edit')"
11
- >
12
- {{ label }}
13
- </button>
14
- </div>
3
+ <div class="bk">
4
+ <button
5
+ ref="button"
6
+ class="bk-edit-indicator bk-button bk-is-primary"
7
+ @mouseenter="isHovering = true"
8
+ @mouseleave="isHovering = false"
9
+ @click="$emit('edit')"
10
+ >
11
+ {{ label }}
12
+ </button>
15
13
 
16
14
  <div
17
- v-if="overlayStyle"
18
- :style="overlayStyle"
15
+ v-show="isHovering"
16
+ ref="overlay"
19
17
  class="bk-edit-indicator-overlay"
20
18
  />
21
19
  </div>
@@ -24,47 +22,123 @@
24
22
 
25
23
  <script setup>
26
24
  import textProvider from "#blokkli/helpers/textProvider";
27
- import { ref, computed } from "#imports";
25
+ import { ref, onMounted, onBeforeUnmount, useState, computed } from "#imports";
28
26
  import "#blokkli-build/styles.css";
29
27
  import useAnimationFrame from "#blokkli/helpers/composables/useAnimationFrame";
30
28
  const props = defineProps({
31
29
  uuid: { type: String, required: true },
32
- editLabel: { type: String, required: false }
30
+ entityType: { type: String, required: true },
31
+ editLabel: { type: String, required: false },
32
+ permissions: { type: Array, required: true }
33
33
  });
34
+ const key = computed(() => props.entityType + ":" + props.uuid);
34
35
  const $t = textProvider();
35
- const label = computed(
36
- () => props.editLabel || $t("editIndicatorLabel", "Edit blocks")
37
- );
36
+ const label = computed(() => {
37
+ if (props.editLabel) {
38
+ return props.editLabel;
39
+ } else if (props.permissions.includes("edit")) {
40
+ return $t("editIndicatorLabel", "Edit blocks");
41
+ } else if (props.permissions.includes("review")) {
42
+ return $t("editIndicatorLabelReview", "Review changes");
43
+ } else if (props.permissions.includes("view")) {
44
+ return $t("editIndicatorLabelView", "View changes");
45
+ }
46
+ return null;
47
+ });
38
48
  defineEmits(["edit"]);
39
49
  const isHovering = ref(false);
40
- const style = ref({});
41
50
  const button = ref(null);
42
- const isVisible = ref(false);
43
- const overlayStyle = ref(null);
44
- function calculateIdealYPosition(elementHeight, bounds) {
45
- const idealTop = Math.min(
46
- Math.max(bounds.top, bounds.bottom - elementHeight - 20),
47
- 20
48
- );
49
- return Math.max(idealTop, bounds.y + 20);
51
+ const overlay = ref(null);
52
+ const targetElement = ref(null);
53
+ const indicatorRegistry = useState(
54
+ "blokkliEditIndicators",
55
+ () => []
56
+ );
57
+ const isManager = computed(() => {
58
+ return indicatorRegistry.value[0]?.key === key.value;
59
+ });
60
+ function calculateIdealYPosition(buttonHeight, bounds, gap) {
61
+ const elementHeight = bounds.bottom - bounds.top;
62
+ let position;
63
+ if (elementHeight < 100) {
64
+ position = bounds.top + elementHeight / 2 - buttonHeight / 2;
65
+ } else {
66
+ position = bounds.top + gap;
67
+ }
68
+ position = Math.max(position, gap);
69
+ return Math.min(position, bounds.bottom - buttonHeight - gap);
50
70
  }
51
- useAnimationFrame(() => {
52
- const el = document.querySelector(`[data-provider-uuid="${props.uuid}"]`);
53
- isVisible.value = window.innerWidth > 1024;
54
- if (isVisible.value && el && el instanceof HTMLElement && button.value) {
55
- const rect = el.getBoundingClientRect();
56
- const buttonHeight = button.value.getBoundingClientRect().height;
57
- const y = calculateIdealYPosition(buttonHeight, rect);
58
- style.value.transform = `translateY(${y}px)`;
59
- if (isHovering.value) {
60
- overlayStyle.value = {
61
- width: rect.width + "px",
62
- height: rect.height + "px",
63
- transform: `translate(${rect.x}px, ${rect.y}px)`
64
- };
65
- } else {
66
- overlayStyle.value = null;
71
+ const GAP = 15;
72
+ const indicators = computed(() => {
73
+ const indicators2 = [...indicatorRegistry.value];
74
+ return indicators2.sort((a, b) => {
75
+ const position = a.targetElement.compareDocumentPosition(b.targetElement);
76
+ if (position & Node.DOCUMENT_POSITION_FOLLOWING) {
77
+ return -1;
78
+ }
79
+ if (position & Node.DOCUMENT_POSITION_PRECEDING) {
80
+ return 1;
81
+ }
82
+ return 0;
83
+ });
84
+ });
85
+ function updateAllIndicatorPositions() {
86
+ const positions = [];
87
+ const heights = [];
88
+ for (let i = 0; i < indicators.value.length; i++) {
89
+ const data = indicators.value[i];
90
+ const rect = data.targetElement.getBoundingClientRect();
91
+ const buttonHeight = data.buttonElement.offsetHeight;
92
+ let idealY = calculateIdealYPosition(buttonHeight, rect, GAP);
93
+ for (let j = 0; j < i; j++) {
94
+ const prevRect = indicators.value[j].targetElement.getBoundingClientRect();
95
+ const prevElementTop = prevRect.top;
96
+ const prevElementHeight = prevRect.height;
97
+ const collisionPosition = prevElementTop + prevElementHeight + GAP;
98
+ if (idealY < collisionPosition) {
99
+ idealY = collisionPosition;
100
+ }
67
101
  }
102
+ const elementBottom = rect.bottom - buttonHeight - GAP;
103
+ if (elementBottom < idealY) {
104
+ idealY = elementBottom;
105
+ }
106
+ idealY = Math.round(idealY);
107
+ positions.push(idealY);
108
+ heights.push(buttonHeight);
109
+ data.buttonElement.style.transform = `translateY(${idealY}px)`;
110
+ }
111
+ }
112
+ onMounted(() => {
113
+ const el = document.querySelector(`[data-provider-uuid="${props.uuid}"]`);
114
+ if (el && el instanceof HTMLElement) {
115
+ targetElement.value = el;
116
+ }
117
+ if (button.value && targetElement.value) {
118
+ indicatorRegistry.value.push({
119
+ key: key.value,
120
+ targetElement: targetElement.value,
121
+ buttonElement: button.value
122
+ });
123
+ }
124
+ });
125
+ onBeforeUnmount(() => {
126
+ indicatorRegistry.value = indicatorRegistry.value.filter(
127
+ (i) => i.key !== key.value
128
+ );
129
+ });
130
+ useAnimationFrame(() => {
131
+ if (!button.value || !targetElement.value) {
132
+ return;
133
+ }
134
+ if (isManager.value) {
135
+ updateAllIndicatorPositions();
136
+ }
137
+ if (isHovering.value && overlay.value) {
138
+ const rect = targetElement.value.getBoundingClientRect();
139
+ overlay.value.style.width = rect.width + "px";
140
+ overlay.value.style.height = rect.height + "px";
141
+ overlay.value.style.transform = `translate(${rect.x}px, ${rect.y}px)`;
68
142
  }
69
143
  });
70
144
  </script>
@@ -1,7 +1,10 @@
1
1
  import '#blokkli-build/styles.css';
2
+ import type { EditPermission } from '#blokkli/types';
2
3
  type __VLS_Props = {
3
4
  uuid: string;
5
+ entityType: string;
4
6
  editLabel?: string;
7
+ permissions: EditPermission[];
5
8
  };
6
9
  declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
7
10
  edit: (...args: any[]) => void;
@@ -1,41 +1,41 @@
1
1
  <template>
2
2
  <Teleport to="body">
3
3
  <Transition :name="ui.useAnimations.value ? 'bk-loading' : void 0">
4
- <Loading
5
- v-if="isInitializing || !toolbarLoaded || !featuresLoaded"
6
- screen
7
- />
4
+ <Loading v-if="showLoading" screen />
8
5
  </Transition>
9
6
 
10
7
  <div id="bk-banner-container">
11
- <Messages />
12
- <div v-if="!state.stateAvailable.value" class="bk-state-unavailable">
13
- <h2>
14
- {{
15
- $t("stateUnavailableTitle", "The edit state could not be loaded.")
16
- }}
17
- </h2>
18
- <p>
19
- {{
20
- $t(
21
- "stateUnavailableText",
22
- "This could be due to missing permissions or a temporary problem. Please try again later."
23
- )
24
- }}
25
- </p>
8
+ <div id="bk-banner-list" class="bk">
9
+ <Banner
10
+ v-if="!state.stateAvailable.value"
11
+ id="state-unavailable"
12
+ icon="sad"
13
+ scheme="red"
14
+ :text="stateNotAvailableText"
15
+ />
16
+ <Banner
17
+ v-if="viewOnlyBanner"
18
+ id="view-only"
19
+ :icon="viewOnlyBanner.icon"
20
+ scheme="yellow"
21
+ :text="viewOnlyBanner.text"
22
+ />
26
23
  </div>
24
+ <Messages />
27
25
  </div>
28
26
  </Teleport>
27
+ <Teleport to="#nuxt-root">
28
+ <div id="bk-canvas-overlay" class="bk bk-canvas-overlay" />
29
+ </Teleport>
29
30
  <Actions v-if="!isInitializing" />
30
31
  <Toolbar @loaded="toolbarLoaded = true" />
31
32
  <AppMenu v-if="toolbarLoaded" />
32
33
  <Indicators />
33
34
  <Features
34
- v-if="!isInitializing && toolbarLoaded"
35
+ v-if="isReady"
35
36
  :key="route.fullPath"
36
37
  @loaded="featuresLoaded = true"
37
38
  />
38
- <DragInteractions v-if="!isInitializing" />
39
39
  <AnimationCanvas v-if="!isInitializing" />
40
40
  <Konami />
41
41
  <SystemRequirements />
@@ -66,15 +66,16 @@ import Features from "./Features/index.vue";
66
66
  import Indicators from "./Indicators/index.vue";
67
67
  import AppMenu from "./AppMenu/index.vue";
68
68
  import DraggableList from "./DraggableList.vue";
69
- import DragInteractions from "./DragInteractions/index.vue";
70
69
  import AnimationCanvas from "./AnimationCanvas/index.vue";
71
70
  import SystemRequirements from "./SystemRequirements/index.vue";
72
71
  import Konami from "./Konami/index.vue";
72
+ import Banner from "./Banner/index.vue";
73
73
  import animationProvider from "./../../helpers/animationProvider";
74
74
  import keyboardProvider from "./../../helpers/keyboardProvider";
75
75
  import selectionProvider from "./../../helpers/selectionProvider";
76
76
  import editStateProvider from "./../../helpers/stateProvider";
77
77
  import typesProvider from "./../../helpers/typesProvider";
78
+ import elementProvider from "./../../helpers/providers/element";
78
79
  import domProvider from "./../../helpers/domProvider";
79
80
  import textProvider from "./../../helpers/textProvider";
80
81
  import storageProvider from "./../../helpers/storageProvider";
@@ -87,8 +88,11 @@ import tourProvider from "./../../helpers/tourProvider";
87
88
  import debugProvider from "./../../helpers/debugProvider";
88
89
  import definitionProvider from "./../../helpers/definitionProvider";
89
90
  import dropAreasProvider from "./../../helpers/dropAreaProvider";
91
+ import blocksProvider from "./../../helpers/providers/blocks";
90
92
  import indicatorsProvider from "./../../helpers/indicatorsProvider";
91
93
  import pluginProvider from "./../../helpers/pluginProvider";
94
+ import directiveProvider from "./../../helpers/providers/directive";
95
+ import fieldsProvider from "./../../helpers/providers/fields";
92
96
  import { eventBus } from "#blokkli/helpers/eventBus";
93
97
  import "#blokkli-build/styles.css";
94
98
  import getAdapter from "#blokkli-build/edit-adapter";
@@ -109,7 +113,9 @@ const props = defineProps({
109
113
  entityUuid: { type: String, required: true },
110
114
  entityBundle: { type: String, required: true },
111
115
  language: { type: String, required: false, default: "en" },
112
- isolate: { type: Boolean, required: false }
116
+ isolate: { type: Boolean, required: false },
117
+ permissions: { type: Array, required: true },
118
+ providerEl: { type: null, required: true }
113
119
  });
114
120
  defineSlots();
115
121
  const context = computed(() => {
@@ -129,24 +135,40 @@ const featuresLoaded = ref(false);
129
135
  const isInitializing = ref(true);
130
136
  const definitions = definitionProvider();
131
137
  const $t = textProvider(context);
132
- const state = await editStateProvider(adapter, context, $t, providerKey);
133
- const storage = await storageProvider(adapter);
138
+ const state = await editStateProvider(
139
+ adapter,
140
+ context,
141
+ $t,
142
+ providerKey,
143
+ props.permissions
144
+ );
145
+ const storage = await storageProvider(adapter, context);
134
146
  const debug = debugProvider(storage);
147
+ const element = elementProvider(debug);
135
148
  const features = featuresProvider(storage);
136
- const theme = themeProvider();
137
149
  const commands = commandsProvider();
138
150
  const tour = tourProvider();
139
151
  const dropAreas = dropAreasProvider();
140
152
  const broadcast = broadcastProvider();
141
- const ui = uiProvider(storage, state, context);
142
- const dom = domProvider(ui, debug, definitions);
143
- const animation = animationProvider(ui, storage);
153
+ const ui = uiProvider(props.providerEl, storage, state, context, element);
154
+ const dom = domProvider(ui, debug, definitions, state, element);
155
+ const theme = themeProvider(element);
156
+ const blocks = blocksProvider(state, dom, context);
157
+ const selection = selectionProvider(blocks);
158
+ const animation = animationProvider(ui, storage, selection, element);
144
159
  const keyboard = keyboardProvider(animation);
145
- const selection = selectionProvider(dom);
146
160
  const types = await typesProvider(adapter, selection, context);
147
161
  const indicators = indicatorsProvider();
148
162
  const plugins = pluginProvider();
163
+ const directive = directiveProvider(ui);
164
+ const fields = fieldsProvider(state, dom, types);
149
165
  const mutatedEntity = computed(() => state.mutatedEntity.value || props.entity);
166
+ const isReady = computed(
167
+ () => !isInitializing.value && dom.isReady.value && directive.isReady.value && toolbarLoaded.value
168
+ );
169
+ const showLoading = computed(() => {
170
+ return !isReady.value || !featuresLoaded.value;
171
+ });
150
172
  const onContextMenu = (e) => {
151
173
  e.preventDefault();
152
174
  e.stopPropagation();
@@ -177,6 +199,7 @@ onMounted(() => {
177
199
  document.documentElement.addEventListener("touchstart", onTouchStart);
178
200
  baseLogger.log("EditProvider mounted");
179
201
  dom.init();
202
+ directive.init();
180
203
  isInitializing.value = false;
181
204
  broadcast.emit("editorLoaded", { uuid: props.entityUuid });
182
205
  });
@@ -208,20 +231,67 @@ provide(INJECT_APP, {
208
231
  definitions,
209
232
  dom,
210
233
  dropAreas,
234
+ element,
211
235
  eventBus,
236
+ directive,
212
237
  features,
213
238
  indicators,
214
239
  keyboard,
215
240
  plugins,
216
241
  runtimeConfig,
217
242
  selection,
243
+ blocks,
218
244
  state,
219
245
  storage,
220
246
  theme,
221
247
  tour,
222
248
  types,
223
- ui
249
+ ui,
250
+ fields
251
+ });
252
+ function textWithHighlight(title, text) {
253
+ return `<strong>${title}</strong> ${text}`;
254
+ }
255
+ const stateNotAvailableText = computed(() => {
256
+ return textWithHighlight(
257
+ $t("stateUnavailableTitle", "The edit state could not be loaded."),
258
+ $t(
259
+ "stateUnavailableText",
260
+ "This could be due to missing permissions or a temporary problem. Please try again later."
261
+ )
262
+ );
224
263
  });
264
+ const viewOnlyBanner = computed(
265
+ () => {
266
+ if (props.permissions.includes("edit")) {
267
+ return null;
268
+ }
269
+ if (props.permissions.includes("review")) {
270
+ return {
271
+ text: textWithHighlight(
272
+ $t("viewBannerReviewTitle", "You are in review mode."),
273
+ $t(
274
+ "viewBannerReviewText",
275
+ "You can view and add comments but cannot edit content."
276
+ )
277
+ ),
278
+ icon: "comment"
279
+ };
280
+ } else if (props.permissions.includes("view")) {
281
+ return {
282
+ text: textWithHighlight(
283
+ $t("viewBannerViewTitle", "You are in view-only mode."),
284
+ $t(
285
+ "viewBannerViewText",
286
+ "You can view comments but cannot edit content."
287
+ )
288
+ ),
289
+ icon: "eye"
290
+ };
291
+ }
292
+ return null;
293
+ }
294
+ );
225
295
  const isProxyMode = computed(() => ui.isProxyMode.value);
226
296
  provide(INJECT_GLOBAL_PROXY_MODE, isProxyMode);
227
297
  if (import.meta.hot) {
@@ -1,3 +1,4 @@
1
+ import type { EditPermission } from '#blokkli/types';
1
2
  import '#blokkli-build/styles.css';
2
3
  declare const _default: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
3
4
  props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, never> & {
@@ -7,6 +8,8 @@ declare const _default: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>
7
8
  entityBundle: string;
8
9
  language?: string;
9
10
  isolate?: boolean;
11
+ permissions: EditPermission[];
12
+ providerEl: HTMLElement;
10
13
  } & Partial<{}>> & import("vue").PublicProps;
11
14
  expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
12
15
  attrs: any;
@@ -86,7 +86,7 @@ const { settings } = defineBlokkliFeature({
86
86
  },
87
87
  screenshot: "feature-add-list.jpg"
88
88
  });
89
- const { state, $t, eventBus, ui } = useBlokkli();
89
+ const { state, $t, eventBus, ui, element } = useBlokkli();
90
90
  const hasContextMenuOpen = computed(
91
91
  () => ui.openContextMenu.value.startsWith("add_list_item_")
92
92
  );
@@ -104,17 +104,15 @@ const isActive = ref(false);
104
104
  let mouseTimeout = null;
105
105
  const style = computed(() => {
106
106
  if (settings.value.orientation === "vertical" && (isActive.value || hasContextMenuOpen.value) && wrapper.value) {
107
- const labels = [
108
- ...wrapper.value.querySelectorAll(".bk-list-item-label span")
109
- ];
110
- const width = labels.reduce((acc, el) => {
111
- if (el.offsetWidth > acc) {
112
- return el.offsetWidth;
113
- }
114
- return acc;
115
- }, 0);
107
+ const widths = element.queryAll(
108
+ wrapper.value,
109
+ ".bk-list-item-label span",
110
+ "AddList vertical sidebar style",
111
+ (el) => el.offsetWidth
112
+ );
113
+ const largestWidth = Math.max(...widths);
116
114
  return {
117
- "--bk-add-list-width": width + 90
115
+ "--bk-add-list-width": largestWidth + 90
118
116
  };
119
117
  }
120
118
  return void 0;