@blokkli/editor 2.0.0-alpha.14 → 2.0.0-alpha.16

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 (47) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +922 -2
  3. package/dist/modules/drupal/graphql/base/fragment.paragraphsBlokkliEditState.graphql +4 -0
  4. package/dist/modules/drupal/graphql/features/publishNew.graphql +1 -4
  5. package/dist/modules/drupal/graphql/features/scheduler.graphql +31 -0
  6. package/dist/modules/drupal/index.mjs +17 -0
  7. package/dist/modules/drupal/runtime/adapter/index.js +31 -1
  8. package/dist/runtime/adapter/index.d.ts +36 -0
  9. package/dist/runtime/blokkliPlugins/MenuButton/index.vue.d.ts +2 -2
  10. package/dist/runtime/components/Edit/Dialog/index.vue +3 -0
  11. package/dist/runtime/components/Edit/Dialog/index.vue.d.ts +2 -0
  12. package/dist/runtime/components/Edit/Features/DraggingOverlay/DropTargets/fragment.glsl +7 -1
  13. package/dist/runtime/components/Edit/Features/DraggingOverlay/DropTargets/index.vue +22 -3
  14. package/dist/runtime/components/Edit/Features/DraggingOverlay/DropTargets/vertex.glsl +1 -0
  15. package/dist/runtime/components/Edit/Features/EntityTitle/index.vue +33 -1
  16. package/dist/runtime/components/Edit/Features/Publish/Dialog/Item.vue +41 -14
  17. package/dist/runtime/components/Edit/Features/Publish/Dialog/Item.vue.d.ts +2 -0
  18. package/dist/runtime/components/Edit/Features/Publish/Dialog/PublishOption.vue +47 -0
  19. package/dist/runtime/components/Edit/Features/Publish/Dialog/PublishOption.vue.d.ts +19 -0
  20. package/dist/runtime/components/Edit/Features/Publish/Dialog/ScheduleDate.vue +183 -0
  21. package/dist/runtime/components/Edit/Features/Publish/Dialog/ScheduleDate.vue.d.ts +13 -0
  22. package/dist/runtime/components/Edit/Features/Publish/Dialog/Summary.vue +83 -0
  23. package/dist/runtime/components/Edit/Features/Publish/Dialog/Summary.vue.d.ts +9 -0
  24. package/dist/runtime/components/Edit/Features/Publish/Dialog/index.vue +391 -129
  25. package/dist/runtime/components/Edit/Features/Publish/Dialog/index.vue.d.ts +3 -14
  26. package/dist/runtime/components/Edit/Features/Publish/index.vue +34 -20
  27. package/dist/runtime/components/Edit/Features/Selection/index.vue +21 -7
  28. package/dist/runtime/components/Edit/Form/Datepicker/index.vue +198 -0
  29. package/dist/runtime/components/Edit/Form/Datepicker/index.vue.d.ts +15 -0
  30. package/dist/runtime/components/Edit/Konami/Game/index.vue +8 -1
  31. package/dist/runtime/components/Edit/index.d.ts +2 -1
  32. package/dist/runtime/components/Edit/index.js +2 -0
  33. package/dist/runtime/composables/defineBlokkli.js +1 -1
  34. package/dist/runtime/css/output.css +1 -1
  35. package/dist/runtime/helpers/composables/useDelayedIntersectionObserver.d.ts +1 -1
  36. package/dist/runtime/helpers/composables/useDelayedIntersectionObserver.js +3 -2
  37. package/dist/runtime/helpers/domProvider.js +6 -1
  38. package/dist/runtime/helpers/stateProvider.d.ts +2 -1
  39. package/dist/runtime/helpers/stateProvider.js +31 -0
  40. package/dist/runtime/helpers/uiProvider.d.ts +2 -0
  41. package/dist/runtime/helpers/uiProvider.js +23 -0
  42. package/dist/runtime/helpers/webgl/index.d.ts +11 -2
  43. package/dist/runtime/helpers/webgl/index.js +162 -7
  44. package/dist/runtime/icons/calendar-clock.svg +1 -0
  45. package/dist/runtime/icons/eye-off.svg +1 -0
  46. package/dist/runtime/types/index.d.ts +9 -1
  47. package/package.json +1 -1
@@ -4,21 +4,14 @@
4
4
  :title="publishLabel"
5
5
  :description="publishDescription"
6
6
  :disabled="!mutations.length || !canEdit"
7
- type="success"
7
+ :type="isScheduled ? 'yellow' : 'success'"
8
8
  :weight="0"
9
9
  :icon="icon"
10
10
  @click="onMenuClick"
11
11
  />
12
12
  <Teleport to="body">
13
13
  <BlokkliTransition name="slide-up">
14
- <PublishDialog
15
- v-if="showDialog"
16
- v-model:states="additionalEditStates"
17
- v-model:revision-message="revisionMessage"
18
- v-model:should-publish="shouldPublish"
19
- @close="showDialog = false"
20
- @submit="onSubmit"
21
- />
14
+ <PublishDialog v-if="showDialog" @close="onClose" @submit="onSubmit" />
22
15
  </BlokkliTransition>
23
16
  </Teleport>
24
17
  </template>
@@ -29,11 +22,13 @@ import {
29
22
  defineBlokkliFeature,
30
23
  computed,
31
24
  useRoute,
32
- ref
25
+ ref,
26
+ nextTick
33
27
  } from "#imports";
34
28
  import { PluginMenuButton } from "#blokkli/plugins";
35
29
  import { BlokkliTransition } from "#blokkli/components";
36
30
  import PublishDialog from "./Dialog/index.vue";
31
+ import onBlokkliEvent from "#blokkli/helpers/composables/onBlokkliEvent";
37
32
  const { adapter, settings } = defineBlokkliFeature({
38
33
  id: "publish",
39
34
  icon: "publish",
@@ -55,26 +50,38 @@ const { state, $t, broadcast, context, eventBus } = useBlokkli();
55
50
  const { mutations, canEdit, mutateWithLoadingState } = state;
56
51
  const hasPublishOptions = !!adapter.getPublishOptions;
57
52
  const isPublished = computed(() => !!state.entity.value.status);
53
+ const isScheduled = computed(
54
+ () => !!state.publishOptions.value.publishOn
55
+ );
58
56
  const showDialog = ref(false);
59
- const additionalEditStates = ref([]);
60
- const shouldPublish = ref(!!state.entity.value.status);
61
- const revisionMessage = ref("");
62
57
  const publishLabel = computed(() => {
63
58
  const suffix = hasPublishOptions ? "..." : "";
59
+ if (isScheduled.value) {
60
+ return $t("publishManageSchedule", "Manage scheduling") + suffix;
61
+ }
64
62
  if (isPublished.value) {
65
63
  return (settings.value.closeAfterPublish ? $t("publishAndCloseLabel", "Publish & Close") : $t("publishLabel", "Publish")) + suffix;
66
64
  }
67
65
  return (settings.value.closeAfterPublish ? $t("publishAndCloseLabelUnpublished", "Save & Close") : $t("publishLabelUnpublished", "Save")) + suffix;
68
66
  });
69
- const publishDescription = computed(
70
- () => isPublished.value ? $t("publishDescription", "Publish all changes.") : $t(
67
+ const publishDescription = computed(() => {
68
+ if (isScheduled.value) {
69
+ return $t(
70
+ "publishDescriptionScheduled",
71
+ "View or change the scheduled publication"
72
+ );
73
+ }
74
+ return isPublished.value ? $t("publishDescription", "Publish all changes.") : $t(
71
75
  "publishDescriptionUnpublished",
72
76
  "Save all changes while keeping page unpublished"
73
- )
74
- );
75
- const icon = computed(
76
- () => isPublished.value ? "publish" : "save"
77
- );
77
+ );
78
+ });
79
+ const icon = computed(() => {
80
+ if (state.publishOptions.value?.publishOn) {
81
+ return "calendar-clock";
82
+ }
83
+ return isPublished.value ? "publish" : "save";
84
+ });
78
85
  const onMenuClick = async () => {
79
86
  if (hasPublishOptions) {
80
87
  showDialog.value = true;
@@ -108,6 +115,13 @@ function onSubmit() {
108
115
  window.location.href = route.path;
109
116
  }
110
117
  }
118
+ async function onClose() {
119
+ await nextTick();
120
+ showDialog.value = false;
121
+ }
122
+ onBlokkliEvent("publish:show-dialog", () => {
123
+ showDialog.value = true;
124
+ });
111
125
  </script>
112
126
 
113
127
  <script>
@@ -85,13 +85,24 @@ const itemDropdownItems = computed(() => {
85
85
  )
86
86
  }
87
87
  ];
88
+ } else if (selection.hasHostSelected.value) {
89
+ return [
90
+ {
91
+ id: "select-all-blocks",
92
+ label: $t("selectAllBlocks", "Select all blocks")
93
+ }
94
+ ];
88
95
  }
89
96
  return [];
90
97
  });
91
98
  function onSelectDropdownItem(item) {
92
- if (item.id === "select-all-of-bundle" && selectedBundle.value) {
93
- const uuids = state.getAllUuids(selectedBundle.value);
94
- eventBus.emit("select", uuids);
99
+ if (item.id === "select-all-of-bundle") {
100
+ if (selectedBundle.value) {
101
+ const uuids = state.getAllUuids(selectedBundle.value);
102
+ eventBus.emit("select", uuids);
103
+ }
104
+ } else if (item.id === "select-all-blocks") {
105
+ selectAllBlocks();
95
106
  }
96
107
  }
97
108
  const artboardElement = ui.artboardElement();
@@ -226,6 +237,12 @@ const visuallySelectBlocks = (toggleUuid) => {
226
237
  }
227
238
  return filter(encompassingRect);
228
239
  };
240
+ function selectAllBlocks() {
241
+ eventBus.emit(
242
+ "select:end",
243
+ getSelectAllUuids(dom.getAllBlocks(), selection.blocks.value)
244
+ );
245
+ }
229
246
  onBlokkliEvent("select:shiftToggle", (uuid) => {
230
247
  const uuids = visuallySelectBlocks(uuid);
231
248
  if (uuids) {
@@ -263,10 +280,7 @@ onBlokkliEvent("keyPressed", (e) => {
263
280
  return;
264
281
  }
265
282
  e.originalEvent.preventDefault();
266
- eventBus.emit(
267
- "select:end",
268
- getSelectAllUuids(dom.getAllBlocks(), selection.blocks.value)
269
- );
283
+ selectAllBlocks();
270
284
  }
271
285
  });
272
286
  </script>
@@ -0,0 +1,198 @@
1
+ <template>
2
+ <div
3
+ class="bk-datepicker"
4
+ :class="{
5
+ 'bk-is-invalid': error
6
+ }"
7
+ >
8
+ <div class="bk-datepicker-header">
9
+ <button
10
+ type="button"
11
+ class="bk-datepicker-nav"
12
+ :disabled="!canGoPrevious"
13
+ @click="previousMonth"
14
+ >
15
+ <Icon name="arrow-left" />
16
+ </button>
17
+ <div class="bk-datepicker-title">{{ monthName }} {{ currentYear }}</div>
18
+ <button
19
+ type="button"
20
+ class="bk-datepicker-nav"
21
+ :disabled="!canGoNext"
22
+ @click="nextMonth"
23
+ >
24
+ <Icon name="arrow-right" />
25
+ </button>
26
+ </div>
27
+ <div class="bk-datepicker-weekdays">
28
+ <div v-for="day in weekdays" :key="day" class="bk-datepicker-weekday">
29
+ {{ day }}
30
+ </div>
31
+ </div>
32
+ <div class="bk-datepicker-days">
33
+ <button
34
+ v-for="day in calendarDays"
35
+ :key="day.key"
36
+ type="button"
37
+ class="bk-datepicker-day"
38
+ :disabled="disabled || day.isDisabled"
39
+ @click="selectDate(day)"
40
+ >
41
+ <div
42
+ class="bk-datepicker-day-inner"
43
+ :class="{
44
+ 'bk-is-other-month': !day.isCurrentMonth,
45
+ 'bk-is-today': day.isToday,
46
+ 'bk-is-selected': day.isSelected,
47
+ 'bk-is-disabled': day.isDisabled
48
+ }"
49
+ >
50
+ {{ day.day }}
51
+ </div>
52
+ </button>
53
+ </div>
54
+ </div>
55
+ </template>
56
+
57
+ <script setup>
58
+ import { ref, computed, watch, useBlokkli } from "#imports";
59
+ import { Icon } from "#blokkli/components";
60
+ const props = defineProps({
61
+ min: { type: String, required: false },
62
+ max: { type: String, required: false },
63
+ disabled: { type: Boolean, required: false },
64
+ error: { type: Boolean, required: false }
65
+ });
66
+ const { ui } = useBlokkli();
67
+ const modelValue = defineModel({ type: String });
68
+ const weekdays = computed(() => {
69
+ const formatter = new Intl.DateTimeFormat(ui.locale.value, {
70
+ weekday: "short"
71
+ });
72
+ const days = [];
73
+ for (let i = 0; i < 7; i++) {
74
+ const date = new Date(2023, 0, 2 + i);
75
+ days.push(formatter.format(date));
76
+ }
77
+ return days;
78
+ });
79
+ const monthNames = computed(() => {
80
+ const formatter = new Intl.DateTimeFormat(ui.locale.value, { month: "long" });
81
+ const months = [];
82
+ for (let i = 0; i < 12; i++) {
83
+ const date = new Date(2023, i, 1);
84
+ months.push(formatter.format(date));
85
+ }
86
+ return months;
87
+ });
88
+ const initDate = modelValue.value ? new Date(modelValue.value) : /* @__PURE__ */ new Date();
89
+ const currentMonth = ref(initDate.getMonth());
90
+ const currentYear = ref(initDate.getFullYear());
91
+ const monthName = computed(() => monthNames.value[currentMonth.value]);
92
+ const canGoPrevious = computed(() => {
93
+ if (props.disabled) {
94
+ return false;
95
+ }
96
+ if (!props.min) {
97
+ return true;
98
+ }
99
+ const prevMonth = currentMonth.value === 0 ? 11 : currentMonth.value - 1;
100
+ const prevYear = currentMonth.value === 0 ? currentYear.value - 1 : currentYear.value;
101
+ const lastDayOfPrevMonth = new Date(prevYear, prevMonth + 1, 0);
102
+ const lastDayString = formatDate(lastDayOfPrevMonth);
103
+ return lastDayString >= props.min;
104
+ });
105
+ const canGoNext = computed(() => {
106
+ if (props.disabled) {
107
+ return false;
108
+ }
109
+ if (!props.max) {
110
+ return true;
111
+ }
112
+ const nextMonth2 = currentMonth.value === 11 ? 0 : currentMonth.value + 1;
113
+ const nextYear = currentMonth.value === 11 ? currentYear.value + 1 : currentYear.value;
114
+ const firstDayOfNextMonth = new Date(nextYear, nextMonth2, 1);
115
+ const firstDayString = formatDate(firstDayOfNextMonth);
116
+ return firstDayString <= props.max;
117
+ });
118
+ function previousMonth() {
119
+ if (currentMonth.value === 0) {
120
+ currentMonth.value = 11;
121
+ currentYear.value--;
122
+ } else {
123
+ currentMonth.value--;
124
+ }
125
+ }
126
+ function nextMonth() {
127
+ if (currentMonth.value === 11) {
128
+ currentMonth.value = 0;
129
+ currentYear.value++;
130
+ } else {
131
+ currentMonth.value++;
132
+ }
133
+ }
134
+ const calendarDays = computed(() => {
135
+ const firstDay = new Date(currentYear.value, currentMonth.value, 1);
136
+ const lastDay = new Date(currentYear.value, currentMonth.value + 1, 0);
137
+ let firstDayOfWeek = firstDay.getDay() - 1;
138
+ if (firstDayOfWeek < 0) firstDayOfWeek = 6;
139
+ const days = [];
140
+ const prevMonthLastDay = new Date(currentYear.value, currentMonth.value, 0);
141
+ for (let i = firstDayOfWeek - 1; i >= 0; i--) {
142
+ const day = prevMonthLastDay.getDate() - i;
143
+ const date = new Date(currentYear.value, currentMonth.value - 1, day);
144
+ days.push(createCalendarDay(date, false));
145
+ }
146
+ for (let day = 1; day <= lastDay.getDate(); day++) {
147
+ const date = new Date(currentYear.value, currentMonth.value, day);
148
+ days.push(createCalendarDay(date, true));
149
+ }
150
+ const remainingDays = 42 - days.length;
151
+ for (let day = 1; day <= remainingDays; day++) {
152
+ const date = new Date(currentYear.value, currentMonth.value + 1, day);
153
+ days.push(createCalendarDay(date, false));
154
+ }
155
+ return days;
156
+ });
157
+ function createCalendarDay(date, isCurrentMonth) {
158
+ const dateString = formatDate(date);
159
+ const today = /* @__PURE__ */ new Date();
160
+ const todayString = formatDate(today);
161
+ let isDisabled = false;
162
+ if (props.min && dateString < props.min) {
163
+ isDisabled = true;
164
+ }
165
+ if (props.max && dateString > props.max) {
166
+ isDisabled = true;
167
+ }
168
+ return {
169
+ day: date.getDate(),
170
+ date,
171
+ dateString,
172
+ key: dateString,
173
+ isCurrentMonth,
174
+ isToday: dateString === todayString,
175
+ isSelected: dateString === modelValue.value,
176
+ isDisabled
177
+ };
178
+ }
179
+ function formatDate(date) {
180
+ const year = date.getFullYear();
181
+ const month = String(date.getMonth() + 1).padStart(2, "0");
182
+ const day = String(date.getDate()).padStart(2, "0");
183
+ return `${year}-${month}-${day}`;
184
+ }
185
+ function selectDate(day) {
186
+ if (day.isDisabled || props.disabled) {
187
+ return;
188
+ }
189
+ modelValue.value = day.dateString;
190
+ }
191
+ watch(modelValue, (newValue) => {
192
+ if (newValue) {
193
+ const date = new Date(newValue);
194
+ currentMonth.value = date.getMonth();
195
+ currentYear.value = date.getFullYear();
196
+ }
197
+ });
198
+ </script>
@@ -0,0 +1,15 @@
1
+ type __VLS_Props = {
2
+ min?: string;
3
+ max?: string;
4
+ disabled?: boolean;
5
+ error?: boolean;
6
+ };
7
+ type __VLS_PublicProps = __VLS_Props & {
8
+ modelValue?: string;
9
+ };
10
+ declare const _default: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
11
+ "update:modelValue": (value: string | undefined) => any;
12
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
13
+ "onUpdate:modelValue"?: ((value: string | undefined) => any) | undefined;
14
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
15
+ export default _default;
@@ -54,6 +54,7 @@ import logoUrl from "./blokkli.png";
54
54
  const emit = defineEmits(["close"]);
55
55
  const DEBUG_ICONS = false;
56
56
  const DEBUG_GAME = false;
57
+ const INIT_EATEN = 0;
57
58
  const largeIconSize = 32;
58
59
  const blackColor = "black";
59
60
  const worldWidth = 7 * 3;
@@ -124,7 +125,7 @@ let snakeCanvas = null;
124
125
  let logoCanvas = null;
125
126
  let lastScore = -1;
126
127
  let lastBlocksEaten = -1;
127
- const cellMoveDuration = 200;
128
+ const cellMoveDuration = 250;
128
129
  function generateFood() {
129
130
  let newFood;
130
131
  do {
@@ -211,6 +212,12 @@ function resetGame() {
211
212
  score.value = 10 * 100;
212
213
  gameStarted.value = true;
213
214
  }
215
+ if (INIT_EATEN) {
216
+ for (let i = 0; i < INIT_EATEN; i++) {
217
+ const head = snake.value[0];
218
+ snake.value.push({ x: head.x - i - 1, y: head.y });
219
+ }
220
+ }
214
221
  generateFood();
215
222
  }
216
223
  function update(currentTime) {
@@ -2,6 +2,7 @@ import AddListItem from './AddListItem/index.vue.js';
2
2
  import ConfigForm from './PluginConfigForm/index.vue.js';
3
3
  import DialogModal from './Dialog/index.vue.js';
4
4
  import DiffViewerState from './DiffViewer/State.vue.js';
5
+ import FormDatepicker from './Form/Datepicker/index.vue.js';
5
6
  import FormGroup from './Form/Group/index.vue.js';
6
7
  import FormItem from './Form/Item/index.vue.js';
7
8
  import FormOverlay from './FormOverlay/index.vue.js';
@@ -26,4 +27,4 @@ import BlokkliTransition from './Transition/index.vue.js';
26
27
  import Sortli from './Sortli/index.vue.js';
27
28
  import ViewportBlockingRect from './ViewportBlockingRect/index.vue.js';
28
29
  import AddListItemIcon from './AddListItemIcon/index.vue.js';
29
- export { AddListItem, AddListItemIcon, ConfigForm, DialogModal, DiffViewerState, FormGroup, FormItem, FormOverlay, FormRadio, FormSelect, FormText, FormTextarea, FormToggle, FormRadioTabs, Highlight, Icon, InfoBox, ItemIcon, Loading, Pagination, RelativeTime, Resizable, ScaleToFit, ScrollBoundary, ShortcutIndicator, Sortli, ViewportBlockingRect, BlokkliTransition, };
30
+ export { AddListItem, AddListItemIcon, ConfigForm, DialogModal, DiffViewerState, FormDatepicker, FormGroup, FormItem, FormOverlay, FormRadio, FormSelect, FormText, FormTextarea, FormToggle, FormRadioTabs, Highlight, Icon, InfoBox, ItemIcon, Loading, Pagination, RelativeTime, Resizable, ScaleToFit, ScrollBoundary, ShortcutIndicator, Sortli, ViewportBlockingRect, BlokkliTransition, };
@@ -2,6 +2,7 @@ import AddListItem from "./AddListItem/index.vue";
2
2
  import ConfigForm from "./PluginConfigForm/index.vue";
3
3
  import DialogModal from "./Dialog/index.vue";
4
4
  import DiffViewerState from "./DiffViewer/State.vue";
5
+ import FormDatepicker from "./Form/Datepicker/index.vue";
5
6
  import FormGroup from "./Form/Group/index.vue";
6
7
  import FormItem from "./Form/Item/index.vue";
7
8
  import FormOverlay from "./FormOverlay/index.vue";
@@ -32,6 +33,7 @@ export {
32
33
  ConfigForm,
33
34
  DialogModal,
34
35
  DiffViewerState,
36
+ FormDatepicker,
35
37
  FormGroup,
36
38
  FormItem,
37
39
  FormOverlay,
@@ -59,7 +59,7 @@ export function defineBlokkli(arg) {
59
59
  ...editContext?.mutatedOptions[uuid] || {}
60
60
  };
61
61
  }
62
- const optionKey = bundle === BUNDLE_BLOKKLI_FRAGMENT ? "fragment:" + item?.value.fragmentName + "__default" : identifier;
62
+ const optionKey = bundle === BUNDLE_BLOKKLI_FRAGMENT ? "fragment:" + item?.value.fragmentName : identifier;
63
63
  const runtimeOptionDefinitions = (editContext?.definitions.runtimeOptions.value || OPTIONS)[optionKey] || {};
64
64
  const result = Object.entries(runtimeOptionDefinitions).reduce((acc, [key, v]) => {
65
65
  const definition = v;