mechanica 1.0.2-b → 1.0.3

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/editor.js CHANGED
@@ -1,6 +1,103 @@
1
- import { watch, defineComponent, computed, inject, openBlock, createElementBlock, Fragment, renderList, createElementVNode, toDisplayString, getCurrentScope, onScopeDispose, toRef as toRef$1, readonly, customRef, ref, toValue, nextTick, getCurrentInstance, onMounted, createBlock, Teleport, createVNode, Transition, withCtx, unref, mergeProps, withModifiers, renderSlot, createCommentVNode, resolveDynamicComponent, normalizeClass, shallowRef, isRef, createTextVNode, reactive, shallowReactive, normalizeStyle, normalizeProps, guardReactiveProps, TransitionGroup, useSlots, createSlots, withDirectives, vModelText, vModelDynamic, createStaticVNode, mergeModels, useModel, resolveComponent, provide, createApp } from "vue";
1
+ import { defineComponent, ref, watch, openBlock, createElementBlock, normalizeStyle, createElementVNode, shallowRef, onMounted, onBeforeUnmount, computed, normalizeClass, createTextVNode, toDisplayString, createCommentVNode, renderSlot, createVNode, Transition, withCtx, getCurrentScope, onScopeDispose, toRef as toRef$1, readonly, customRef, toValue, nextTick, getCurrentInstance, createBlock, createSlots, withDirectives, vModelText, vModelDynamic, inject, Fragment, renderList, unref, h, TransitionGroup, useSlots, Teleport, mergeProps, withModifiers, createStaticVNode, resolveDynamicComponent, isRef, reactive, vShow, shallowReactive, mergeModels, useModel, vModelCheckbox, resolveComponent, normalizeProps, guardReactiveProps, provide, createApp } from "vue";
2
2
  import { blocksList as blocksList$1, addUpdateListener } from "virtual:builder-blocks";
3
3
  import { registerAlias, unfoldSchema } from "compact-json-schema";
4
+ const _sfc_main$z = /* @__PURE__ */ defineComponent({
5
+ __name: "HoverFrame",
6
+ props: {
7
+ element: {},
8
+ resizable: { type: Boolean }
9
+ },
10
+ setup(__props, { expose: __expose }) {
11
+ const props = __props;
12
+ const style = ref({ display: "none" });
13
+ const updateStyle = () => {
14
+ if (props.element) {
15
+ const rect = props.element.getBoundingClientRect();
16
+ style.value = {
17
+ top: rect.top + document.documentElement.scrollTop + "px",
18
+ left: rect.left + document.documentElement.scrollLeft + "px",
19
+ width: rect.width + "px",
20
+ height: rect.height + "px"
21
+ };
22
+ } else {
23
+ style.value = { display: "none" };
24
+ }
25
+ };
26
+ const resizeObserver = new ResizeObserver(updateStyle);
27
+ watch(() => props.element, (element, lastElement) => {
28
+ updateStyle();
29
+ if (element) {
30
+ resizeObserver.observe(element);
31
+ } else if (lastElement) {
32
+ resizeObserver.unobserve(lastElement);
33
+ }
34
+ }, { immediate: true });
35
+ __expose({
36
+ update: updateStyle
37
+ });
38
+ return (_ctx, _cache) => {
39
+ return openBlock(), createElementBlock("div", {
40
+ class: "editor-component editor-hover-frame",
41
+ style: normalizeStyle(style.value)
42
+ }, null, 4);
43
+ };
44
+ }
45
+ });
46
+ const _sfc_main$y = /* @__PURE__ */ defineComponent({
47
+ __name: "InsertedPlace",
48
+ props: {
49
+ top: {}
50
+ },
51
+ setup(__props) {
52
+ return (_ctx, _cache) => {
53
+ return openBlock(), createElementBlock("div", {
54
+ class: "editor__inserted-place-marker",
55
+ style: normalizeStyle({ top: _ctx.top + "px" })
56
+ }, null, 4);
57
+ };
58
+ }
59
+ });
60
+ const _export_sfc = (sfc, props) => {
61
+ const target = sfc.__vccOpts || sfc;
62
+ for (const [key, val] of props) {
63
+ target[key] = val;
64
+ }
65
+ return target;
66
+ };
67
+ const _sfc_main$x = {};
68
+ const _hoisted_1$q = {
69
+ width: "16",
70
+ height: "16",
71
+ viewBox: "0 0 16 16",
72
+ fill: "none",
73
+ xmlns: "http://www.w3.org/2000/svg"
74
+ };
75
+ function _sfc_render$9(_ctx, _cache) {
76
+ return openBlock(), createElementBlock("svg", _hoisted_1$q, _cache[0] || (_cache[0] = [
77
+ createElementVNode("path", {
78
+ d: "M10.707 14.364C10.8945 14.1764 10.9998 13.9221 10.9998 13.657C10.9998 13.3918 10.8945 13.1375 10.707 12.95L5.75705 7.99995L10.707 3.04995C10.8892 2.86135 10.99 2.60875 10.9877 2.34655C10.9854 2.08435 10.8803 1.83354 10.6949 1.64813C10.5095 1.46272 10.2586 1.35756 9.99645 1.35528C9.73425 1.353 9.48165 1.45379 9.29305 1.63595L3.63605 7.29295C3.44858 7.48048 3.34326 7.73479 3.34326 7.99995C3.34326 8.26512 3.44858 8.51942 3.63605 8.70695L9.29305 14.364C9.48058 14.5514 9.73488 14.6567 10 14.6567C10.2652 14.6567 10.5195 14.5514 10.707 14.364Z",
79
+ fill: "currentColor"
80
+ }, null, -1)
81
+ ]));
82
+ }
83
+ const ChevronLeftIcon = /* @__PURE__ */ _export_sfc(_sfc_main$x, [["render", _sfc_render$9]]);
84
+ const _sfc_main$w = {};
85
+ const _hoisted_1$p = {
86
+ width: "16",
87
+ height: "16",
88
+ viewBox: "0 0 16 16",
89
+ fill: "none",
90
+ xmlns: "http://www.w3.org/2000/svg"
91
+ };
92
+ function _sfc_render$8(_ctx, _cache) {
93
+ return openBlock(), createElementBlock("svg", _hoisted_1$p, _cache[0] || (_cache[0] = [
94
+ createElementVNode("path", {
95
+ d: "M5.29295 1.63605C5.10548 1.82358 5.00017 2.07788 5.00017 2.34305C5.00017 2.60821 5.10548 2.86252 5.29295 3.05005L10.243 8.00005L5.29295 12.95C5.11079 13.1387 5.01 13.3913 5.01228 13.6534C5.01456 13.9156 5.11972 14.1665 5.30513 14.3519C5.49054 14.5373 5.74135 14.6424 6.00355 14.6447C6.26575 14.647 6.51835 14.5462 6.70695 14.364L12.364 8.70705C12.5514 8.51952 12.6567 8.26521 12.6567 8.00005C12.6567 7.73488 12.5514 7.48058 12.364 7.29305L6.70695 1.63605C6.51942 1.44858 6.26512 1.34326 5.99995 1.34326C5.73479 1.34326 5.48048 1.44858 5.29295 1.63605Z",
96
+ fill: "currentColor"
97
+ }, null, -1)
98
+ ]));
99
+ }
100
+ const ChevronRightIcon = /* @__PURE__ */ _export_sfc(_sfc_main$w, [["render", _sfc_render$8]]);
4
101
  const findParent = (el, callback) => {
5
102
  if (callback(el)) return el;
6
103
  if (!el.parentElement) return null;
@@ -162,7 +259,8 @@ const useDraggableItem = () => {
162
259
  clonedItem = null;
163
260
  (_a = options.onEnd) == null ? void 0 : _a.call(options, e2);
164
261
  },
165
- type: "absolute"
262
+ type: "absolute",
263
+ prevent: false
166
264
  });
167
265
  };
168
266
  return drag;
@@ -216,16 +314,160 @@ class MultiMap {
216
314
  this._map.clear();
217
315
  }
218
316
  }
317
+ class PairMap {
318
+ constructor() {
319
+ this._map = /* @__PURE__ */ new Map();
320
+ }
321
+ set(keyA, keyB, value) {
322
+ const map = this._map.get(keyA);
323
+ if (map) {
324
+ map.set(keyB, value);
325
+ return;
326
+ }
327
+ this._map.set(keyA, /* @__PURE__ */ new Map([[keyB, value]]));
328
+ }
329
+ get(keyA, keyB) {
330
+ const map = this._map.get(keyA);
331
+ if (!map) return null;
332
+ return map.get(keyB) ?? null;
333
+ }
334
+ deletePair(keyA) {
335
+ this._map.delete(keyA);
336
+ }
337
+ delete(keyA, keyB) {
338
+ const map = this._map.get(keyA);
339
+ if (!map) return;
340
+ map.delete(keyB);
341
+ if (map.size === 0) {
342
+ this.deletePair(keyA);
343
+ }
344
+ }
345
+ clear() {
346
+ this._map.clear();
347
+ }
348
+ }
349
+ const dataMap = new PairMap();
350
+ const events = new MultiMap();
351
+ const getArgKey = (args) => {
352
+ return args.length === 0 ? "_default" : JSON.stringify(args);
353
+ };
354
+ const getEntryOrCreate = (request, args, defaultValue) => {
355
+ const argKey = getArgKey(args);
356
+ const existsValue = dataMap.get(request, argKey);
357
+ if (existsValue) return existsValue;
358
+ dataMap.set(request, argKey, defaultValue);
359
+ return defaultValue;
360
+ };
361
+ const useRequest = (request, ...args) => {
362
+ const defaultValue = dataMap.get(request, getArgKey(args));
363
+ const pending = shallowRef(defaultValue === null);
364
+ const data = shallowRef((defaultValue == null ? void 0 : defaultValue.data) ?? null);
365
+ const error = shallowRef(null);
366
+ let lastArgs = [];
367
+ const mutate = async (...args2) => {
368
+ error.value = null;
369
+ const returnDataValue = returnDataCallback == null ? void 0 : returnDataCallback(...args2);
370
+ if (returnDataValue !== void 0) {
371
+ data.value = returnDataValue;
372
+ return;
373
+ }
374
+ const entry = getEntryOrCreate(request, args2, { data: null, lastUpdate: -1 });
375
+ data.value = entry.data;
376
+ pending.value = entry === null;
377
+ lastArgs = args2;
378
+ try {
379
+ data.value = await makeRequestWithoutCache(entry, request, ...args2);
380
+ } catch (e) {
381
+ error.value = e;
382
+ } finally {
383
+ delete entry.promise;
384
+ pending.value = false;
385
+ }
386
+ };
387
+ const lazyMutate = async (...args2) => {
388
+ const entry = dataMap.get(request, getArgKey(args2));
389
+ if (entry !== null && entry.lastUpdate > 0 && Date.now() < entry.lastUpdate + 1e3 * 30) {
390
+ data.value = entry.data;
391
+ lastArgs = args2;
392
+ return;
393
+ }
394
+ mutate(...args2);
395
+ };
396
+ let returnDataCallback;
397
+ const setReturnData = (callback) => {
398
+ returnDataCallback = callback;
399
+ };
400
+ const mutateWithLastArgs = () => mutate(...lastArgs);
401
+ onMounted(() => {
402
+ lazyMutate(...args);
403
+ });
404
+ onMounted(() => {
405
+ events.add(request, mutateWithLastArgs);
406
+ });
407
+ onBeforeUnmount(() => {
408
+ events.remove(request, mutateWithLastArgs);
409
+ });
410
+ return { data, error, pending, mutate, lazyMutate, setReturnData };
411
+ };
412
+ const makeRequestWithoutCache = async (entry, request, ...args) => {
413
+ if (!entry.promise) {
414
+ const promise = (async () => {
415
+ const resp = await request(...args);
416
+ entry.data = resp;
417
+ entry.lastUpdate = Date.now();
418
+ delete entry.promise;
419
+ })();
420
+ entry.promise = promise;
421
+ }
422
+ await entry.promise;
423
+ return entry.data;
424
+ };
425
+ const getSearchFeed = (str, dotToSpace = true) => {
426
+ const reg = dotToSpace ? /[_\-,()]/g : /[_\-.,()]/g;
427
+ const arr = str.toLowerCase().replace(reg, " ").split(" ").filter((a) => a.length > 0);
428
+ return arr;
429
+ };
430
+ const compareSearchFeed = (source, target) => {
431
+ for (const str2 of target) {
432
+ let find = false;
433
+ for (const str of source) {
434
+ if (str.startsWith(str2)) {
435
+ find = true;
436
+ }
437
+ }
438
+ if (!find) return false;
439
+ }
440
+ return true;
441
+ };
442
+ const findByKeys = (source, keys, target) => {
443
+ return source.filter((_, index) => compareSearchFeed(keys[index], target));
444
+ };
445
+ const getValue = (item) => {
446
+ return typeof item === "function" ? item() : item.value;
447
+ };
448
+ const useSearch = (searchValue, data, keyExtractor) => {
449
+ const searchKeys = computed(() => {
450
+ var _a;
451
+ return ((_a = getValue(data)) == null ? void 0 : _a.map((item) => getSearchFeed(keyExtractor(item)))) ?? [];
452
+ });
453
+ const dataSearched = computed(() => {
454
+ const searchFeed = getSearchFeed(searchValue.value);
455
+ const currentData = getValue(data);
456
+ if (searchFeed.length === 0 || !currentData) return currentData;
457
+ return findByKeys(currentData, searchKeys.value, searchFeed);
458
+ });
459
+ return dataSearched;
460
+ };
219
461
  const listeners = new MultiMap();
220
462
  let hasEvent = false;
463
+ const handleKeyDownLayer = (e) => {
464
+ if (!listeners.has(e.code)) return;
465
+ const _listeners = listeners.get(e.code);
466
+ e.preventDefault();
467
+ const callback = _listeners[_listeners.length - 1];
468
+ callback(e);
469
+ };
221
470
  const useKeyDownLayer = (key, watcher, callback) => {
222
- const onKeyDown = (e) => {
223
- if (!listeners.has(e.code)) return;
224
- const _listeners = listeners.get(e.code);
225
- e.preventDefault();
226
- const callback2 = _listeners[_listeners.length - 1];
227
- callback2(e);
228
- };
229
471
  watch(watcher, (value) => {
230
472
  if (value) {
231
473
  listeners.add(key, callback);
@@ -233,11 +475,11 @@ const useKeyDownLayer = (key, watcher, callback) => {
233
475
  listeners.remove(key, callback);
234
476
  }
235
477
  if (listeners.size > 0 && !hasEvent) {
236
- document.addEventListener("keydown", onKeyDown);
478
+ document.addEventListener("keydown", handleKeyDownLayer);
237
479
  hasEvent = true;
238
480
  }
239
481
  if (listeners.size === 0) {
240
- document.removeEventListener("keydown", onKeyDown);
482
+ document.removeEventListener("keydown", handleKeyDownLayer);
241
483
  hasEvent = false;
242
484
  }
243
485
  }, { immediate: true });
@@ -250,300 +492,108 @@ class BlockDropEvent extends Event {
250
492
  this.content = content;
251
493
  }
252
494
  }
253
- const _hoisted_1$g = { class: "blocks-list" };
254
- const _hoisted_2$5 = { class: "page-editor-blocks__group" };
255
- const _hoisted_3$4 = { class: "title" };
256
- const _hoisted_4$4 = { class: "blocks-list__blocks" };
257
- const _hoisted_5$2 = ["onMousedown"];
258
- const _sfc_main$m = /* @__PURE__ */ defineComponent({
259
- __name: "BlocksList",
495
+ const _hoisted_1$o = {
496
+ key: 0,
497
+ class: "v-form-control__label"
498
+ };
499
+ const _hoisted_2$9 = {
500
+ key: 0,
501
+ class: "v-form-control__required-marker"
502
+ };
503
+ const _hoisted_3$7 = {
504
+ key: 1,
505
+ class: "v-form-control__outline"
506
+ };
507
+ const _hoisted_4$4 = {
508
+ key: 3,
509
+ class: "v-form-control__actions"
510
+ };
511
+ const _hoisted_5$2 = {
512
+ key: 0,
513
+ class: "v-form-control__error"
514
+ };
515
+ const _sfc_main$v = /* @__PURE__ */ defineComponent({
516
+ __name: "VFormControl",
260
517
  props: {
261
- blocks: {}
518
+ error: {},
519
+ label: {},
520
+ required: { type: Boolean },
521
+ disabled: { type: Boolean },
522
+ outline: { type: Boolean }
262
523
  },
263
524
  setup(__props) {
264
525
  const props = __props;
265
- const groupBlocks = computed(() => {
266
- const groups = new MultiMap();
267
- for (let block of props.blocks) {
268
- if (block.hidden || block.isDev) continue;
269
- groups.add(block.group ?? "default", block);
270
- }
271
- const output = [];
272
- for (let [groupName, blocks] of groups._map) {
273
- blocks.sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
274
- output.push({ name: groupName, blocks });
526
+ const error = computed(() => {
527
+ if (!props.error) return "";
528
+ const code = props.error["code"];
529
+ if (code) {
530
+ return props.error.message ?? "";
275
531
  }
276
- return output;
532
+ return props.error.message ?? "Произошла ошибка";
277
533
  });
278
- const groupNames = {
279
- default: "Доступные блоки",
280
- layout: "Макет"
281
- };
282
- const drag = useDraggableItem();
283
- const dragMode = inject("dragMode");
284
- const onItemMouseDown = (e, item) => {
285
- drag(e, {
286
- onStart(item2) {
287
- item2.classList.add("drag");
288
- document.body.classList.add("mousedrag");
289
- dragMode.value = true;
290
- },
291
- onEnd(e2) {
292
- var _a;
293
- document.body.classList.remove("mousedrag");
294
- (_a = e2.target) == null ? void 0 : _a.dispatchEvent(new BlockDropEvent(item));
295
- dragMode.value = false;
296
- }
297
- });
298
- };
299
534
  return (_ctx, _cache) => {
300
- return openBlock(), createElementBlock("div", _hoisted_1$g, [
301
- (openBlock(true), createElementBlock(Fragment, null, renderList(groupBlocks.value, (group) => {
302
- return openBlock(), createElementBlock("div", _hoisted_2$5, [
303
- createElementVNode("div", _hoisted_3$4, toDisplayString(groupNames[group.name] ?? group.name), 1),
304
- createElementVNode("div", _hoisted_4$4, [
305
- (openBlock(true), createElementBlock(Fragment, null, renderList(group.blocks, (item) => {
306
- return openBlock(), createElementBlock("button", {
307
- class: "blocks-list__block editor-component",
308
- key: item.id,
309
- onMousedown: ($event) => onItemMouseDown($event, item)
310
- }, toDisplayString(item.name), 41, _hoisted_5$2);
311
- }), 128))
312
- ])
313
- ]);
314
- }), 256))
315
- ]);
535
+ return openBlock(), createElementBlock("div", {
536
+ class: normalizeClass(["v-form-control", { error: !!props.error, disabled: props.disabled }])
537
+ }, [
538
+ !!props.label ? (openBlock(), createElementBlock("label", _hoisted_1$o, [
539
+ createTextVNode(toDisplayString(props.label), 1),
540
+ props.required ? (openBlock(), createElementBlock("span", _hoisted_2$9, "*")) : createCommentVNode("", true)
541
+ ])) : createCommentVNode("", true),
542
+ props.outline ? (openBlock(), createElementBlock("div", _hoisted_3$7, [
543
+ renderSlot(_ctx.$slots, "default")
544
+ ])) : renderSlot(_ctx.$slots, "default", { key: 2 }),
545
+ _ctx.$slots.actions ? (openBlock(), createElementBlock("div", _hoisted_4$4, [
546
+ renderSlot(_ctx.$slots, "actions")
547
+ ])) : createCommentVNode("", true),
548
+ createVNode(Transition, null, {
549
+ default: withCtx(() => [
550
+ !!props.error ? (openBlock(), createElementBlock("div", _hoisted_5$2, toDisplayString(error.value), 1)) : createCommentVNode("", true)
551
+ ]),
552
+ _: 1
553
+ })
554
+ ], 2);
316
555
  };
317
556
  }
318
557
  });
319
- const defaultImageSrc = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAMAAAANIilAAAAAUVBMVEUAAADy8vLy8vLy8vLy8vLv7+/v7+/x8fHz8/Py8vJtbW2fn5/h4eGvr6+wsLDq6uqoqKh+fn7Jycm4uLiOjo51dXWGhoaWlpbZ2dnAwMDY2NgSuPoLAAAACXRSTlMA38+/XyAQgH+A/hFhAAABBUlEQVRIx+3X3YqDMBCG4ala3XwxJv5E273/C90RlLAodBxPWup7IFF80BwYCRGVP7k5XFbQ3P1mVN3ujNkqdUmFUVdRpsc5mRNd+MLfhDu7LTxF2A/YbfQCbIHBbpqAIMBAb3ZyiP4lroF6I5frn4DrE9jBqXEPwCnxA2hZq3DdovUNawX2bPnOVff9ETwBD2NW7fgoxxbgZ626A+fEGGh4sOqIsWEtxlM6DZinz9oKcevT6YjIZtZC/Pvvwd3y/oc/DJemHyTYx7RkdEhjBwhWkpCWoQjYpYGHAuxH7DZ40dL7DHZb9/Z/jAtf+F1wrrcZVXpcUKnfGp3clHFFdpzmVUn0B/oSge0dVY8uAAAAAElFTkSuQmCC";
320
- const getDefaultValue = (schema) => {
321
- if (schema.default) return schema.default;
322
- if (schema.nullable) return null;
323
- if (schema.type === "object" && schema.format === "image") {
324
- return { src: defaultImageSrc, previewSrc: defaultImageSrc };
558
+ function tryOnScopeDispose(fn) {
559
+ if (getCurrentScope()) {
560
+ onScopeDispose(fn);
561
+ return true;
325
562
  }
326
- if (schema.type === "number" || schema.type === "integer") return 0;
327
- if (schema.type === "object") return {};
328
- if (schema.type === "array") return [];
329
- if (schema.type === "boolean") return false;
330
- return "";
331
- };
332
- const passDefaultValue = (state, schema) => {
333
- if (!schema) return state;
334
- if (schema.type === "object" && state) {
335
- for (let key in schema.properties) {
336
- if (!(key in state) && !schema.required.includes(key)) continue;
337
- state[key] = passDefaultValue(state[key], schema.properties[key]);
338
- }
339
- }
340
- return state ?? getDefaultValue(schema);
341
- };
342
- const walkTree = (blocks, callback) => {
343
- for (let block of blocks) {
344
- callback(block);
345
- if (!block.children) continue;
346
- if (Array.isArray(block.children)) {
347
- walkTree(block.children, callback);
348
- } else {
349
- for (let value of Object.values(block.children)) {
350
- walkTree(value, callback);
351
- }
352
- }
353
- }
354
- };
355
- const walkSchema = (obj, schema, callback) => {
356
- if (schema.type === "object") {
357
- if (!obj) {
358
- return;
359
- }
360
- for (let [key, value] of Object.entries(obj)) {
361
- const childSchema = schema.properties[key];
362
- if (!childSchema) continue;
363
- const isRequired = schema.required.includes(key);
364
- callback(value, childSchema, key, obj, isRequired);
365
- if (childSchema.type === "array" || childSchema.type === "object") {
366
- walkSchema(value, childSchema, callback);
367
- }
368
- }
369
- }
370
- if (schema.type === "array" && schema.items) {
371
- for (let value of obj) {
372
- callback(value, schema.items);
373
- if (schema.items.type === "array" || schema.items.type === "object") {
374
- walkSchema(value, schema.items, callback);
375
- }
376
- }
377
- }
378
- };
379
- const findBlock = (blocks, callback) => {
380
- for (let block of blocks) {
381
- if (callback(block)) {
382
- return block;
383
- }
384
- if (!block.children) continue;
385
- if (Array.isArray(block.children)) {
386
- const result = findBlock(block.children, callback);
387
- if (result) return result;
388
- } else {
389
- for (let value of Object.values(block.children)) {
390
- const result = findBlock(value, callback);
391
- if (result) return result;
392
- }
393
- }
394
- }
395
- return null;
396
- };
397
- const hasSlots = (block) => {
398
- return !!block.slots && Object.keys(block.slots).length > 0;
399
- };
400
- const hasMultipleSlots = (block) => {
401
- if (!block.slots || Object.keys(block.slots).length === 0) return false;
402
- return Object.keys(block.slots).length > 1 || Object.keys(block.slots)[0] !== "default";
403
- };
404
- const forEachChildren = (block, content, callback) => {
405
- if (!hasSlots(block)) {
406
- if (content.children) {
407
- delete content.children;
408
- }
409
- return;
410
- }
411
- if (hasMultipleSlots(block)) {
412
- if (!content.children) content.children = {};
413
- if (Array.isArray(content.children)) content.children = { default: content.children };
414
- for (let key in block.slots) {
415
- if (!content.children[key]) content.children[key] = [];
416
- callback(content.children[key]);
417
- }
418
- } else {
419
- if (!content.children) content.children = [];
420
- if (!Array.isArray(content.children)) content.children = content.children.default ?? [];
421
- callback(content.children);
422
- }
423
- };
424
- const deleteBlock = (blocks, target) => {
425
- let isDeleted = false;
426
- walkTree(blocks, (block) => {
427
- if (!block.children) return;
428
- if (Array.isArray(block.children)) {
429
- if (deleteFromArray(block.children, target)) {
430
- isDeleted = true;
431
- }
432
- } else {
433
- for (let children of Object.values(block.children)) {
434
- if (deleteFromArray(children, target)) {
435
- isDeleted = true;
436
- }
437
- }
438
- }
439
- });
440
- if (!isDeleted) {
441
- deleteFromArray(blocks, target);
442
- }
443
- };
444
- const createContentBlockChild = (blocksMap2, contentBlock, parent, index = -1) => {
445
- const parentBlock = blocksMap2.get(parent.blockId);
446
- if (!parentBlock.slots) return;
447
- if (Object.keys(parentBlock.slots).length === 1 && Object.keys(parentBlock.slots)[0] === "default") {
448
- if (!parent.children) parent.children = [];
449
- if (!Array.isArray(parent.children)) parent.children = parent.children.default ?? [];
450
- if (index < 0) {
451
- parent.children.push(contentBlock);
452
- } else {
453
- parent.children.splice(index, 0, contentBlock);
454
- }
455
- } else {
456
- if (!parent.children || Array.isArray(parent.children)) parent.children = {};
457
- if (index < 0) {
458
- const key = "default" in parentBlock.slots ? "default" : Object.keys(parentBlock.slots)[0];
459
- if (!parent.children[key]) parent.children[key] = [];
460
- parent.children[key].push(contentBlock);
461
- } else {
462
- let startIndex = 0;
463
- for (let children of Object.values(parent.children)) {
464
- if (index - startIndex <= children.length) {
465
- children.splice(index - startIndex, 0, contentBlock);
466
- }
467
- startIndex += children.length;
468
- }
469
- }
470
- }
471
- };
472
- const getBlockIndex = (parent, target) => {
473
- if (!parent.children) return -1;
474
- if (Array.isArray(parent.children)) {
475
- return parent.children.indexOf(target);
476
- } else {
477
- let startIndex = 0;
478
- for (let children of Object.values(parent.children)) {
479
- const index = children.indexOf(target);
480
- if (index >= 0) {
481
- return startIndex + index;
482
- }
483
- startIndex += children.length;
484
- }
485
- return -1;
486
- }
487
- };
488
- const createContentBlock = (block) => {
489
- const id = uid();
490
- return {
491
- id,
492
- blockId: block.id,
493
- data: {
494
- ...passDefaultValue({}, block.props),
495
- "data-block-id": id
496
- }
497
- };
498
- };
499
- const deleteFromArray = (arr, item) => {
500
- const index = arr.indexOf(item);
501
- if (index < 0) return false;
502
- arr.splice(index, 1);
503
- return true;
504
- };
505
- const uid = () => {
506
- return Math.trunc(Math.random() * 1e5).toString(16);
507
- };
508
- function tryOnScopeDispose(fn) {
509
- if (getCurrentScope()) {
510
- onScopeDispose(fn);
511
- return true;
512
- }
513
- return false;
514
- }
515
- function createEventHook() {
516
- const fns = /* @__PURE__ */ new Set();
517
- const off = (fn) => {
518
- fns.delete(fn);
519
- };
520
- const clear = () => {
521
- fns.clear();
522
- };
523
- const on = (fn) => {
524
- fns.add(fn);
525
- const offFn = () => off(fn);
526
- tryOnScopeDispose(offFn);
527
- return {
528
- off: offFn
529
- };
530
- };
531
- const trigger = (...args) => {
532
- return Promise.all(Array.from(fns).map((fn) => fn(...args)));
533
- };
534
- return {
535
- on,
536
- off,
537
- trigger,
538
- clear
539
- };
540
- }
541
- const isClient = typeof window !== "undefined" && typeof document !== "undefined";
542
- typeof WorkerGlobalScope !== "undefined" && globalThis instanceof WorkerGlobalScope;
543
- const isDef = (val) => typeof val !== "undefined";
544
- const toString = Object.prototype.toString;
545
- const isObject = (val) => toString.call(val) === "[object Object]";
546
- const noop = () => {
563
+ return false;
564
+ }
565
+ function createEventHook() {
566
+ const fns = /* @__PURE__ */ new Set();
567
+ const off = (fn) => {
568
+ fns.delete(fn);
569
+ };
570
+ const clear = () => {
571
+ fns.clear();
572
+ };
573
+ const on = (fn) => {
574
+ fns.add(fn);
575
+ const offFn = () => off(fn);
576
+ tryOnScopeDispose(offFn);
577
+ return {
578
+ off: offFn
579
+ };
580
+ };
581
+ const trigger = (...args) => {
582
+ return Promise.all(Array.from(fns).map((fn) => fn(...args)));
583
+ };
584
+ return {
585
+ on,
586
+ off,
587
+ trigger,
588
+ clear
589
+ };
590
+ }
591
+ const isClient = typeof window !== "undefined" && typeof document !== "undefined";
592
+ typeof WorkerGlobalScope !== "undefined" && globalThis instanceof WorkerGlobalScope;
593
+ const isDef = (val) => typeof val !== "undefined";
594
+ const toString = Object.prototype.toString;
595
+ const isObject = (val) => toString.call(val) === "[object Object]";
596
+ const noop = () => {
547
597
  };
548
598
  const hasOwn = (val, key) => Object.prototype.hasOwnProperty.call(val, key);
549
599
  function createFilterWrapper(filter, fn) {
@@ -645,18 +695,18 @@ function unrefElement(elRef) {
645
695
  }
646
696
  function useEventListener(...args) {
647
697
  let target;
648
- let events;
698
+ let events2;
649
699
  let listeners2;
650
700
  let options;
651
701
  if (typeof args[0] === "string" || Array.isArray(args[0])) {
652
- [events, listeners2, options] = args;
702
+ [events2, listeners2, options] = args;
653
703
  target = defaultWindow;
654
704
  } else {
655
- [target, events, listeners2, options] = args;
705
+ [target, events2, listeners2, options] = args;
656
706
  }
657
707
  if (!target)
658
708
  return noop;
659
- events = toArray(events);
709
+ events2 = toArray(events2);
660
710
  listeners2 = toArray(listeners2);
661
711
  const cleanups = [];
662
712
  const cleanup = () => {
@@ -675,7 +725,7 @@ function useEventListener(...args) {
675
725
  return;
676
726
  const optionsClone = isObject(options2) ? { ...options2 } : options2;
677
727
  cleanups.push(
678
- ...events.flatMap((event) => {
728
+ ...events2.flatMap((event) => {
679
729
  return listeners2.map((listener) => register(el, event, listener, optionsClone));
680
730
  })
681
731
  );
@@ -863,7 +913,7 @@ function useVModel(props, key, emit, options = {}) {
863
913
  }
864
914
  event = event || `update:${key.toString()}`;
865
915
  const cloneFn = (val) => !clone ? val : typeof clone === "function" ? clone(val) : cloneFnJSON(val);
866
- const getValue = () => isDef(props[key]) ? cloneFn(props[key]) : defaultValue;
916
+ const getValue2 = () => isDef(props[key]) ? cloneFn(props[key]) : defaultValue;
867
917
  const triggerEmit = (value) => {
868
918
  if (shouldEmit) {
869
919
  if (shouldEmit(value))
@@ -873,7 +923,7 @@ function useVModel(props, key, emit, options = {}) {
873
923
  }
874
924
  };
875
925
  if (passive) {
876
- const initialValue = getValue();
926
+ const initialValue = getValue2();
877
927
  const proxy = ref(initialValue);
878
928
  let isUpdating = false;
879
929
  watch(
@@ -898,7 +948,7 @@ function useVModel(props, key, emit, options = {}) {
898
948
  } else {
899
949
  return computed({
900
950
  get() {
901
- return getValue();
951
+ return getValue2();
902
952
  },
903
953
  set(value) {
904
954
  triggerEmit(value);
@@ -906,1306 +956,2284 @@ function useVModel(props, key, emit, options = {}) {
906
956
  });
907
957
  }
908
958
  }
909
- const margin = 8;
910
- const _sfc_main$l = /* @__PURE__ */ defineComponent({
911
- ...{
912
- inheritAttrs: false
913
- },
914
- __name: "VPopover",
959
+ const _hoisted_1$n = {
960
+ key: 0,
961
+ class: "v-input__start-adornment"
962
+ };
963
+ const _hoisted_2$8 = ["placeholder", "rows", "name"];
964
+ const _hoisted_3$6 = ["placeholder", "type", "name"];
965
+ const _hoisted_4$3 = {
966
+ key: 3,
967
+ class: "v-input__max-length"
968
+ };
969
+ const _sfc_main$u = /* @__PURE__ */ defineComponent({
970
+ __name: "VInput",
915
971
  props: {
916
- open: { type: Boolean },
917
- element: {},
918
- placement: {},
919
- offset: {},
920
- fitAnchor: { type: Boolean },
921
- class: {},
922
- anchorPosition: {}
972
+ modelValue: {},
973
+ multiline: { type: Boolean },
974
+ autofocus: { type: Boolean },
975
+ rows: {},
976
+ placeholder: {},
977
+ type: {},
978
+ name: {},
979
+ large: { type: Boolean },
980
+ maxLength: {},
981
+ prefix: {},
982
+ validator: { type: Function },
983
+ error: {},
984
+ label: {},
985
+ required: { type: Boolean },
986
+ disabled: { type: Boolean }
923
987
  },
924
- emits: ["update:open"],
988
+ emits: ["update:modelValue"],
925
989
  setup(__props, { emit: __emit }) {
926
990
  const props = __props;
927
991
  const emit = __emit;
928
- const popoverRef = ref();
929
- const position = ref({ top: 0, left: 0 });
930
- const origin = ref("center");
931
- const open = useVModel(props, "open", emit, { passive: true });
932
- const activatorElement = ref();
933
- const clamp = (value, min, max) => {
934
- if (value < min) return min;
935
- if (value > max) return max;
992
+ const parse = (value) => {
993
+ if (props.validator) {
994
+ return props.validator(value);
995
+ }
996
+ if (props.type === "number") {
997
+ const val = parseFloat(value);
998
+ if (isNaN(val)) return null;
999
+ return val;
1000
+ }
1001
+ if (props.type === "integer") {
1002
+ const val = parseInt(value);
1003
+ if (isNaN(val)) return null;
1004
+ return val;
1005
+ }
936
1006
  return value;
937
1007
  };
938
- const calcPrimary = (pos, start, end, size, min, max) => {
939
- const fitStart = start - size >= min;
940
- const fitEnd = end + size <= max;
941
- if ((!fitEnd || pos === "start") && fitStart) return start - size;
942
- if ((!fitStart || pos === "end") && fitEnd) return end;
943
- return pos === "start" ? min : max - size;
944
- };
945
- const calcSub = (pos, start, end, size, min, max) => {
946
- if (pos === "start") return clamp(start, min, max - size);
947
- if (pos === "end") return clamp(end - size, min, max - size);
948
- return clamp((start + end) / 2 - size / 2, min, max - size);
949
- };
950
- const calcOrigin = (start, end, point) => {
951
- return clamp(Math.round((point - start) / (end - start) * 100), 0, 100) + "%";
952
- };
953
- const getRect = () => {
954
- if (props.anchorPosition) {
955
- return {
956
- top: props.anchorPosition.y,
957
- bottom: props.anchorPosition.y,
958
- left: props.anchorPosition.x,
959
- right: props.anchorPosition.x,
960
- width: 0,
961
- height: 0
962
- };
963
- }
964
- const element = props.element ?? activatorElement.value;
965
- if (!element) return null;
966
- return element.getBoundingClientRect();
967
- };
968
- const isHorizontal = computed(() => props.placement.startsWith("left") || props.placement.startsWith("right"));
969
- const calcPosition = () => {
970
- if (!popoverRef.value) return;
971
- const rect = getRect();
972
- if (!rect) return;
973
- const placement = props.placement.split("-");
974
- const offset = props.offset ?? 0;
975
- const width = popoverRef.value.clientWidth;
976
- const height = popoverRef.value.clientHeight;
977
- if (placement[0] === "top" || placement[0] === "bottom") {
978
- const top = calcPrimary(placement[0] === "top" ? "start" : "end", rect.top - offset, rect.bottom + offset, height, margin, window.innerHeight - margin);
979
- if (props.fitAnchor) {
980
- position.value = {
981
- top,
982
- left: calcSub("start", rect.left, rect.right, rect.width, margin, window.innerWidth - margin),
983
- width: rect.width
984
- };
985
- } else {
986
- position.value = { top, left: calcSub(placement[1], rect.left, rect.right, width, margin, window.innerWidth - margin) };
987
- }
988
- } else {
989
- const left = calcPrimary(placement[0] === "left" ? "start" : "end", rect.left - offset, rect.right + offset, width, margin, window.innerWidth - margin);
990
- if (props.fitAnchor) {
991
- position.value = {
992
- left,
993
- top: calcSub("start", rect.top, rect.bottom, rect.height, margin, window.innerHeight - margin),
994
- height: rect.height
995
- };
996
- } else {
997
- position.value = { left, top: calcSub(placement[1], rect.top, rect.bottom, height, margin, window.innerHeight - margin) };
998
- }
999
- }
1000
- origin.value = calcOrigin(position.value.left, position.value.left + width, rect.left + rect.width / 2) + calcOrigin(position.value.top, position.value.top + height, rect.top + rect.height / 2);
1001
- };
1002
- watch([() => props.element, () => props.anchorPosition], () => {
1003
- calcPosition();
1008
+ let lastValue = "";
1009
+ const model = ref("");
1010
+ watch(() => props.modelValue, (value) => {
1011
+ if (value === lastValue) return;
1012
+ model.value = (value ?? "").toString();
1013
+ }, { immediate: true });
1014
+ watch(() => model.value, (modelValue) => {
1015
+ const val = parse(modelValue);
1016
+ lastValue = val;
1017
+ emit("update:modelValue", val);
1004
1018
  });
1005
- useResizeObserver(popoverRef, calcPosition);
1006
- useEventListener(window, "resize", calcPosition);
1007
- const close = () => {
1008
- open.value = false;
1009
- };
1010
- const closeDelayed = () => {
1011
- setTimeout(close, 0);
1012
- };
1013
- useKeyDownLayer("Escape", open, close);
1014
- useMouseDownOutside(open, closeDelayed, popoverRef);
1015
- watch(open, (open2) => {
1016
- if (!props.element) return;
1017
- if (open2) {
1018
- props.element.classList.add("popoverHover");
1019
- } else {
1020
- props.element.classList.remove("popoverHover");
1019
+ const error = computed(() => {
1020
+ if ((props.type === "number" || props.type === "integer") && model.value && props.modelValue === null) {
1021
+ return { message: "Введите числовое значение" };
1021
1022
  }
1023
+ return props.error;
1022
1024
  });
1023
- const activatorProps = {
1024
- onMousedown: (e) => {
1025
- open.value = !open.value;
1026
- if (open.value) {
1027
- activatorElement.value = e.currentTarget;
1028
- }
1029
- },
1030
- onTouchstart: (e) => {
1031
- open.value = !open.value;
1032
- if (open.value) {
1033
- activatorElement.value = e.currentTarget;
1034
- }
1025
+ const inputType = computed(() => {
1026
+ if (props.type !== "phone" && props.type !== "number" && props.type !== "integer") return props.type;
1027
+ return void 0;
1028
+ });
1029
+ const inputRef = ref();
1030
+ onMounted(() => {
1031
+ var _a;
1032
+ if (props.autofocus || props.error) {
1033
+ (_a = inputRef.value) == null ? void 0 : _a.focus();
1035
1034
  }
1036
- };
1037
- const style = computed(() => {
1038
- return {
1039
- left: position.value.left + "px",
1040
- top: position.value.top + "px",
1041
- width: position.value.width ? position.value.width + "px" : void 0,
1042
- height: position.value.height ? position.value.height + "px" : void 0,
1043
- transformOrigin: origin.value
1044
- };
1045
1035
  });
1036
+ if (props.multiline) {
1037
+ useTextareaAutosize({ element: inputRef, input: model });
1038
+ }
1046
1039
  return (_ctx, _cache) => {
1047
- return openBlock(), createElementBlock(Fragment, null, [
1048
- (openBlock(), createBlock(Teleport, { to: "body" }, [
1049
- createVNode(Transition, null, {
1050
- default: withCtx(() => [
1051
- unref(open) ? (openBlock(), createElementBlock("div", mergeProps({ key: 0 }, _ctx.$attrs, {
1052
- class: ["v-popover editor-component", [isHorizontal.value ? "horizontal" : "vertical", props.fitAnchor && "fit-anchor", props.class]],
1053
- style: style.value,
1054
- ref_key: "popoverRef",
1055
- ref: popoverRef,
1056
- onMousedown: _cache[0] || (_cache[0] = withModifiers(() => {
1057
- }, ["stop"]))
1058
- }), [
1059
- renderSlot(_ctx.$slots, "default")
1060
- ], 16)) : createCommentVNode("", true)
1061
- ]),
1062
- _: 3
1063
- })
1064
- ])),
1065
- renderSlot(_ctx.$slots, "activator", { props: activatorProps })
1066
- ], 64);
1040
+ return openBlock(), createBlock(_sfc_main$v, {
1041
+ class: normalizeClass(["v-input", { large: _ctx.large, multiline: _ctx.multiline }]),
1042
+ error: error.value,
1043
+ label: _ctx.label,
1044
+ required: _ctx.required,
1045
+ disabled: _ctx.disabled,
1046
+ outline: ""
1047
+ }, createSlots({
1048
+ default: withCtx(() => [
1049
+ renderSlot(_ctx.$slots, "start-adornment"),
1050
+ props.prefix ? (openBlock(), createElementBlock("div", _hoisted_1$n, toDisplayString(props.prefix), 1)) : createCommentVNode("", true),
1051
+ props.multiline ? withDirectives((openBlock(), createElementBlock("textarea", {
1052
+ key: 1,
1053
+ ref_key: "inputRef",
1054
+ ref: inputRef,
1055
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => model.value = $event),
1056
+ placeholder: props.placeholder,
1057
+ rows: props.rows,
1058
+ class: "scroll",
1059
+ name: props.name
1060
+ }, null, 8, _hoisted_2$8)), [
1061
+ [vModelText, model.value]
1062
+ ]) : withDirectives((openBlock(), createElementBlock("input", {
1063
+ key: 2,
1064
+ ref_key: "inputRef",
1065
+ ref: inputRef,
1066
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => model.value = $event),
1067
+ placeholder: props.placeholder,
1068
+ type: inputType.value,
1069
+ name: props.name
1070
+ }, null, 8, _hoisted_3$6)), [
1071
+ [vModelDynamic, model.value]
1072
+ ]),
1073
+ props.maxLength ? (openBlock(), createElementBlock("div", _hoisted_4$3, toDisplayString(model.value.length) + " / " + toDisplayString(props.maxLength), 1)) : createCommentVNode("", true),
1074
+ renderSlot(_ctx.$slots, "end-adornment")
1075
+ ]),
1076
+ _: 2
1077
+ }, [
1078
+ _ctx.$slots.actions ? {
1079
+ name: "actions",
1080
+ fn: withCtx(() => [
1081
+ renderSlot(_ctx.$slots, "actions")
1082
+ ]),
1083
+ key: "0"
1084
+ } : void 0
1085
+ ]), 1032, ["error", "label", "required", "disabled", "class"]);
1067
1086
  };
1068
1087
  }
1069
1088
  });
1070
- const _sfc_main$k = /* @__PURE__ */ defineComponent({
1071
- __name: "VButton",
1089
+ const _hoisted_1$m = { class: "blocks-list" };
1090
+ const _hoisted_2$7 = { class: "page-editor-blocks__group" };
1091
+ const _hoisted_3$5 = { class: "title" };
1092
+ const _hoisted_4$2 = { class: "blocks-list__blocks" };
1093
+ const _hoisted_5$1 = ["onMousedown"];
1094
+ const _hoisted_6$1 = {
1095
+ key: 0,
1096
+ class: "page-editor__nothing-found"
1097
+ };
1098
+ const _sfc_main$t = /* @__PURE__ */ defineComponent({
1099
+ __name: "BlocksList",
1072
1100
  props: {
1073
- component: {},
1074
- disabled: { type: Boolean },
1075
- flat: { type: Boolean },
1076
- outline: { type: Boolean },
1077
- large: { type: Boolean }
1101
+ blocks: {}
1078
1102
  },
1079
1103
  setup(__props) {
1104
+ const props = __props;
1105
+ const searchValue = ref("");
1106
+ const filteredBlocks = useSearch(searchValue, () => props.blocks, (item) => item.name + " " + item.id);
1107
+ const groupBlocks = computed(() => {
1108
+ const groups = new MultiMap();
1109
+ for (let block of filteredBlocks.value) {
1110
+ if (block.hidden || block.isDev) continue;
1111
+ groups.add(block.group ?? "default", block);
1112
+ }
1113
+ const output = [];
1114
+ for (let [groupName, blocks] of groups._map) {
1115
+ blocks.sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
1116
+ output.push({ name: groupName, blocks });
1117
+ }
1118
+ return output;
1119
+ });
1120
+ const groupNames = {
1121
+ default: "Доступные блоки",
1122
+ layout: "Макет"
1123
+ };
1124
+ const drag = useDraggableItem();
1125
+ const dragMode = inject("dragMode");
1126
+ const onItemMouseDown = (e, item) => {
1127
+ drag(e, {
1128
+ onStart(item2) {
1129
+ item2.classList.add("drag");
1130
+ document.body.classList.add("mousedrag");
1131
+ dragMode.value = true;
1132
+ },
1133
+ onEnd(e2) {
1134
+ var _a;
1135
+ document.body.classList.remove("mousedrag");
1136
+ (_a = e2.target) == null ? void 0 : _a.dispatchEvent(new BlockDropEvent(item));
1137
+ dragMode.value = false;
1138
+ }
1139
+ });
1140
+ };
1080
1141
  return (_ctx, _cache) => {
1081
- return openBlock(), createBlock(resolveDynamicComponent(_ctx.component ?? "button"), {
1082
- class: normalizeClass(["v-button", { disabled: _ctx.disabled, flat: _ctx.flat, outline: _ctx.outline, large: _ctx.large }])
1083
- }, {
1084
- default: withCtx(() => [
1085
- renderSlot(_ctx.$slots, "default")
1086
- ]),
1087
- _: 3
1088
- }, 8, ["class"]);
1142
+ return openBlock(), createElementBlock("div", _hoisted_1$m, [
1143
+ createVNode(_sfc_main$u, {
1144
+ modelValue: searchValue.value,
1145
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => searchValue.value = $event),
1146
+ placeholder: "Поиск...",
1147
+ class: "page-editor-blocks__search"
1148
+ }, null, 8, ["modelValue"]),
1149
+ (openBlock(true), createElementBlock(Fragment, null, renderList(groupBlocks.value, (group) => {
1150
+ return openBlock(), createElementBlock("div", _hoisted_2$7, [
1151
+ createElementVNode("div", _hoisted_3$5, toDisplayString(groupNames[group.name] ?? group.name), 1),
1152
+ createElementVNode("div", _hoisted_4$2, [
1153
+ (openBlock(true), createElementBlock(Fragment, null, renderList(group.blocks, (item) => {
1154
+ return openBlock(), createElementBlock("button", {
1155
+ class: "blocks-list__block editor-component",
1156
+ key: item.id,
1157
+ onMousedown: ($event) => onItemMouseDown($event, item)
1158
+ }, toDisplayString(item.name), 41, _hoisted_5$1);
1159
+ }), 128))
1160
+ ])
1161
+ ]);
1162
+ }), 256)),
1163
+ unref(filteredBlocks).length === 0 ? (openBlock(), createElementBlock("div", _hoisted_6$1, "Блоки не найдены")) : createCommentVNode("", true)
1164
+ ]);
1089
1165
  };
1090
1166
  }
1091
1167
  });
1092
- const useContextMenu = (creator) => {
1093
- let target = null;
1094
- const props = reactive({
1095
- items: [],
1096
- open: false,
1097
- anchorPosition: { x: 0, y: 0 },
1098
- "onUpdate:open": (value) => {
1099
- if (value === false && target !== null) {
1100
- target.removeAttribute("data-popover-target");
1101
- target = null;
1168
+ const defaultImageSrc = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2NCIgaGVpZ2h0PSI2NCIgZmlsbD0ibm9uZSI+PHJlY3Qgd2lkdGg9IjY0IiBoZWlnaHQ9IjY0IiBmaWxsPSIjRjJGMkYyIiByeD0iOCIvPjxwYXRoIGZpbGw9IiM2RDZENkQiIGQ9Ik00MS42IDE5LjZIMjIuNEE0LjQgNC40IDAgMCAwIDE4IDI0djE2YTQuNCA0LjQgMCAwIDAgNC40IDQuNGgxOS4yQTQuNCA0LjQgMCAwIDAgNDYgNDBWMjRhNC40IDQuNCAwIDAgMC00LjQtNC40TTIyLjQgMjJoMTkuMmEyIDIgMCAwIDEgMiAydjEzLjEwNGwtNC4zNTItNC4zNTJhMS4xMiAxLjEyIDAgMCAwLS44OTYtLjM1MiAxLjI4IDEuMjggMCAwIDAtLjg4LjQzMmwtMi4wNjQgMi40OC03LjM2LTcuMzZhMS4xMiAxLjEyIDAgMCAwLS44NDgtLjM1MiAxLjI4IDEuMjggMCAwIDAtLjg4LjQzMmwtNS45MiA3LjA1NlYyNGEyIDIgMCAwIDEgMi0ybS0yIDE4di0xLjE2OGw2Ljg4LTguMjU2IDYuNTkyIDYuNTkyLTQuMDMyIDQuOEgyMi40YTIgMiAwIDAgMS0yLTEuOTY4bTIxLjIgMmgtOC42NGw1LjUyLTYuNjI0IDUuMDQgNS4wNEExLjk3IDEuOTcgMCAwIDEgNDEuNiA0MiIvPjwvc3ZnPg==";
1169
+ const getDefaultValue = (schema) => {
1170
+ if (schema.default) return schema.default;
1171
+ if (schema.nullable) return null;
1172
+ if (schema.type === "object" && schema.format === "image") {
1173
+ return { src: defaultImageSrc, previewSrc: defaultImageSrc };
1174
+ }
1175
+ if (schema.type === "number" || schema.type === "integer") return 0;
1176
+ if (schema.type === "object") {
1177
+ if (!schema.properties) return {};
1178
+ return Object.fromEntries(Object.entries(schema.properties).map(([key, value]) => {
1179
+ var _a;
1180
+ if (!((_a = schema.required) == null ? void 0 : _a.includes(key))) {
1181
+ return [key, void 0];
1102
1182
  }
1103
- props.open = value;
1183
+ return [key, getDefaultValue(value)];
1184
+ }));
1185
+ }
1186
+ if (schema.type === "array") return [];
1187
+ if (schema.type === "boolean") return false;
1188
+ return "";
1189
+ };
1190
+ const processBlock = (contentBlock, schema) => {
1191
+ if (!contentBlock.id) {
1192
+ contentBlock.id = uid();
1193
+ }
1194
+ if (!contentBlock.data) {
1195
+ contentBlock.data = {};
1196
+ }
1197
+ contentBlock.data["data-block-id"] = contentBlock.id;
1198
+ if (schema) {
1199
+ walkSchema(contentBlock.data, schema.props, (value, schema2, key, parent, isRequired) => {
1200
+ if (key && isRequired && !schema2.nullable && (value === null || value === void 0)) {
1201
+ parent[key] = getDefaultValue(schema2);
1202
+ }
1203
+ });
1204
+ if (schema.slots) {
1205
+ if (Object.keys(schema.slots).join() === "default") {
1206
+ contentBlock.children = [];
1207
+ } else {
1208
+ contentBlock.children = Object.fromEntries(Object.keys(schema.slots).map((key) => [key, []]));
1209
+ }
1210
+ onUpdateBlockChildren(contentBlock);
1211
+ }
1212
+ }
1213
+ return contentBlock;
1214
+ };
1215
+ const saveBlock = (contentBlock, schema) => {
1216
+ if (contentBlock.children) {
1217
+ if (Array.isArray(contentBlock.children)) {
1218
+ contentBlock.children = contentBlock.children.filter((item) => !item.blockId.startsWith("__dev"));
1219
+ } else {
1220
+ for (let key in contentBlock.children) {
1221
+ contentBlock.children[key] = contentBlock.children[key].filter((item) => !item.blockId.startsWith("__dev"));
1222
+ }
1223
+ }
1224
+ }
1225
+ if (!contentBlock.data) return;
1226
+ delete contentBlock.data["data-block-id"];
1227
+ if (!schema) return;
1228
+ walkSchema(contentBlock.data, schema.props, (value, schema2, key, parent) => {
1229
+ if (schema2.type === "object" && schema2.format === "image" && value.src === defaultImageSrc && key && parent) {
1230
+ parent[key] = null;
1104
1231
  }
1105
1232
  });
1106
- const open = (e, ...args) => {
1107
- e.preventDefault();
1108
- props.items = creator(...args);
1109
- props.anchorPosition = { x: e.clientX, y: e.clientY };
1110
- props.open = true;
1111
- if (target !== null) {
1112
- target.removeAttribute("data-popover-target");
1113
- target = null;
1233
+ };
1234
+ const processBlocks = (state, blocksMap2) => {
1235
+ walkTree(state, (block) => {
1236
+ processBlock(block, blocksMap2.get(block.blockId));
1237
+ });
1238
+ return state;
1239
+ };
1240
+ const saveBlocks = (state, blocksMap2) => {
1241
+ walkTree(state, (block) => {
1242
+ saveBlock(block, blocksMap2.get(block.blockId));
1243
+ });
1244
+ return state;
1245
+ };
1246
+ const splitData = (data, scopes) => {
1247
+ const groupedData = { "site": {}, "folder": {}, "page": {} };
1248
+ for (let [key, scope] of Object.entries(scopes)) {
1249
+ groupedData[scope][key] = data[key];
1250
+ }
1251
+ return groupedData;
1252
+ };
1253
+ const walkTree = (blocks, callback) => {
1254
+ for (let block of blocks) {
1255
+ callback(block);
1256
+ if (!block.children) continue;
1257
+ if (Array.isArray(block.children)) {
1258
+ walkTree(block.children, callback);
1259
+ } else {
1260
+ for (let value of Object.values(block.children)) {
1261
+ walkTree(value, callback);
1262
+ }
1114
1263
  }
1115
- target = e.currentTarget;
1116
- target.setAttribute("data-popover-target", "true");
1117
- };
1118
- return {
1119
- props,
1120
- open
1121
- };
1264
+ }
1122
1265
  };
1123
- const _sfc_main$j = /* @__PURE__ */ defineComponent({
1124
- __name: "VContextMenu",
1266
+ const walkSchema = (obj, schema, callback) => {
1267
+ if (schema.type === "object") {
1268
+ if (!obj) {
1269
+ return;
1270
+ }
1271
+ for (let [key, childSchema] of Object.entries(schema.properties)) {
1272
+ const isRequired = schema.required.includes(key);
1273
+ callback(obj[key], childSchema, key, obj, isRequired);
1274
+ if (childSchema.type === "array" || childSchema.type === "object") {
1275
+ walkSchema(obj[key], childSchema, callback);
1276
+ }
1277
+ }
1278
+ }
1279
+ if (schema.type === "array" && schema.items) {
1280
+ for (let value of obj) {
1281
+ callback(value, schema.items);
1282
+ if (schema.items.type === "array" || schema.items.type === "object") {
1283
+ walkSchema(value, schema.items, callback);
1284
+ }
1285
+ }
1286
+ }
1287
+ };
1288
+ const findBlock = (blocks, callback) => {
1289
+ for (let block of blocks) {
1290
+ if (callback(block)) {
1291
+ return block;
1292
+ }
1293
+ if (!block.children) continue;
1294
+ if (Array.isArray(block.children)) {
1295
+ const result = findBlock(block.children, callback);
1296
+ if (result) return result;
1297
+ } else {
1298
+ for (let value of Object.values(block.children)) {
1299
+ const result = findBlock(value, callback);
1300
+ if (result) return result;
1301
+ }
1302
+ }
1303
+ }
1304
+ return null;
1305
+ };
1306
+ const hasSlots = (block) => {
1307
+ return !!block.slots && Object.keys(block.slots).length > 0;
1308
+ };
1309
+ const hasMultipleSlots = (block) => {
1310
+ if (!block.slots || Object.keys(block.slots).length === 0) return false;
1311
+ return Object.keys(block.slots).join() !== "default";
1312
+ };
1313
+ const forEachChildren = (block, content, callback) => {
1314
+ if (!hasSlots(block)) {
1315
+ if (content.children) {
1316
+ delete content.children;
1317
+ }
1318
+ return;
1319
+ }
1320
+ if (hasMultipleSlots(block)) {
1321
+ if (!content.children) content.children = {};
1322
+ if (Array.isArray(content.children)) content.children = { default: content.children };
1323
+ for (let key in block.slots) {
1324
+ if (!content.children[key]) content.children[key] = [];
1325
+ callback(content.children[key]);
1326
+ }
1327
+ } else {
1328
+ if (!content.children) content.children = [];
1329
+ if (!Array.isArray(content.children)) content.children = content.children.default ?? [];
1330
+ callback(content.children);
1331
+ }
1332
+ };
1333
+ const deleteBlock = (blocks, target) => {
1334
+ let isDeleted = false;
1335
+ walkTree(blocks, (block) => {
1336
+ if (!block.children) return;
1337
+ if (Array.isArray(block.children)) {
1338
+ if (deleteFromArray(block.children, target)) {
1339
+ isDeleted = true;
1340
+ onUpdateBlockChildren(block);
1341
+ }
1342
+ } else {
1343
+ for (let children of Object.values(block.children)) {
1344
+ if (deleteFromArray(children, target)) {
1345
+ isDeleted = true;
1346
+ onUpdateBlockChildren(block);
1347
+ }
1348
+ }
1349
+ }
1350
+ });
1351
+ if (!isDeleted) {
1352
+ deleteFromArray(blocks, target);
1353
+ }
1354
+ };
1355
+ const createContentBlockChild = (blocksMap2, contentBlock, parent, index = -1) => {
1356
+ const parentBlock = blocksMap2.get(parent.blockId);
1357
+ if (!parentBlock.slots) return;
1358
+ if (Object.keys(parentBlock.slots).join() === "default") {
1359
+ if (!parent.children) parent.children = [];
1360
+ if (!Array.isArray(parent.children)) parent.children = parent.children.default ?? [];
1361
+ if (index < 0) {
1362
+ parent.children.push(contentBlock);
1363
+ } else {
1364
+ parent.children.splice(index, 0, contentBlock);
1365
+ }
1366
+ } else {
1367
+ if (!parent.children || Array.isArray(parent.children)) parent.children = {};
1368
+ if (index < 0) {
1369
+ const key = "default" in parentBlock.slots ? "default" : Object.keys(parentBlock.slots)[0];
1370
+ if (!parent.children[key]) parent.children[key] = [];
1371
+ parent.children[key].push(contentBlock);
1372
+ } else {
1373
+ let startIndex = 0;
1374
+ for (let children of Object.values(parent.children)) {
1375
+ if (index - startIndex <= children.length) {
1376
+ children.splice(index - startIndex, 0, contentBlock);
1377
+ }
1378
+ startIndex += children.length;
1379
+ }
1380
+ }
1381
+ }
1382
+ onUpdateBlockChildren(parent);
1383
+ };
1384
+ const getBlockIndex = (parent, target) => {
1385
+ if (!parent.children) return -1;
1386
+ if (Array.isArray(parent.children)) {
1387
+ return parent.children.indexOf(target);
1388
+ } else {
1389
+ let startIndex = 0;
1390
+ for (let children of Object.values(parent.children)) {
1391
+ const index = children.indexOf(target);
1392
+ if (index >= 0) {
1393
+ return startIndex + index;
1394
+ }
1395
+ startIndex += children.length;
1396
+ }
1397
+ return -1;
1398
+ }
1399
+ };
1400
+ const createContentBlock = (block) => {
1401
+ const id = uid();
1402
+ return processBlock({ id, blockId: block.id, data: {} }, block);
1403
+ };
1404
+ const insertBlockBefore = (block, contentBlocks, prependBlockId) => {
1405
+ const contentBlock = createContentBlock(block);
1406
+ if (!prependBlockId) {
1407
+ contentBlocks.push(contentBlock);
1408
+ } else {
1409
+ const index = contentBlocks.findIndex((item) => item.id === prependBlockId);
1410
+ if (index < 0) {
1411
+ contentBlocks.push(contentBlock);
1412
+ } else {
1413
+ contentBlocks.splice(index, 0, contentBlock);
1414
+ }
1415
+ }
1416
+ return contentBlock;
1417
+ };
1418
+ const _onUpdateBlockChildren = (children) => {
1419
+ if (children.length === 0) {
1420
+ children.push(createDevBlock());
1421
+ } else {
1422
+ const index = children.findIndex((item) => item.blockId === "__dev-block");
1423
+ if (index >= 0) {
1424
+ children.splice(index, 1);
1425
+ }
1426
+ }
1427
+ };
1428
+ const onUpdateBlockChildren = (block) => {
1429
+ if (!block.children) return;
1430
+ if (Array.isArray(block.children)) {
1431
+ _onUpdateBlockChildren(block.children);
1432
+ } else {
1433
+ for (let children of Object.values(block.children)) {
1434
+ _onUpdateBlockChildren(children);
1435
+ }
1436
+ }
1437
+ };
1438
+ const changeBlockId = (content, schema) => {
1439
+ content.id = uid();
1440
+ processBlock(content);
1441
+ forEachChildren(schema, content, (contents) => {
1442
+ for (let content2 of contents) {
1443
+ content2.id = uid();
1444
+ processBlock(content2);
1445
+ }
1446
+ });
1447
+ };
1448
+ const createDevBlock = () => {
1449
+ const id = uid();
1450
+ const style = `
1451
+ min-width: 60px;
1452
+ min-height: 60px;
1453
+ background-color: #0073E920;
1454
+ background-image: url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' rx='4' ry='4' stroke='%230073E9FF' stroke-width='4' stroke-dasharray='6%2c 14' stroke-dashoffset='0' stroke-linecap='square'/%3e%3c/svg%3e");
1455
+ border-radius: 4px;
1456
+ `;
1457
+ return { id, data: {}, blockId: "__dev-block", vnode: h("div", { class: "dev-empty-slot-block", style }) };
1458
+ };
1459
+ const deleteFromArray = (arr, item) => {
1460
+ const index = arr.indexOf(item);
1461
+ if (index < 0) return false;
1462
+ arr.splice(index, 1);
1463
+ return true;
1464
+ };
1465
+ const uid = () => {
1466
+ return Math.trunc(Math.random() * 1e5).toString(16);
1467
+ };
1468
+ const _hoisted_1$l = ["onClick"];
1469
+ const _sfc_main$s = /* @__PURE__ */ defineComponent({
1470
+ __name: "VTabs",
1125
1471
  props: {
1126
- open: { type: Boolean },
1127
- placement: {},
1128
- anchorPosition: {},
1129
- offset: {},
1130
- items: { type: [Array, Function] }
1472
+ items: {},
1473
+ modelValue: {}
1131
1474
  },
1132
- emits: ["update:open"],
1475
+ emits: ["update:modelValue"],
1133
1476
  setup(__props, { emit: __emit }) {
1134
1477
  const props = __props;
1135
- const activatorElement = ref();
1136
1478
  const emit = __emit;
1137
- const open = useVModel(props, "open", emit, { passive: true });
1138
- const items = shallowRef([]);
1139
- watch(open, (open2) => {
1140
- if (!open2) return;
1141
- const _items = typeof props.items === "function" ? props.items() : props.items;
1142
- items.value = _items.filter((item) => !!item);
1143
- });
1144
- const activatorProps = {
1145
- onClick: (e) => {
1146
- open.value = true;
1147
- activatorElement.value = e.currentTarget;
1479
+ const model = useVModel(props, "modelValue", emit, { passive: true });
1480
+ watch(() => props.items, (items) => {
1481
+ if ((model.value === void 0 || model.value === null) && items.length > 0) {
1482
+ model.value = items[0].id;
1148
1483
  }
1149
- };
1150
- const onItemClick = (item) => {
1151
- var _a, _b;
1152
- if (item.onClick) {
1153
- item.onClick();
1154
- open.value = false;
1484
+ }, { immediate: true });
1485
+ const tabsRef = ref();
1486
+ const markerStyle = ref({});
1487
+ const placeMarker = () => {
1488
+ const id = model.value;
1489
+ if (!tabsRef.value) return;
1490
+ const index = props.items.findIndex((item) => item.id === id);
1491
+ if (index < 0) {
1492
+ markerStyle.value = { width: "0px" };
1493
+ return;
1155
1494
  }
1156
- if (((_a = item.props) == null ? void 0 : _a.to) || ((_b = item.props) == null ? void 0 : _b.href)) {
1157
- open.value = false;
1495
+ const child = tabsRef.value.children[index];
1496
+ const p = 0;
1497
+ markerStyle.value = { left: child.offsetLeft + p + "px", width: child.clientWidth - p * 2 + "px" };
1498
+ for (let child2 of tabsRef.value.children) {
1499
+ const item = child2;
1500
+ item.style.left = item.offsetLeft + "px";
1158
1501
  }
1159
1502
  };
1503
+ onMounted(() => {
1504
+ placeMarker();
1505
+ });
1506
+ watch(() => props.items, () => {
1507
+ placeMarker();
1508
+ }, { deep: true, flush: "post" });
1509
+ watch(model, placeMarker, { flush: "post" });
1160
1510
  return (_ctx, _cache) => {
1161
- return openBlock(), createElementBlock(Fragment, null, [
1162
- renderSlot(_ctx.$slots, "activator", { props: activatorProps }),
1163
- createVNode(_sfc_main$l, {
1164
- open: unref(open),
1165
- "onUpdate:open": _cache[0] || (_cache[0] = ($event) => isRef(open) ? open.value = $event : null),
1166
- element: activatorElement.value,
1167
- anchorPosition: props.anchorPosition,
1168
- placement: props.placement ?? "bottom-start",
1169
- offset: _ctx.offset,
1170
- class: "v-context-menu"
1171
- }, {
1511
+ return openBlock(), createElementBlock("div", {
1512
+ ref_key: "tabsRef",
1513
+ ref: tabsRef,
1514
+ class: "v-tabs"
1515
+ }, [
1516
+ createVNode(TransitionGroup, null, {
1172
1517
  default: withCtx(() => [
1173
- (openBlock(true), createElementBlock(Fragment, null, renderList(items.value, (item) => {
1174
- return openBlock(), createBlock(_sfc_main$k, mergeProps({ ref_for: true }, item.props, {
1175
- class: "v-context-menu__item",
1176
- onClick: ($event) => onItemClick(item)
1177
- }), {
1178
- default: withCtx(() => [
1179
- createTextVNode(toDisplayString(item.title), 1)
1180
- ]),
1181
- _: 2
1182
- }, 1040, ["onClick"]);
1183
- }), 256))
1518
+ (openBlock(true), createElementBlock(Fragment, null, renderList(props.items, (item) => {
1519
+ return openBlock(), createElementBlock("button", {
1520
+ key: item.id,
1521
+ class: normalizeClass(["v-tabs__tab", { active: unref(model) === item.id }]),
1522
+ onClick: ($event) => model.value = item.id
1523
+ }, toDisplayString(item.title), 11, _hoisted_1$l);
1524
+ }), 128))
1184
1525
  ]),
1185
1526
  _: 1
1186
- }, 8, ["open", "element", "anchorPosition", "placement", "offset"])
1187
- ], 64);
1527
+ }),
1528
+ createElementVNode("div", {
1529
+ class: "v-tabs__marker",
1530
+ style: normalizeStyle(markerStyle.value)
1531
+ }, null, 4)
1532
+ ], 512);
1188
1533
  };
1189
1534
  }
1190
1535
  });
1191
- const _hoisted_1$f = ["onBlockdrop", "onMousedown", "onMouseenter", "onClick", "onContextmenu"];
1192
- const _hoisted_2$4 = ["onBlockdrop"];
1193
- const _sfc_main$i = /* @__PURE__ */ defineComponent({
1194
- __name: "ContentHierarchy",
1536
+ const _hoisted_1$k = { class: "v-tabs-pages" };
1537
+ const _sfc_main$r = /* @__PURE__ */ defineComponent({
1538
+ __name: "VTabsPages",
1195
1539
  props: {
1196
- contentBlocks: {},
1197
- blocksMap: {},
1198
- hoverBlockId: {},
1199
- activeBlockId: {}
1540
+ page: {},
1541
+ "page:class": {}
1200
1542
  },
1201
- emits: ["update:hoverBlockId", "update:activeBlockId"],
1543
+ setup(__props) {
1544
+ const props = __props;
1545
+ const slots = useSlots();
1546
+ const transitionClass = ref("slide-right");
1547
+ watch(() => props.page, (value, lastValue) => {
1548
+ const keys = Object.keys(slots);
1549
+ if (keys.indexOf(value) > keys.indexOf(lastValue)) {
1550
+ transitionClass.value = "slide-left";
1551
+ } else {
1552
+ transitionClass.value = "slide-right";
1553
+ }
1554
+ });
1555
+ return (_ctx, _cache) => {
1556
+ return openBlock(), createElementBlock("div", _hoisted_1$k, [
1557
+ createVNode(Transition, { name: transitionClass.value }, {
1558
+ default: withCtx(() => [
1559
+ (openBlock(), createElementBlock("div", {
1560
+ key: props.page,
1561
+ class: normalizeClass(["v-tabs-pages__page", props["page:class"]])
1562
+ }, [
1563
+ renderSlot(_ctx.$slots, props.page)
1564
+ ], 2))
1565
+ ]),
1566
+ _: 3
1567
+ }, 8, ["name"])
1568
+ ]);
1569
+ };
1570
+ }
1571
+ });
1572
+ const _sfc_main$q = {};
1573
+ const _hoisted_1$j = {
1574
+ width: "20",
1575
+ height: "20",
1576
+ viewBox: "0 0 20 20",
1577
+ fill: "none",
1578
+ xmlns: "http://www.w3.org/2000/svg"
1579
+ };
1580
+ function _sfc_render$7(_ctx, _cache) {
1581
+ return openBlock(), createElementBlock("svg", _hoisted_1$j, _cache[0] || (_cache[0] = [
1582
+ createElementVNode("path", {
1583
+ "fill-rule": "evenodd",
1584
+ "clip-rule": "evenodd",
1585
+ d: "M7.5001 14.1665C7.50013 14.3313 7.54902 14.4924 7.64059 14.6294C7.73217 14.7664 7.8623 14.8732 8.01455 14.9362C8.1668 14.9993 8.33433 15.0158 8.49596 14.9836C8.65758 14.9515 8.80605 14.8722 8.9226 14.7557L13.0893 10.589C13.2455 10.4327 13.3333 10.2208 13.3333 9.99982C13.3333 9.77885 13.2455 9.56693 13.0893 9.41066L8.9226 5.24399C8.80605 5.12748 8.65758 5.04814 8.49596 5.016C8.33433 4.98386 8.1668 5.00037 8.01455 5.06342C7.8623 5.12648 7.73217 5.23327 7.6406 5.37027C7.54902 5.50728 7.50013 5.66836 7.5001 5.83316L7.5001 14.1665Z",
1586
+ fill: "currentColor"
1587
+ }, null, -1)
1588
+ ]));
1589
+ }
1590
+ const CollapseArrowIcon = /* @__PURE__ */ _export_sfc(_sfc_main$q, [["render", _sfc_render$7]]);
1591
+ const _sfc_main$p = /* @__PURE__ */ defineComponent({
1592
+ __name: "VCollapse",
1593
+ props: {
1594
+ open: { type: Boolean },
1595
+ label: {},
1596
+ withPadding: { type: Boolean }
1597
+ },
1598
+ emits: ["update:open"],
1202
1599
  setup(__props, { emit: __emit }) {
1203
1600
  const props = __props;
1204
1601
  const emit = __emit;
1205
- const flatBlocks = computed(() => {
1206
- const arr = [];
1207
- const collectBlocks = (items, intent = 0, parent = null) => {
1208
- for (let i = 0; i < items.length; i++) {
1209
- const data = items[i];
1210
- const block = props.blocksMap.get(data.blockId);
1211
- if (!block) {
1212
- arr.push({
1213
- content: data,
1214
- key: data.id,
1215
- intent,
1216
- hasSlots: false,
1217
- hasMultipleSlots: false,
1218
- block: {},
1219
- parent
1220
- });
1221
- continue;
1222
- }
1223
- arr.push({
1224
- content: data,
1225
- key: data.id,
1226
- intent,
1227
- hasSlots: hasSlots(block),
1228
- hasMultipleSlots: hasMultipleSlots(block),
1229
- block,
1230
- parent
1231
- });
1232
- forEachChildren(block, data, (blocks) => {
1233
- collectBlocks(blocks, intent + 1, data);
1234
- });
1235
- }
1236
- };
1237
- collectBlocks(props.contentBlocks);
1238
- return arr;
1602
+ const height = ref(0);
1603
+ const open = ref(props.open ?? false);
1604
+ const transition = ref(false);
1605
+ const innerRef = ref();
1606
+ let hideTimeout = null;
1607
+ const setOpen = async (value) => {
1608
+ open.value = value;
1609
+ if (hideTimeout !== null) {
1610
+ clearTimeout(hideTimeout);
1611
+ hideTimeout = null;
1612
+ }
1613
+ if (open.value === false && innerRef.value) {
1614
+ height.value = innerRef.value.clientHeight;
1615
+ }
1616
+ transition.value = true;
1617
+ await nextTick();
1618
+ await new Promise((res) => requestAnimationFrame(res));
1619
+ if (open.value) {
1620
+ height.value = innerRef.value.clientHeight;
1621
+ } else {
1622
+ height.value = 0;
1623
+ }
1624
+ hideTimeout = setTimeout(() => {
1625
+ transition.value = false;
1626
+ }, 200);
1627
+ setTimeout(() => mouseMove = true, 0);
1628
+ emit("update:open", open.value);
1629
+ };
1630
+ const onClick = async () => {
1631
+ setOpen(!open.value);
1632
+ };
1633
+ watch(() => props.open, (value) => {
1634
+ if (typeof value !== "boolean" || open.value === value) return;
1635
+ setOpen(value);
1239
1636
  });
1240
- const drag = useDraggableItem();
1241
- const dragMode = inject("dragMode");
1242
- const onItemMouseDown = (e, item) => {
1243
- if (e.button !== 0) return;
1244
- const target = e.currentTarget;
1245
- drag(e, {
1246
- onStart(item2) {
1247
- target.setAttribute("data-source-drag", "");
1248
- item2.classList.add("drag");
1249
- document.body.classList.add("mousedrag");
1250
- dragMode.value = true;
1251
- },
1252
- onEnd(e2) {
1253
- var _a;
1254
- document.body.classList.remove("mousedrag");
1255
- target.removeAttribute("data-source-drag");
1256
- if (e2.target !== target) {
1257
- (_a = e2.target) == null ? void 0 : _a.dispatchEvent(new BlockDropEvent(item.block, item.content));
1258
- }
1259
- dragMode.value = false;
1260
- }
1261
- });
1637
+ let mouseMove = false;
1638
+ useEventListener("mousedown", () => mouseMove = false);
1639
+ const onMouseEnter = (e) => {
1640
+ if (e.buttons > 0 && !mouseMove && !document.body.classList.contains("mousedrag")) {
1641
+ mouseMove = true;
1642
+ onClick();
1643
+ }
1644
+ };
1645
+ return (_ctx, _cache) => {
1646
+ return openBlock(), createElementBlock("div", {
1647
+ class: normalizeClass(["v-collapse", { open: open.value }])
1648
+ }, [
1649
+ renderSlot(_ctx.$slots, "activator", {
1650
+ props: { onClick, open: open.value }
1651
+ }, () => [
1652
+ createElementVNode("div", {
1653
+ class: normalizeClass(["v-collapse__activator", { open: open.value }]),
1654
+ onMousedown: onClick,
1655
+ onMouseenter: onMouseEnter
1656
+ }, [
1657
+ createVNode(CollapseArrowIcon),
1658
+ createElementVNode("div", null, toDisplayString(props.label), 1)
1659
+ ], 34)
1660
+ ]),
1661
+ createElementVNode("div", {
1662
+ class: normalizeClass(["v-collapse__content", { "v-transition": transition.value, withPadding: props.withPadding }]),
1663
+ style: normalizeStyle(transition.value ? { height: `${height.value}px` } : void 0)
1664
+ }, [
1665
+ transition.value || open.value ? (openBlock(), createElementBlock("div", {
1666
+ key: 0,
1667
+ ref_key: "innerRef",
1668
+ ref: innerRef,
1669
+ class: "v-collapse__content-inner"
1670
+ }, [
1671
+ renderSlot(_ctx.$slots, "default")
1672
+ ], 512)) : createCommentVNode("", true)
1673
+ ], 6)
1674
+ ], 2);
1262
1675
  };
1263
- const containerRef = ref();
1264
- const places = shallowReactive([]);
1265
- watch(dragMode, (dragMode2) => {
1266
- if (!dragMode2 || !containerRef.value) {
1267
- places.length = 0;
1268
- return;
1676
+ }
1677
+ });
1678
+ const margin = 8;
1679
+ const _sfc_main$o = /* @__PURE__ */ defineComponent({
1680
+ ...{
1681
+ inheritAttrs: false
1682
+ },
1683
+ __name: "VPopover",
1684
+ props: {
1685
+ open: { type: Boolean },
1686
+ element: {},
1687
+ placement: {},
1688
+ offset: {},
1689
+ fitAnchor: { type: Boolean },
1690
+ class: {},
1691
+ anchorPosition: {}
1692
+ },
1693
+ emits: ["update:open"],
1694
+ setup(__props, { emit: __emit }) {
1695
+ const props = __props;
1696
+ const emit = __emit;
1697
+ const popoverRef = ref();
1698
+ const position = ref({ top: 0, left: 0 });
1699
+ const origin = ref("center");
1700
+ const open = useVModel(props, "open", emit, { passive: true });
1701
+ const activatorElement = ref();
1702
+ const clamp = (value, min, max) => {
1703
+ if (value < min) return min;
1704
+ if (value > max) return max;
1705
+ return value;
1706
+ };
1707
+ const calcPrimary = (pos, start, end, size, min, max) => {
1708
+ const fitStart = start - size >= min;
1709
+ const fitEnd = end + size <= max;
1710
+ if ((!fitEnd || pos === "start") && fitStart) return start - size;
1711
+ if ((!fitStart || pos === "end") && fitEnd) return end;
1712
+ return pos === "start" ? min : max - size;
1713
+ };
1714
+ const calcSub = (pos, start, end, size, min, max) => {
1715
+ if (pos === "start") return clamp(start, min, max - size);
1716
+ if (pos === "end") return clamp(end - size, min, max - size);
1717
+ return clamp((start + end) / 2 - size / 2, min, max - size);
1718
+ };
1719
+ const calcOrigin = (start, end, point) => {
1720
+ return clamp(Math.round((point - start) / (end - start) * 100), 0, 100) + "%";
1721
+ };
1722
+ const getRect = () => {
1723
+ if (props.anchorPosition) {
1724
+ return {
1725
+ top: props.anchorPosition.y,
1726
+ bottom: props.anchorPosition.y,
1727
+ left: props.anchorPosition.x,
1728
+ right: props.anchorPosition.x,
1729
+ width: 0,
1730
+ height: 0
1731
+ };
1269
1732
  }
1270
- const containerRect = containerRef.value.getBoundingClientRect();
1271
- places.length = 0;
1272
- const children = Array.from(containerRef.value.children).filter((child) => child.classList.contains("page-editor-hierarchy__item"));
1273
- let lastRectHeight = 0;
1274
- let lastRectBottom = containerRect.top;
1275
- for (let i = 0; i < children.length + 1; i++) {
1276
- const child = children[i];
1277
- const rect = i === children.length ? { top: lastRectBottom, height: containerRect.bottom - lastRectBottom, bottom: 0 } : child.getBoundingClientRect();
1278
- let top = lastRectHeight * 0.2;
1279
- let bottom = rect.height * 0.2;
1280
- if (i > 0 && !flatBlocks.value[i - 1].hasSlots) {
1281
- top = lastRectHeight * 0.5;
1733
+ const element = props.element ?? activatorElement.value;
1734
+ if (!element) return null;
1735
+ return element.getBoundingClientRect();
1736
+ };
1737
+ const isHorizontal = computed(() => props.placement.startsWith("left") || props.placement.startsWith("right"));
1738
+ const calcPosition = () => {
1739
+ if (!popoverRef.value) return;
1740
+ const rect = getRect();
1741
+ if (!rect) return;
1742
+ const placement = props.placement.split("-");
1743
+ const offset = props.offset ?? 0;
1744
+ const width = popoverRef.value.clientWidth;
1745
+ const height = popoverRef.value.clientHeight;
1746
+ if (placement[0] === "top" || placement[0] === "bottom") {
1747
+ const top = calcPrimary(placement[0] === "top" ? "start" : "end", rect.top - offset, rect.bottom + offset, height, margin, window.innerHeight - margin);
1748
+ if (props.fitAnchor) {
1749
+ position.value = {
1750
+ top,
1751
+ left: calcSub("start", rect.left, rect.right, rect.width, margin, window.innerWidth - margin),
1752
+ width: rect.width
1753
+ };
1754
+ } else {
1755
+ position.value = { top, left: calcSub(placement[1], rect.left, rect.right, width, margin, window.innerWidth - margin) };
1282
1756
  }
1283
- if (i === children.length) {
1284
- bottom = rect.height;
1285
- } else if (!flatBlocks.value[i].hasSlots) {
1286
- bottom = rect.height * 0.5;
1757
+ } else {
1758
+ const left = calcPrimary(placement[0] === "left" ? "start" : "end", rect.left - offset, rect.right + offset, width, margin, window.innerWidth - margin);
1759
+ if (props.fitAnchor) {
1760
+ position.value = {
1761
+ left,
1762
+ top: calcSub("start", rect.top, rect.bottom, rect.height, margin, window.innerHeight - margin),
1763
+ height: rect.height
1764
+ };
1765
+ } else {
1766
+ position.value = { left, top: calcSub(placement[1], rect.top, rect.bottom, height, margin, window.innerHeight - margin) };
1287
1767
  }
1288
- places.push({
1289
- index: i,
1290
- style: {
1291
- top: rect.top - containerRect.top + containerRef.value.scrollTop - top + "px",
1292
- paddingTop: top - 1 + "px",
1293
- height: top + bottom + "px"
1294
- }
1295
- });
1296
- lastRectHeight = rect.height;
1297
- lastRectBottom = rect.bottom;
1298
1768
  }
1769
+ origin.value = calcOrigin(position.value.left, position.value.left + width, rect.left + rect.width / 2) + calcOrigin(position.value.top, position.value.top + height, rect.top + rect.height / 2);
1770
+ };
1771
+ watch([() => props.element, () => props.anchorPosition], () => {
1772
+ calcPosition();
1299
1773
  });
1300
- const onItemBlockDrop = (e, item) => {
1301
- if (e.content) {
1302
- deleteBlock(props.contentBlocks, e.content);
1303
- }
1304
- if (item.hasSlots) {
1305
- const contentBlock = e.content ?? { id: uid(), blockId: e.block.id, data: {} };
1306
- createContentBlockChild(props.blocksMap, contentBlock, item.content, -1);
1307
- }
1774
+ useResizeObserver(popoverRef, calcPosition);
1775
+ useEventListener(window, "resize", calcPosition);
1776
+ const close = () => {
1777
+ open.value = false;
1308
1778
  };
1309
- const onPlaceBlockDrop = (e, _index, dublicate = false) => {
1310
- e.stopPropagation();
1311
- let index = _index;
1312
- let content = e.content;
1313
- if (content && !dublicate) {
1314
- const sourceIndex = flatBlocks.value.findIndex((item) => item.content === content);
1315
- if (sourceIndex === index || sourceIndex === index - 1) return;
1316
- if (index > sourceIndex && sourceIndex !== -1) index--;
1317
- deleteBlock(props.contentBlocks, content);
1779
+ const closeDelayed = () => {
1780
+ setTimeout(close, 0);
1781
+ };
1782
+ useKeyDownLayer("Escape", open, close);
1783
+ useMouseDownOutside(open, closeDelayed, popoverRef);
1784
+ watch(open, (open2) => {
1785
+ if (!props.element) return;
1786
+ if (open2) {
1787
+ props.element.classList.add("popoverHover");
1788
+ } else {
1789
+ props.element.classList.remove("popoverHover");
1318
1790
  }
1319
- if (content && dublicate) {
1320
- content = cloneDeep(content);
1321
- content.id = uid();
1322
- content.data["data-block-id"] = content.id;
1323
- forEachChildren(e.block, content, (contents) => {
1324
- for (let content2 of contents) {
1325
- content2.id = uid();
1791
+ });
1792
+ const activatorProps = {
1793
+ onMousedown: (e) => {
1794
+ open.value = !open.value;
1795
+ if (open.value) {
1796
+ activatorElement.value = e.currentTarget;
1797
+ }
1798
+ },
1799
+ // onTouchstart: (e: TouchEvent) => {
1800
+ // open.value = !open.value
1801
+ // if (open.value) {
1802
+ // activatorElement.value = e.currentTarget as HTMLElement
1803
+ // }
1804
+ // },
1805
+ onKeydown(e) {
1806
+ if (e.code === "Enter") {
1807
+ open.value = !open.value;
1808
+ if (open.value) {
1809
+ activatorElement.value = e.currentTarget;
1326
1810
  }
1327
- });
1328
- }
1329
- const contentBlock = content ?? createContentBlock(e.block);
1330
- if (index >= flatBlocks.value.length) {
1331
- props.contentBlocks.push(contentBlock);
1332
- } else {
1333
- const blockEntry = flatBlocks.value[index];
1334
- if (blockEntry.parent === null) {
1335
- const index2 = props.contentBlocks.indexOf(blockEntry.content);
1336
- props.contentBlocks.splice(index2, 0, contentBlock);
1337
- } else {
1338
- const index2 = getBlockIndex(blockEntry.parent, blockEntry.content);
1339
- createContentBlockChild(props.blocksMap, contentBlock, blockEntry.parent, index2);
1340
1811
  }
1341
1812
  }
1342
1813
  };
1343
- const contextMenu = useContextMenu((content) => [
1344
- content !== null && { title: "Дублировать блок", onClick() {
1345
- const index = flatBlocks.value.findIndex((item) => item.content === content);
1346
- const block = props.blocksMap.get(content.blockId);
1347
- onPlaceBlockDrop(new BlockDropEvent(block, content), index, true);
1348
- } },
1349
- content !== null && { title: "Копировать блок", async onClick() {
1350
- const blob = new Blob([JSON.stringify(content)], { type: "text/plain" });
1351
- await navigator.clipboard.write([
1352
- new ClipboardItem({ "text/plain": blob })
1353
- ]);
1354
- } },
1355
- {
1356
- title: "Вставить блок",
1357
- onClick: () => placeBlockFromClipboard(content)
1358
- },
1359
- content !== null && {
1360
- title: "Удалить блок",
1361
- onClick: () => deleteBlock(props.contentBlocks, content)
1362
- }
1363
- ]);
1364
- const placeBlockFromClipboard = async (content) => {
1365
- const resp = await navigator.clipboard.read();
1366
- if (!resp[0].types.includes("text/plain")) return;
1367
- const entry = await resp[0].getType("text/plain");
1368
- const text = await entry.text();
1369
- if (!text.startsWith("{")) return;
1370
- try {
1371
- const contentData = JSON.parse(text);
1372
- contentData.id = uid();
1373
- const block = props.blocksMap.get(contentData.blockId);
1374
- if (!block) return;
1375
- if (content !== null) {
1376
- const index = flatBlocks.value.findIndex((item) => item.content === content);
1377
- if (flatBlocks.value[index].hasSlots) {
1378
- onItemBlockDrop(new BlockDropEvent(block, contentData), flatBlocks.value[index]);
1379
- } else {
1380
- onPlaceBlockDrop(new BlockDropEvent(block, contentData), index);
1381
- }
1382
- } else {
1383
- onPlaceBlockDrop(new BlockDropEvent(block, contentData), flatBlocks.value.length);
1384
- }
1385
- } catch (e) {
1386
- console.warn(e);
1387
- }
1814
+ const style = computed(() => {
1815
+ return {
1816
+ left: position.value.left + "px",
1817
+ top: position.value.top + "px",
1818
+ width: position.value.width ? position.value.width + "px" : void 0,
1819
+ height: position.value.height ? position.value.height + "px" : void 0,
1820
+ transformOrigin: origin.value
1821
+ };
1822
+ });
1823
+ return (_ctx, _cache) => {
1824
+ return openBlock(), createElementBlock(Fragment, null, [
1825
+ (openBlock(), createBlock(Teleport, { to: "body" }, [
1826
+ createVNode(Transition, null, {
1827
+ default: withCtx(() => [
1828
+ unref(open) ? (openBlock(), createElementBlock("div", mergeProps({ key: 0 }, _ctx.$attrs, {
1829
+ class: ["v-popover editor-component", [isHorizontal.value ? "horizontal" : "vertical", props.fitAnchor && "fit-anchor", props.class]],
1830
+ style: style.value,
1831
+ ref_key: "popoverRef",
1832
+ ref: popoverRef,
1833
+ onMousedown: _cache[0] || (_cache[0] = withModifiers(() => {
1834
+ }, ["stop"]))
1835
+ }), [
1836
+ renderSlot(_ctx.$slots, "default")
1837
+ ], 16)) : createCommentVNode("", true)
1838
+ ]),
1839
+ _: 3
1840
+ })
1841
+ ])),
1842
+ renderSlot(_ctx.$slots, "activator", { props: activatorProps })
1843
+ ], 64);
1844
+ };
1845
+ }
1846
+ });
1847
+ const _sfc_main$n = {};
1848
+ const _hoisted_1$i = {
1849
+ width: "16",
1850
+ height: "16",
1851
+ viewBox: "0 0 16 16",
1852
+ fill: "none",
1853
+ xmlns: "http://www.w3.org/2000/svg"
1854
+ };
1855
+ function _sfc_render$6(_ctx, _cache) {
1856
+ return openBlock(), createElementBlock("svg", _hoisted_1$i, _cache[0] || (_cache[0] = [
1857
+ createElementVNode("path", {
1858
+ d: "M14.364 5.293C14.1764 5.10553 13.9221 5.00021 13.657 5.00021C13.3918 5.00021 13.1375 5.10553 12.95 5.293L7.99995 10.243L3.04995 5.293C2.86135 5.11084 2.60875 5.01005 2.34655 5.01232C2.08435 5.0146 1.83354 5.11977 1.64813 5.30518C1.46272 5.49059 1.35756 5.7414 1.35528 6.0036C1.353 6.26579 1.45379 6.5184 1.63595 6.707L7.29295 12.364C7.48048 12.5515 7.73479 12.6568 7.99995 12.6568C8.26512 12.6568 8.51942 12.5515 8.70695 12.364L14.364 6.707C14.5514 6.51947 14.6567 6.26516 14.6567 6C14.6567 5.73483 14.5514 5.48053 14.364 5.293Z",
1859
+ fill: "currentColor"
1860
+ }, null, -1)
1861
+ ]));
1862
+ }
1863
+ const ArrowDownIcon = /* @__PURE__ */ _export_sfc(_sfc_main$n, [["render", _sfc_render$6]]);
1864
+ const _sfc_main$m = {};
1865
+ const _hoisted_1$h = { class: "v-icon-button" };
1866
+ function _sfc_render$5(_ctx, _cache) {
1867
+ return openBlock(), createElementBlock("button", _hoisted_1$h, [
1868
+ renderSlot(_ctx.$slots, "default")
1869
+ ]);
1870
+ }
1871
+ const VIconButton = /* @__PURE__ */ _export_sfc(_sfc_main$m, [["render", _sfc_render$5]]);
1872
+ const _sfc_main$l = {};
1873
+ const _hoisted_1$g = {
1874
+ width: "16",
1875
+ height: "16",
1876
+ viewBox: "0 0 16 16",
1877
+ fill: "none",
1878
+ xmlns: "http://www.w3.org/2000/svg"
1879
+ };
1880
+ function _sfc_render$4(_ctx, _cache) {
1881
+ return openBlock(), createElementBlock("svg", _hoisted_1$g, _cache[0] || (_cache[0] = [
1882
+ createElementVNode("path", {
1883
+ d: "M9.31382 7.9L12.8488 4.364C12.9443 4.27176 13.0205 4.16141 13.0729 4.03941C13.1253 3.9174 13.1529 3.78618 13.1541 3.6534C13.1552 3.52062 13.1299 3.38894 13.0796 3.26605C13.0294 3.14315 12.9551 3.0315 12.8612 2.93761C12.7673 2.84371 12.6557 2.76946 12.5328 2.71918C12.4099 2.6689 12.2782 2.6436 12.1454 2.64475C12.0126 2.64591 11.8814 2.67349 11.7594 2.7259C11.6374 2.77831 11.5271 2.85449 11.4348 2.95L7.89882 6.485L4.36382 2.95C4.27157 2.85449 4.16123 2.77831 4.03922 2.7259C3.91722 2.67349 3.786 2.64591 3.65322 2.64475C3.52044 2.6436 3.38876 2.6689 3.26587 2.71918C3.14297 2.76946 3.03132 2.84371 2.93742 2.93761C2.84353 3.0315 2.76928 3.14315 2.719 3.26605C2.66872 3.38894 2.64342 3.52062 2.64457 3.6534C2.64572 3.78618 2.67331 3.9174 2.72572 4.03941C2.77813 4.16141 2.85431 4.27176 2.94982 4.364L6.48482 7.899L2.94982 11.435C2.85431 11.5273 2.77813 11.6376 2.72572 11.7596C2.67331 11.8816 2.64572 12.0128 2.64457 12.1456C2.64342 12.2784 2.66872 12.4101 2.719 12.533C2.76928 12.6559 2.84353 12.7675 2.93742 12.8614C3.03132 12.9553 3.14297 13.0295 3.26587 13.0798C3.38876 13.1301 3.52044 13.1554 3.65322 13.1543C3.786 13.1531 3.91722 13.1255 4.03922 13.0731C4.16123 13.0207 4.27157 12.9445 4.36382 12.849L7.89882 9.314L11.4348 12.849C11.5271 12.9445 11.6374 13.0207 11.7594 13.0731C11.8814 13.1255 12.0126 13.1531 12.1454 13.1543C12.2782 13.1554 12.4099 13.1301 12.5328 13.0798C12.6557 13.0295 12.7673 12.9553 12.8612 12.8614C12.9551 12.7675 13.0294 12.6559 13.0796 12.533C13.1299 12.4101 13.1552 12.2784 13.1541 12.1456C13.1529 12.0128 13.1253 11.8816 13.0729 11.7596C13.0205 11.6376 12.9443 11.5273 12.8488 11.435L9.31382 7.9Z",
1884
+ fill: "currentColor"
1885
+ }, null, -1)
1886
+ ]));
1887
+ }
1888
+ const CloseMinIcon = /* @__PURE__ */ _export_sfc(_sfc_main$l, [["render", _sfc_render$4]]);
1889
+ const _hoisted_1$f = { key: 0 };
1890
+ const _hoisted_2$6 = {
1891
+ key: 1,
1892
+ class: "v-select__placeholder"
1893
+ };
1894
+ const _hoisted_3$4 = { class: "v-select__actions" };
1895
+ const _hoisted_4$1 = { class: "v-select__menu" };
1896
+ const _hoisted_5 = {
1897
+ key: 0,
1898
+ class: "v-select__divider"
1899
+ };
1900
+ const _hoisted_6 = {
1901
+ key: 1,
1902
+ class: "group-title"
1903
+ };
1904
+ const _hoisted_7 = ["onClick"];
1905
+ const _sfc_main$k = /* @__PURE__ */ defineComponent({
1906
+ __name: "VSelect",
1907
+ props: {
1908
+ items: {},
1909
+ modelValue: {},
1910
+ placeholder: {},
1911
+ nullable: { type: Boolean },
1912
+ visualValue: {},
1913
+ error: {},
1914
+ label: {},
1915
+ required: { type: Boolean },
1916
+ disabled: { type: Boolean }
1917
+ },
1918
+ emits: ["update:modelValue"],
1919
+ setup(__props, { emit: __emit }) {
1920
+ const props = __props;
1921
+ const emit = __emit;
1922
+ const model = useVModel(props, "modelValue", emit, { passive: true, defaultValue: null });
1923
+ const currentItem = computed(() => {
1924
+ if (model.value === null) return null;
1925
+ return props.items.find((item) => typeof item !== "string" && item.id === model.value) ?? null;
1926
+ });
1927
+ const items = computed(() => {
1928
+ return props.items;
1929
+ });
1930
+ const opened = ref(false);
1931
+ const onItemClick = (item) => {
1932
+ model.value = item.id;
1933
+ opened.value = false;
1934
+ };
1935
+ const resetValue = () => {
1936
+ model.value = null;
1937
+ opened.value = false;
1388
1938
  };
1389
1939
  return (_ctx, _cache) => {
1390
- return openBlock(), createElementBlock("div", {
1391
- ref_key: "containerRef",
1392
- ref: containerRef,
1393
- class: "page-editor-hierarchy",
1394
- onClick: _cache[1] || (_cache[1] = withModifiers(($event) => emit("update:activeBlockId", null), ["self"]))
1395
- }, [
1396
- (openBlock(true), createElementBlock(Fragment, null, renderList(flatBlocks.value, (item) => {
1397
- return openBlock(), createElementBlock("div", {
1398
- class: normalizeClass(["page-editor-hierarchy__item", { active: props.activeBlockId === item.content.id, hover: props.hoverBlockId === item.content.id }]),
1399
- style: normalizeStyle({ paddingLeft: `${16 + item.intent * 16}px` }),
1400
- onBlockdrop: ($event) => onItemBlockDrop($event, item),
1401
- onMousedown: ($event) => onItemMouseDown($event, item),
1402
- onMouseenter: ($event) => emit("update:hoverBlockId", item.content.id),
1403
- onMouseleave: _cache[0] || (_cache[0] = ($event) => emit("update:hoverBlockId", null)),
1404
- onClick: ($event) => emit("update:activeBlockId", item.content.id),
1405
- onContextmenu: withModifiers(($event) => unref(contextMenu).open($event, item.content), ["stop"])
1406
- }, toDisplayString(item.block.name), 47, _hoisted_1$f);
1407
- }), 256)),
1408
- (openBlock(true), createElementBlock(Fragment, null, renderList(unref(places), (item) => {
1409
- return openBlock(), createElementBlock("div", {
1410
- class: "page-editor-hierarhy__place",
1411
- style: normalizeStyle(item.style),
1412
- onBlockdrop: ($event) => onPlaceBlockDrop($event, item.index)
1413
- }, null, 44, _hoisted_2$4);
1414
- }), 256)),
1415
- createVNode(_sfc_main$j, normalizeProps(guardReactiveProps(unref(contextMenu).props)), null, 16)
1416
- ], 512);
1940
+ return openBlock(), createBlock(_sfc_main$v, {
1941
+ outline: "",
1942
+ class: "v-select",
1943
+ label: props.label,
1944
+ error: props.error,
1945
+ disabled: props.disabled,
1946
+ required: props.required
1947
+ }, {
1948
+ default: withCtx(() => [
1949
+ createVNode(_sfc_main$o, {
1950
+ open: opened.value,
1951
+ "onUpdate:open": _cache[0] || (_cache[0] = ($event) => opened.value = $event),
1952
+ placement: "bottom",
1953
+ "fit-anchor": "",
1954
+ offset: 8
1955
+ }, {
1956
+ activator: withCtx(({ props: activatorProps }) => [
1957
+ createElementVNode("button", mergeProps({
1958
+ class: ["v-select__activator", { opened: opened.value }]
1959
+ }, activatorProps), [
1960
+ currentItem.value ? (openBlock(), createElementBlock("div", _hoisted_1$f, toDisplayString(currentItem.value.title), 1)) : (openBlock(), createElementBlock("div", _hoisted_2$6, toDisplayString(props.placeholder ?? "Выберите значение"), 1)),
1961
+ createVNode(ArrowDownIcon)
1962
+ ], 16),
1963
+ createElementVNode("div", _hoisted_3$4, [
1964
+ renderSlot(_ctx.$slots, "default"),
1965
+ _ctx.nullable && unref(model) ? (openBlock(), createBlock(VIconButton, {
1966
+ key: 0,
1967
+ title: "Очистить значение",
1968
+ class: "v-select__delete-button",
1969
+ onClick: resetValue
1970
+ }, {
1971
+ default: withCtx(() => [
1972
+ createVNode(CloseMinIcon)
1973
+ ]),
1974
+ _: 1
1975
+ })) : createCommentVNode("", true)
1976
+ ])
1977
+ ]),
1978
+ default: withCtx(() => [
1979
+ createElementVNode("div", _hoisted_4$1, [
1980
+ (openBlock(true), createElementBlock(Fragment, null, renderList(items.value, (item) => {
1981
+ return openBlock(), createElementBlock(Fragment, null, [
1982
+ item === "" ? (openBlock(), createElementBlock("div", _hoisted_5)) : typeof item === "string" ? (openBlock(), createElementBlock("div", _hoisted_6, toDisplayString(item), 1)) : (openBlock(), createElementBlock("button", {
1983
+ key: 2,
1984
+ class: normalizeClass({ active: item.id === unref(model) }),
1985
+ onClick: ($event) => onItemClick(item)
1986
+ }, [
1987
+ renderSlot(_ctx.$slots, "item", { item }, () => [
1988
+ createTextVNode(toDisplayString(item.title), 1)
1989
+ ])
1990
+ ], 10, _hoisted_7))
1991
+ ], 64);
1992
+ }), 256))
1993
+ ])
1994
+ ]),
1995
+ _: 3
1996
+ }, 8, ["open"])
1997
+ ]),
1998
+ _: 3
1999
+ }, 8, ["label", "error", "disabled", "required"]);
1417
2000
  };
1418
2001
  }
1419
2002
  });
1420
- const _sfc_main$h = /* @__PURE__ */ defineComponent({
1421
- __name: "HoverFrame",
2003
+ const _hoisted_1$e = { class: "json-editor__array" };
2004
+ const _sfc_main$j = /* @__PURE__ */ defineComponent({
2005
+ __name: "JsonEditorArray",
1422
2006
  props: {
1423
- element: {},
1424
- resizable: { type: Boolean }
2007
+ label: {},
2008
+ schema: {},
2009
+ modelValue: {},
2010
+ expanded: { type: Boolean }
1425
2011
  },
1426
- setup(__props) {
2012
+ emits: ["update:modelValue"],
2013
+ setup(__props, { emit: __emit }) {
2014
+ var _a;
1427
2015
  const props = __props;
1428
- const style = ref({ display: "none" });
1429
- const updateStyle = () => {
1430
- if (props.element) {
1431
- const rect = props.element.getBoundingClientRect();
1432
- style.value = {
1433
- top: rect.top + document.documentElement.scrollTop + "px",
1434
- left: rect.left + document.documentElement.scrollLeft + "px",
1435
- width: rect.width + "px",
1436
- height: rect.height + "px"
1437
- };
1438
- } else {
1439
- style.value = { display: "none" };
1440
- }
1441
- };
1442
- const resizeObserver = new ResizeObserver(updateStyle);
1443
- watch(() => props.element, (element, lastElement) => {
1444
- updateStyle();
1445
- if (element) {
1446
- resizeObserver.observe(element);
1447
- } else if (lastElement) {
1448
- resizeObserver.unobserve(lastElement);
2016
+ const emit = __emit;
2017
+ const childExpanded = ((_a = props.schema.items) == null ? void 0 : _a.type) === "object" && Object.keys(props.schema.items.properties).length < 2;
2018
+ const length = ref(0);
2019
+ const tempArray = ref([]);
2020
+ if (props.schema.type === "array" && props.modelValue) {
2021
+ length.value = props.modelValue.length ?? 0;
2022
+ tempArray.value = [...props.modelValue];
2023
+ }
2024
+ watch(tempArray, () => {
2025
+ emit("update:modelValue", tempArray.value.slice(0, length.value));
2026
+ }, { deep: true });
2027
+ watch(length, (length2) => {
2028
+ for (let i = tempArray.value.length; i < length2; i++) {
2029
+ tempArray.value[i] = props.schema.items ? getDefaultValue(props.schema.items) : null;
1449
2030
  }
1450
- }, { immediate: true });
2031
+ emit("update:modelValue", tempArray.value.slice(0, length2));
2032
+ });
2033
+ const label = computed(() => {
2034
+ return `${props.label} (${length.value})`;
2035
+ });
1451
2036
  return (_ctx, _cache) => {
1452
- return openBlock(), createElementBlock("div", {
1453
- class: "editor-component editor-hover-frame",
1454
- style: normalizeStyle(style.value)
1455
- }, null, 4);
2037
+ return openBlock(), createElementBlock("div", _hoisted_1$e, [
2038
+ createVNode(_sfc_main$p, {
2039
+ label: label.value,
2040
+ open: props.expanded
2041
+ }, {
2042
+ default: withCtx(() => [
2043
+ createVNode(_sfc_main$u, {
2044
+ label: "Количество элементов",
2045
+ modelValue: length.value,
2046
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => length.value = $event),
2047
+ type: "number"
2048
+ }, null, 8, ["modelValue"]),
2049
+ (openBlock(true), createElementBlock(Fragment, null, renderList(length.value, (index) => {
2050
+ return openBlock(), createBlock(_sfc_main$6, {
2051
+ key: index,
2052
+ schema: props.schema.items,
2053
+ name: `${props.schema.itemName ?? "Элемент"} ${index}`,
2054
+ modelValue: tempArray.value[index - 1],
2055
+ "onUpdate:modelValue": ($event) => tempArray.value[index - 1] = $event,
2056
+ expanded: unref(childExpanded)
2057
+ }, null, 8, ["schema", "name", "modelValue", "onUpdate:modelValue", "expanded"]);
2058
+ }), 128))
2059
+ ]),
2060
+ _: 1
2061
+ }, 8, ["label", "open"])
2062
+ ]);
1456
2063
  };
1457
2064
  }
1458
2065
  });
1459
- const _hoisted_1$e = ["onClick"];
2066
+ const _sfc_main$i = {};
2067
+ const _hoisted_1$d = {
2068
+ width: "46",
2069
+ height: "28",
2070
+ viewBox: "0 0 46 28",
2071
+ fill: "none",
2072
+ xmlns: "http://www.w3.org/2000/svg"
2073
+ };
2074
+ function _sfc_render$3(_ctx, _cache) {
2075
+ return openBlock(), createElementBlock("svg", _hoisted_1$d, _cache[0] || (_cache[0] = [
2076
+ createStaticVNode('<mask id="mask0_1044_6" style="mask-type:luminance;" maskUnits="userSpaceOnUse" x="0" y="0" width="46" height="28"><path d="M45.5 0H0.5V28H45.5V0Z" fill="white"></path></mask><g mask="url(#mask0_1044_6)"><path d="M23.5 27.8537C35.9264 27.8537 46 25.6664 46 22.9683C46 20.2702 35.9264 18.083 23.5 18.083C11.0736 18.083 1 20.2702 1 22.9683C1 25.6664 11.0736 27.8537 23.5 27.8537Z" fill="#D7D7D7"></path><path d="M39.6719 9.5459L32.538 1.51859C32.1955 0.971432 31.6956 0.640625 31.169 0.640625H15.831C15.3044 0.640625 14.8045 0.971432 14.462 1.51789L7.32812 9.5466V15.9946H39.6719V9.5459Z" stroke="#A0A0A0" stroke-width="0.703125"></path><path d="M30.2591 11.7594C30.2591 10.6393 30.958 9.71457 31.825 9.71387H39.6719V22.3718C39.6719 23.8534 38.7437 25.0678 37.5977 25.0678H9.40234C8.25625 25.0678 7.32812 23.8527 7.32812 22.3718V9.71387H15.175C16.042 9.71387 16.7409 10.6372 16.7409 11.7573V11.7727C16.7409 12.8928 17.4475 13.7973 18.3138 13.7973H28.6862C29.5525 13.7973 30.2591 12.8845 30.2591 11.7643V11.7594Z" fill="#FAFAFA" stroke="#A0A0A0" stroke-width="0.703125"></path></g>', 2)
2077
+ ]));
2078
+ }
2079
+ const EmptyFileIcon = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["render", _sfc_render$3]]);
2080
+ const _sfc_main$h = {};
2081
+ const _hoisted_1$c = {
2082
+ width: "24",
2083
+ height: "24",
2084
+ viewBox: "0 0 24 24",
2085
+ fill: "none",
2086
+ xmlns: "http://www.w3.org/2000/svg"
2087
+ };
2088
+ function _sfc_render$2(_ctx, _cache) {
2089
+ return openBlock(), createElementBlock("svg", _hoisted_1$c, _cache[0] || (_cache[0] = [
2090
+ createElementVNode("path", {
2091
+ d: "M14 18C14 18.5304 13.7893 19.0391 13.4142 19.4142C13.0391 19.7893 12.5304 20 12 20C11.4696 20 10.9609 19.7893 10.5858 19.4142C10.2107 19.0391 10 18.5304 10 18C10 17.4696 10.2107 16.9609 10.5858 16.5858C10.9609 16.2107 11.4696 16 12 16C12.5304 16 13.0391 16.2107 13.4142 16.5858C13.7893 16.9609 14 17.4696 14 18ZM14 12C14 12.5304 13.7893 13.0391 13.4142 13.4142C13.0391 13.7893 12.5304 14 12 14C11.4696 14 10.9609 13.7893 10.5858 13.4142C10.2107 13.0391 10 12.5304 10 12C10 11.4696 10.2107 10.9609 10.5858 10.5858C10.9609 10.2107 11.4696 10 12 10C12.5304 10 13.0391 10.2107 13.4142 10.5858C13.7893 10.9609 14 11.4696 14 12ZM12 8C12.5304 8 13.0391 7.78929 13.4142 7.41421C13.7893 7.03914 14 6.53043 14 6C14 5.46957 13.7893 4.96086 13.4142 4.58579C13.0391 4.21071 12.5304 4 12 4C11.4696 4 10.9609 4.21071 10.5858 4.58579C10.2107 4.96086 10 5.46957 10 6C10 6.53043 10.2107 7.03914 10.5858 7.41421C10.9609 7.78929 11.4696 8 12 8Z",
2092
+ fill: "currentColor"
2093
+ }, null, -1)
2094
+ ]));
2095
+ }
2096
+ const MoreIcon = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["render", _sfc_render$2]]);
1460
2097
  const _sfc_main$g = /* @__PURE__ */ defineComponent({
1461
- __name: "VTabs",
2098
+ __name: "VButton",
2099
+ props: {
2100
+ component: {},
2101
+ disabled: { type: Boolean },
2102
+ flat: { type: Boolean },
2103
+ outline: { type: Boolean },
2104
+ large: { type: Boolean }
2105
+ },
2106
+ setup(__props) {
2107
+ return (_ctx, _cache) => {
2108
+ return openBlock(), createBlock(resolveDynamicComponent(_ctx.component ?? "button"), {
2109
+ class: normalizeClass(["v-button", { disabled: _ctx.disabled, flat: _ctx.flat, outline: _ctx.outline, large: _ctx.large }])
2110
+ }, {
2111
+ default: withCtx(() => [
2112
+ renderSlot(_ctx.$slots, "default")
2113
+ ]),
2114
+ _: 3
2115
+ }, 8, ["class"]);
2116
+ };
2117
+ }
2118
+ });
2119
+ const useContextMenu = (creator) => {
2120
+ let target = null;
2121
+ const props = reactive({
2122
+ items: [],
2123
+ open: false,
2124
+ anchorPosition: { x: 0, y: 0 },
2125
+ "onUpdate:open": (value) => {
2126
+ if (value === false && target !== null) {
2127
+ target.removeAttribute("data-popover-target");
2128
+ target = null;
2129
+ }
2130
+ props.open = value;
2131
+ }
2132
+ });
2133
+ const open = (e, ...args) => {
2134
+ e.preventDefault();
2135
+ props.items = creator(...args);
2136
+ props.anchorPosition = { x: e.clientX, y: e.clientY };
2137
+ props.open = true;
2138
+ if (target !== null) {
2139
+ target.removeAttribute("data-popover-target");
2140
+ target = null;
2141
+ }
2142
+ target = e.currentTarget;
2143
+ target.setAttribute("data-popover-target", "true");
2144
+ };
2145
+ return {
2146
+ props,
2147
+ open
2148
+ };
2149
+ };
2150
+ const _sfc_main$f = /* @__PURE__ */ defineComponent({
2151
+ __name: "VContextMenu",
1462
2152
  props: {
1463
- items: {},
1464
- modelValue: {}
2153
+ open: { type: Boolean },
2154
+ placement: {},
2155
+ anchorPosition: {},
2156
+ offset: {},
2157
+ items: { type: [Array, Function] }
1465
2158
  },
1466
- emits: ["update:modelValue"],
2159
+ emits: ["update:open"],
1467
2160
  setup(__props, { emit: __emit }) {
1468
2161
  const props = __props;
2162
+ const activatorElement = ref();
1469
2163
  const emit = __emit;
1470
- const model = useVModel(props, "modelValue", emit, { passive: true });
1471
- watch(() => props.items, (items) => {
1472
- if ((model.value === void 0 || model.value === null) && items.length > 0) {
1473
- model.value = items[0].id;
2164
+ const open = useVModel(props, "open", emit, { passive: true });
2165
+ const items = shallowRef([]);
2166
+ watch(open, (open2) => {
2167
+ if (!open2) return;
2168
+ const _items = typeof props.items === "function" ? props.items() : props.items;
2169
+ items.value = _items.filter((item) => !!item);
2170
+ });
2171
+ const activatorProps = {
2172
+ onClick: (e) => {
2173
+ open.value = true;
2174
+ activatorElement.value = e.currentTarget;
1474
2175
  }
1475
- }, { immediate: true });
1476
- const tabsRef = ref();
1477
- const markerStyle = ref({});
1478
- const placeMarker = () => {
1479
- const id = model.value;
1480
- if (!tabsRef.value) return;
1481
- const index = props.items.findIndex((item) => item.id === id);
1482
- if (index < 0) {
1483
- markerStyle.value = { width: "0px" };
1484
- return;
2176
+ };
2177
+ const onItemClick = (item) => {
2178
+ var _a, _b;
2179
+ if (item.onClick) {
2180
+ item.onClick();
2181
+ open.value = false;
1485
2182
  }
1486
- const child = tabsRef.value.children[index];
1487
- const p = 8;
1488
- markerStyle.value = { left: child.offsetLeft + p + "px", width: child.clientWidth - p * 2 + "px" };
1489
- for (let child2 of tabsRef.value.children) {
1490
- const item = child2;
1491
- item.style.left = item.offsetLeft + "px";
2183
+ if (((_a = item.props) == null ? void 0 : _a.to) || ((_b = item.props) == null ? void 0 : _b.href)) {
2184
+ open.value = false;
1492
2185
  }
1493
2186
  };
1494
- onMounted(() => {
1495
- placeMarker();
1496
- });
1497
- watch(() => props.items, () => {
1498
- placeMarker();
1499
- }, { deep: true, flush: "post" });
1500
- watch(model, placeMarker, { flush: "post" });
1501
2187
  return (_ctx, _cache) => {
1502
- return openBlock(), createElementBlock("div", {
1503
- ref_key: "tabsRef",
1504
- ref: tabsRef,
1505
- class: "v-tabs"
1506
- }, [
1507
- createVNode(TransitionGroup, null, {
2188
+ return openBlock(), createElementBlock(Fragment, null, [
2189
+ renderSlot(_ctx.$slots, "activator", { props: activatorProps }),
2190
+ createVNode(_sfc_main$o, {
2191
+ open: unref(open),
2192
+ "onUpdate:open": _cache[0] || (_cache[0] = ($event) => isRef(open) ? open.value = $event : null),
2193
+ element: activatorElement.value,
2194
+ anchorPosition: props.anchorPosition,
2195
+ placement: props.placement ?? "bottom-start",
2196
+ offset: _ctx.offset,
2197
+ class: "v-context-menu"
2198
+ }, {
1508
2199
  default: withCtx(() => [
1509
- (openBlock(true), createElementBlock(Fragment, null, renderList(props.items, (item) => {
1510
- return openBlock(), createElementBlock("button", {
1511
- key: item.id,
1512
- class: normalizeClass(["v-tabs__tab", { active: unref(model) === item.id }]),
1513
- onClick: ($event) => model.value = item.id
1514
- }, toDisplayString(item.title), 11, _hoisted_1$e);
1515
- }), 128))
2200
+ (openBlock(true), createElementBlock(Fragment, null, renderList(items.value, (item) => {
2201
+ return openBlock(), createBlock(_sfc_main$g, mergeProps({ ref_for: true }, item.props, {
2202
+ class: "v-context-menu__item",
2203
+ onClick: ($event) => onItemClick(item)
2204
+ }), {
2205
+ default: withCtx(() => [
2206
+ createTextVNode(toDisplayString(item.title), 1)
2207
+ ]),
2208
+ _: 2
2209
+ }, 1040, ["onClick"]);
2210
+ }), 256))
1516
2211
  ]),
1517
2212
  _: 1
1518
- }),
1519
- createElementVNode("div", {
1520
- class: "v-tabs__marker",
1521
- style: normalizeStyle(markerStyle.value)
1522
- }, null, 4)
1523
- ], 512);
2213
+ }, 8, ["open", "element", "anchorPosition", "placement", "offset"])
2214
+ ], 64);
1524
2215
  };
1525
2216
  }
1526
2217
  });
1527
- const _hoisted_1$d = { class: "v-tabs-pages" };
1528
- const _sfc_main$f = /* @__PURE__ */ defineComponent({
1529
- __name: "VTabsPages",
1530
- props: {
1531
- page: {},
1532
- "page:class": {}
1533
- },
2218
+ const createDialogSystem = () => {
2219
+ return {
2220
+ install: (app) => {
2221
+ const dialogHistory = shallowReactive([]);
2222
+ const open = (dialog2, props) => {
2223
+ dialogHistory.push({ dialog: dialog2, props });
2224
+ };
2225
+ const close = () => {
2226
+ dialogHistory.length = 0;
2227
+ };
2228
+ const back = () => {
2229
+ if (dialogHistory.length === 0) return;
2230
+ dialogHistory.pop();
2231
+ };
2232
+ const dialog = computed(() => {
2233
+ if (dialogHistory.length === 0) return { dialog: null, props: {} };
2234
+ return dialogHistory[dialogHistory.length - 1];
2235
+ });
2236
+ const isOpen = computed(() => dialogHistory.length > 0);
2237
+ app.provide("dialogStore", { open, close, back, dialogHistory, dialog, isOpen });
2238
+ }
2239
+ };
2240
+ };
2241
+ const useDialog = () => inject("dialogStore");
2242
+ const _sfc_main$e = /* @__PURE__ */ defineComponent({
2243
+ __name: "VDialogProvider",
1534
2244
  setup(__props) {
1535
- const props = __props;
1536
- const slots = useSlots();
1537
- const transitionClass = ref("slide-right");
1538
- watch(() => props.page, (value, lastValue) => {
1539
- const keys = Object.keys(slots);
1540
- if (keys.indexOf(value) > keys.indexOf(lastValue)) {
1541
- transitionClass.value = "slide-left";
2245
+ const dialogStore = inject("dialogStore");
2246
+ let mouseDown = false;
2247
+ const onMouseDown = (e) => {
2248
+ mouseDown = e.target === e.currentTarget;
2249
+ };
2250
+ const onMouseUp = (e) => {
2251
+ if (!mouseDown || e.target !== e.currentTarget) {
2252
+ mouseDown = false;
2253
+ return;
2254
+ }
2255
+ dialogStore.back();
2256
+ };
2257
+ useKeyDownLayer("Escape", dialogStore.isOpen, () => {
2258
+ dialogStore.back();
2259
+ });
2260
+ watch(dialogStore.isOpen, (isOpen) => {
2261
+ var _a, _b;
2262
+ if (isOpen) {
2263
+ const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
2264
+ document.body.style.overflowY = "hidden";
2265
+ document.body.style.paddingRight = scrollbarWidth + "px";
2266
+ (_a = document.getElementById("app")) == null ? void 0 : _a.setAttribute("inert", "");
1542
2267
  } else {
1543
- transitionClass.value = "slide-right";
2268
+ document.body.style.paddingRight = "";
2269
+ document.body.style.overflowY = "auto";
2270
+ (_b = document.getElementById("app")) == null ? void 0 : _b.removeAttribute("inert");
1544
2271
  }
1545
2272
  });
1546
2273
  return (_ctx, _cache) => {
1547
- return openBlock(), createElementBlock("div", _hoisted_1$d, [
1548
- createVNode(Transition, { name: transitionClass.value }, {
2274
+ return openBlock(), createBlock(Teleport, { to: "body" }, [
2275
+ createVNode(Transition, null, {
1549
2276
  default: withCtx(() => [
1550
- (openBlock(), createElementBlock("div", {
1551
- key: props.page,
1552
- class: normalizeClass(["v-tabs-pages__page", props["page:class"]])
2277
+ unref(dialogStore).isOpen.value ? (openBlock(), createElementBlock("div", {
2278
+ key: 0,
2279
+ class: "v-dialog-backdrop",
2280
+ onMousedown: onMouseDown,
2281
+ onMouseup: onMouseUp
1553
2282
  }, [
1554
- renderSlot(_ctx.$slots, props.page)
1555
- ], 2))
2283
+ (openBlock(true), createElementBlock(Fragment, null, renderList(unref(dialogStore).dialogHistory, (dialog, index) => {
2284
+ return withDirectives((openBlock(), createBlock(resolveDynamicComponent(dialog.dialog), mergeProps({
2285
+ class: "bd-scale scroll",
2286
+ role: "dialog",
2287
+ ref_for: true
2288
+ }, dialog.props), null, 16)), [
2289
+ [vShow, index === unref(dialogStore).dialogHistory.length - 1]
2290
+ ]);
2291
+ }), 256))
2292
+ ], 32)) : createCommentVNode("", true)
1556
2293
  ]),
1557
- _: 3
1558
- }, 8, ["name"])
2294
+ _: 1
2295
+ })
1559
2296
  ]);
1560
2297
  };
1561
2298
  }
1562
2299
  });
1563
- const _hoisted_1$c = {
1564
- key: 0,
1565
- class: "v-form-control__label"
2300
+ const _hoisted_1$b = {
2301
+ class: "v-dialog scroll editor-component",
2302
+ role: "dialog"
1566
2303
  };
1567
- const _hoisted_2$3 = {
2304
+ const _hoisted_2$5 = {
1568
2305
  key: 0,
1569
- class: "v-form-control__required-marker"
2306
+ class: "v-dialog__header heading"
1570
2307
  };
1571
2308
  const _hoisted_3$3 = {
1572
2309
  key: 1,
1573
- class: "v-form-control__outline"
1574
- };
1575
- const _hoisted_4$3 = {
1576
- key: 3,
1577
- class: "v-form-control__actions"
1578
- };
1579
- const _hoisted_5$1 = {
1580
- key: 0,
1581
- class: "v-form-control__error"
2310
+ class: "v-dialog__actions"
1582
2311
  };
1583
- const _sfc_main$e = /* @__PURE__ */ defineComponent({
1584
- __name: "VFormControl",
2312
+ const _sfc_main$d = /* @__PURE__ */ defineComponent({
2313
+ __name: "VDialog",
1585
2314
  props: {
1586
- error: {},
1587
- label: {},
1588
- required: { type: Boolean },
1589
- disabled: { type: Boolean },
1590
- outline: { type: Boolean }
2315
+ "content:class": {}
1591
2316
  },
1592
2317
  setup(__props) {
2318
+ const slots = useSlots();
1593
2319
  const props = __props;
1594
- const error = computed(() => {
1595
- if (!props.error) return "";
1596
- const code = props.error["code"];
1597
- if (code) {
1598
- return props.error.message ?? "";
1599
- }
1600
- return props.error.message ?? "Произошла ошибка";
1601
- });
2320
+ const dialog = useDialog();
1602
2321
  return (_ctx, _cache) => {
1603
- return openBlock(), createElementBlock("div", {
1604
- class: normalizeClass(["v-form-control", { error: !!props.error, disabled: props.disabled }])
1605
- }, [
1606
- !!props.label ? (openBlock(), createElementBlock("label", _hoisted_1$c, [
1607
- createTextVNode(toDisplayString(props.label), 1),
1608
- props.required ? (openBlock(), createElementBlock("span", _hoisted_2$3, "*")) : createCommentVNode("", true)
2322
+ return openBlock(), createElementBlock("div", _hoisted_1$b, [
2323
+ unref(slots).header ? (openBlock(), createElementBlock("div", _hoisted_2$5, [
2324
+ renderSlot(_ctx.$slots, "header"),
2325
+ createVNode(VIconButton, {
2326
+ class: "close-icon",
2327
+ onClick: unref(dialog).close
2328
+ }, {
2329
+ default: withCtx(() => [
2330
+ createVNode(CloseMinIcon)
2331
+ ]),
2332
+ _: 1
2333
+ }, 8, ["onClick"])
1609
2334
  ])) : createCommentVNode("", true),
1610
- props.outline ? (openBlock(), createElementBlock("div", _hoisted_3$3, [
2335
+ createElementVNode("div", {
2336
+ class: normalizeClass(["v-dialog__content", [props["content:class"], unref(slots).actions ? "" : "bottom-padding"]])
2337
+ }, [
1611
2338
  renderSlot(_ctx.$slots, "default")
1612
- ])) : renderSlot(_ctx.$slots, "default", { key: 2 }),
1613
- _ctx.$slots.actions ? (openBlock(), createElementBlock("div", _hoisted_4$3, [
2339
+ ], 2),
2340
+ unref(slots).actions ? (openBlock(), createElementBlock("div", _hoisted_3$3, [
1614
2341
  renderSlot(_ctx.$slots, "actions")
1615
- ])) : createCommentVNode("", true),
1616
- createVNode(Transition, null, {
1617
- default: withCtx(() => [
1618
- !!props.error ? (openBlock(), createElementBlock("div", _hoisted_5$1, toDisplayString(error.value), 1)) : createCommentVNode("", true)
1619
- ]),
1620
- _: 1
1621
- })
1622
- ], 2);
2342
+ ])) : createCommentVNode("", true)
2343
+ ]);
1623
2344
  };
1624
2345
  }
1625
2346
  });
1626
- const _hoisted_1$b = {
2347
+ const _hoisted_1$a = {
1627
2348
  key: 0,
1628
- class: "v-input__start-adornment"
2349
+ class: "project-images__grid"
1629
2350
  };
1630
- const _hoisted_2$2 = ["placeholder", "rows", "name"];
1631
- const _hoisted_3$2 = ["placeholder", "type", "name"];
1632
- const _hoisted_4$2 = {
1633
- key: 3,
1634
- class: "v-input__max-length"
2351
+ const _hoisted_2$4 = ["onClick"];
2352
+ const _hoisted_3$2 = ["src"];
2353
+ const _sfc_main$c = /* @__PURE__ */ defineComponent({
2354
+ __name: "ProjectImagesDialog",
2355
+ props: {
2356
+ fileRequest: { type: Function },
2357
+ onOpenImage: { type: Function }
2358
+ },
2359
+ setup(__props) {
2360
+ const props = __props;
2361
+ const { data } = useRequest(props.fileRequest);
2362
+ const dialog = useDialog();
2363
+ const openImage = (item) => {
2364
+ props.onOpenImage(item);
2365
+ dialog.back();
2366
+ };
2367
+ return (_ctx, _cache) => {
2368
+ return openBlock(), createBlock(_sfc_main$d, { style: { "width": "900px" } }, {
2369
+ header: withCtx(() => _cache[0] || (_cache[0] = [
2370
+ createTextVNode("Изображения проекта")
2371
+ ])),
2372
+ default: withCtx(() => [
2373
+ unref(data) ? (openBlock(), createElementBlock("div", _hoisted_1$a, [
2374
+ (openBlock(true), createElementBlock(Fragment, null, renderList(unref(data), (item) => {
2375
+ return openBlock(), createElementBlock("button", {
2376
+ onClick: ($event) => openImage(item)
2377
+ }, [
2378
+ createElementVNode("img", {
2379
+ src: item.previewSrc ?? item.src
2380
+ }, null, 8, _hoisted_3$2)
2381
+ ], 8, _hoisted_2$4);
2382
+ }), 256))
2383
+ ])) : createCommentVNode("", true)
2384
+ ]),
2385
+ _: 1
2386
+ });
2387
+ };
2388
+ }
2389
+ });
2390
+ const _hoisted_1$9 = {
2391
+ key: 0,
2392
+ class: "v-image-uploader__drag-label"
1635
2393
  };
1636
- const _sfc_main$d = /* @__PURE__ */ defineComponent({
1637
- __name: "VInput",
2394
+ const _hoisted_2$3 = { class: "v-image-uploader__image-preview" };
2395
+ const _hoisted_3$1 = ["src"];
2396
+ const _hoisted_4 = { class: "v-image-uploader__image-info" };
2397
+ const _sfc_main$b = /* @__PURE__ */ defineComponent({
2398
+ __name: "VImageUploader",
1638
2399
  props: {
2400
+ accept: {},
2401
+ schema: {},
1639
2402
  modelValue: {},
1640
- multiline: { type: Boolean },
1641
- autofocus: { type: Boolean },
1642
- rows: {},
1643
- placeholder: {},
1644
- type: {},
1645
- name: {},
1646
- large: { type: Boolean },
1647
- maxLength: {},
1648
- validator: { type: Function },
1649
2403
  error: {},
1650
2404
  label: {},
1651
2405
  required: { type: Boolean },
1652
2406
  disabled: { type: Boolean }
1653
- },
1654
- emits: ["update:modelValue"],
1655
- setup(__props, { emit: __emit }) {
1656
- const props = __props;
1657
- const emit = __emit;
1658
- const parse = (value) => {
1659
- if (props.validator) {
1660
- return props.validator(value);
1661
- }
1662
- if (props.type === "number") {
1663
- const val = parseFloat(value);
1664
- if (isNaN(val)) return null;
1665
- return val;
1666
- }
1667
- if (props.type === "integer") {
1668
- const val = parseInt(value);
1669
- if (isNaN(val)) return null;
1670
- return val;
2407
+ },
2408
+ emits: ["update:modelValue"],
2409
+ setup(__props, { emit: __emit }) {
2410
+ const props = __props;
2411
+ const emit = __emit;
2412
+ const fileUploader = inject("fileUploader");
2413
+ const fileRequest = inject("fileRequest", null);
2414
+ const addFile = async (file) => {
2415
+ emit("update:modelValue", { src: URL.createObjectURL(file), file, name: file.name });
2416
+ if (fileUploader) {
2417
+ const resp = await fileUploader(file);
2418
+ emit("update:modelValue", { src: resp.src, previewSrc: resp.previewSrc, name: resp.name });
1671
2419
  }
1672
- return value;
1673
2420
  };
1674
- let lastValue = "";
1675
- const model = ref("");
1676
- watch(() => props.modelValue, (value) => {
1677
- if (value === lastValue) return;
1678
- model.value = (value ?? "").toString();
1679
- }, { immediate: true });
1680
- watch(() => model.value, (modelValue) => {
1681
- const val = parse(modelValue);
1682
- lastValue = val;
1683
- emit("update:modelValue", val);
1684
- });
1685
- const error = computed(() => {
1686
- if ((props.type === "number" || props.type === "integer") && model.value && props.modelValue === null) {
1687
- return { message: "Введите числовое значение" };
2421
+ const drag = ref(false);
2422
+ const onDragOver = (e) => {
2423
+ var _a, _b, _c;
2424
+ if ((_c = (_b = (_a = e.dataTransfer) == null ? void 0 : _a.types) == null ? void 0 : _b[0]) == null ? void 0 : _c.startsWith("text")) return;
2425
+ e.preventDefault();
2426
+ drag.value = true;
2427
+ };
2428
+ const onDragLeave = (e) => {
2429
+ var _a;
2430
+ if (e.relatedTarget === e.currentTarget || ((_a = e.relatedTarget) == null ? void 0 : _a.parentElement) === e.currentTarget) return;
2431
+ drag.value = false;
2432
+ };
2433
+ const onDrop = (e) => {
2434
+ e.preventDefault();
2435
+ drag.value = false;
2436
+ for (const item of e.dataTransfer.items) {
2437
+ if (item.kind !== "file") continue;
2438
+ const file = item.getAsFile();
2439
+ if (!file) continue;
2440
+ addFile(file);
1688
2441
  }
1689
- return props.error;
1690
- });
1691
- const inputType = computed(() => {
1692
- if (props.type !== "phone" && props.type !== "number" && props.type !== "integer") return props.type;
1693
- return void 0;
2442
+ };
2443
+ const fileDialog = useFileDialog({
2444
+ accept: props.accept ?? "image/*",
2445
+ multiple: false
1694
2446
  });
1695
- const inputRef = ref();
1696
- onMounted(() => {
1697
- var _a;
1698
- if (props.autofocus || props.error) {
1699
- (_a = inputRef.value) == null ? void 0 : _a.focus();
2447
+ fileDialog.onChange((files) => {
2448
+ if (!files || files.length === 0) return;
2449
+ for (const file of files) {
2450
+ addFile(file);
1700
2451
  }
2452
+ fileDialog.reset();
1701
2453
  });
1702
- if (props.multiline) {
1703
- useTextareaAutosize({ element: inputRef, input: model });
2454
+ const removeImage = () => {
2455
+ emit("update:modelValue", getDefaultValue(props.schema));
2456
+ };
2457
+ const dialog = useDialog();
2458
+ const contextMenuItems = [];
2459
+ const onOpenImage = (image) => {
2460
+ emit("update:modelValue", image);
2461
+ };
2462
+ if (fileRequest) {
2463
+ contextMenuItems.push({ title: "Выбрать из файлов проекта", onClick: () => dialog.open(_sfc_main$c, { fileRequest, onOpenImage }) });
1704
2464
  }
1705
2465
  return (_ctx, _cache) => {
1706
- return openBlock(), createBlock(_sfc_main$e, {
1707
- class: normalizeClass(["v-input", { large: _ctx.large, multiline: _ctx.multiline }]),
1708
- error: error.value,
2466
+ return openBlock(), createBlock(_sfc_main$v, {
2467
+ class: normalizeClass(["v-image-uploader", { drag: drag.value }]),
2468
+ error: _ctx.error,
1709
2469
  label: _ctx.label,
1710
2470
  required: _ctx.required,
1711
2471
  disabled: _ctx.disabled,
1712
- outline: ""
1713
- }, createSlots({
2472
+ outline: "",
2473
+ onDrop,
2474
+ onDragover: onDragOver,
2475
+ onDragleave: onDragLeave
2476
+ }, {
1714
2477
  default: withCtx(() => [
1715
- renderSlot(_ctx.$slots, "start-adornment"),
1716
- _ctx.type === "phone" ? (openBlock(), createElementBlock("div", _hoisted_1$b, "+7")) : createCommentVNode("", true),
1717
- props.multiline ? withDirectives((openBlock(), createElementBlock("textarea", {
1718
- key: 1,
1719
- ref_key: "inputRef",
1720
- ref: inputRef,
1721
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => model.value = $event),
1722
- placeholder: props.placeholder,
1723
- rows: props.rows,
1724
- class: "scroll",
1725
- name: props.name
1726
- }, null, 8, _hoisted_2$2)), [
1727
- [vModelText, model.value]
1728
- ]) : withDirectives((openBlock(), createElementBlock("input", {
1729
- key: 2,
1730
- ref_key: "inputRef",
1731
- ref: inputRef,
1732
- "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => model.value = $event),
1733
- placeholder: props.placeholder,
1734
- type: inputType.value,
1735
- name: props.name
1736
- }, null, 8, _hoisted_3$2)), [
1737
- [vModelDynamic, model.value]
1738
- ]),
1739
- props.maxLength ? (openBlock(), createElementBlock("div", _hoisted_4$2, toDisplayString(model.value.length) + " / " + toDisplayString(props.maxLength), 1)) : createCommentVNode("", true),
1740
- renderSlot(_ctx.$slots, "end-adornment")
2478
+ drag.value ? (openBlock(), createElementBlock("div", _hoisted_1$9, "Отпустите файл здесь")) : !props.modelValue || props.modelValue.src === unref(defaultImageSrc) ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [
2479
+ createVNode(EmptyFileIcon),
2480
+ createElementVNode("div", null, [
2481
+ createElementVNode("a", {
2482
+ onClick: _cache[0] || (_cache[0] = ($event) => unref(fileDialog).open())
2483
+ }, "Загрузите изображение"),
2484
+ _cache[1] || (_cache[1] = createElementVNode("br", null, null, -1)),
2485
+ _cache[2] || (_cache[2] = createTextVNode("или перетащите сюда ")),
2486
+ contextMenuItems.length > 0 ? (openBlock(), createBlock(_sfc_main$f, {
2487
+ key: 0,
2488
+ items: contextMenuItems,
2489
+ placement: "bottom-end"
2490
+ }, {
2491
+ activator: withCtx(({ props: props2 }) => [
2492
+ createVNode(VIconButton, mergeProps(props2, { class: "v-image-uploader__more-button" }), {
2493
+ default: withCtx(() => [
2494
+ createVNode(MoreIcon)
2495
+ ]),
2496
+ _: 2
2497
+ }, 1040)
2498
+ ]),
2499
+ _: 1
2500
+ })) : createCommentVNode("", true)
2501
+ ])
2502
+ ], 64)) : (openBlock(), createElementBlock(Fragment, { key: 2 }, [
2503
+ createElementVNode("div", _hoisted_2$3, [
2504
+ createElementVNode("img", {
2505
+ src: props.modelValue.previewSrc ?? props.modelValue.src,
2506
+ alt: "Preview Image"
2507
+ }, null, 8, _hoisted_3$1),
2508
+ createVNode(VIconButton, {
2509
+ class: "v-image-uploader__delete-button",
2510
+ onClick: removeImage
2511
+ }, {
2512
+ default: withCtx(() => [
2513
+ createVNode(CloseMinIcon)
2514
+ ]),
2515
+ _: 1
2516
+ })
2517
+ ]),
2518
+ createElementVNode("div", _hoisted_4, [
2519
+ createElementVNode("div", null, toDisplayString(props.modelValue.name), 1)
2520
+ ])
2521
+ ], 64))
1741
2522
  ]),
1742
- _: 2
1743
- }, [
1744
- _ctx.$slots.actions ? {
1745
- name: "actions",
1746
- fn: withCtx(() => [
1747
- renderSlot(_ctx.$slots, "actions")
1748
- ]),
1749
- key: "0"
1750
- } : void 0
1751
- ]), 1032, ["error", "label", "required", "disabled", "class"]);
2523
+ _: 1
2524
+ }, 8, ["class", "error", "label", "required", "disabled"]);
1752
2525
  };
1753
2526
  }
1754
2527
  });
1755
- const _export_sfc = (sfc, props) => {
1756
- const target = sfc.__vccOpts || sfc;
1757
- for (const [key, val] of props) {
1758
- target[key] = val;
1759
- }
1760
- return target;
1761
- };
1762
- const _sfc_main$c = {};
1763
- const _hoisted_1$a = {
1764
- width: "20",
1765
- height: "20",
1766
- viewBox: "0 0 20 20",
2528
+ const _sfc_main$a = {};
2529
+ const _hoisted_1$8 = {
2530
+ width: "18",
2531
+ height: "18",
2532
+ viewBox: "0 0 18 18",
1767
2533
  fill: "none",
1768
2534
  xmlns: "http://www.w3.org/2000/svg"
1769
2535
  };
1770
- function _sfc_render$5(_ctx, _cache) {
1771
- return openBlock(), createElementBlock("svg", _hoisted_1$a, _cache[0] || (_cache[0] = [
2536
+ function _sfc_render$1(_ctx, _cache) {
2537
+ return openBlock(), createElementBlock("svg", _hoisted_1$8, _cache[0] || (_cache[0] = [
1772
2538
  createElementVNode("path", {
1773
- "fill-rule": "evenodd",
1774
- "clip-rule": "evenodd",
1775
- d: "M7.5001 14.1665C7.50013 14.3313 7.54902 14.4924 7.64059 14.6294C7.73217 14.7664 7.8623 14.8732 8.01455 14.9362C8.1668 14.9993 8.33433 15.0158 8.49596 14.9836C8.65758 14.9515 8.80605 14.8722 8.9226 14.7557L13.0893 10.589C13.2455 10.4327 13.3333 10.2208 13.3333 9.99982C13.3333 9.77885 13.2455 9.56693 13.0893 9.41066L8.9226 5.24399C8.80605 5.12748 8.65758 5.04814 8.49596 5.016C8.33433 4.98386 8.1668 5.00037 8.01455 5.06342C7.8623 5.12648 7.73217 5.23327 7.6406 5.37027C7.54902 5.50728 7.50013 5.66836 7.5001 5.83316L7.5001 14.1665Z",
2539
+ d: "M14.0326 5.40749C13.9629 5.33719 13.8799 5.28139 13.7885 5.24332C13.6971 5.20524 13.5991 5.18564 13.5001 5.18564C13.4011 5.18564 13.303 5.20524 13.2117 5.24332C13.1203 5.28139 13.0373 5.33719 12.9676 5.40749L7.38008 11.0025L5.03258 8.64749C4.96019 8.57756 4.87474 8.52257 4.7811 8.48567C4.68745 8.44877 4.58746 8.43067 4.48683 8.43241C4.38619 8.43415 4.28688 8.4557 4.19457 8.49582C4.10227 8.53594 4.01876 8.59385 3.94883 8.66624C3.87891 8.73863 3.82392 8.82408 3.78702 8.91773C3.75011 9.01137 3.73202 9.11136 3.73376 9.212C3.7355 9.31263 3.75704 9.41194 3.79716 9.50425C3.83728 9.59656 3.89519 9.68006 3.96758 9.74999L6.84758 12.63C6.91731 12.7003 7.00026 12.7561 7.09165 12.7942C7.18305 12.8322 7.28108 12.8518 7.38008 12.8518C7.47909 12.8518 7.57712 12.8322 7.66852 12.7942C7.75991 12.7561 7.84286 12.7003 7.91258 12.63L14.0326 6.50999C14.1087 6.43976 14.1695 6.35452 14.211 6.25964C14.2526 6.16477 14.274 6.06231 14.274 5.95874C14.274 5.85516 14.2526 5.75271 14.211 5.65783C14.1695 5.56296 14.1087 5.47772 14.0326 5.40749Z",
1776
2540
  fill: "currentColor"
1777
2541
  }, null, -1)
1778
2542
  ]));
1779
2543
  }
1780
- const CollapseArrowIcon = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["render", _sfc_render$5]]);
1781
- const _sfc_main$b = /* @__PURE__ */ defineComponent({
1782
- __name: "VCollapse",
1783
- props: {
1784
- open: { type: Boolean },
2544
+ const CheckIcon = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["render", _sfc_render$1]]);
2545
+ const _hoisted_1$7 = {
2546
+ key: 0,
2547
+ class: "v-checkbox__label left"
2548
+ };
2549
+ const _hoisted_2$2 = ["name"];
2550
+ const _hoisted_3 = {
2551
+ key: 1,
2552
+ class: "v-checkbox__label"
2553
+ };
2554
+ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
2555
+ __name: "VCheckbox",
2556
+ props: /* @__PURE__ */ mergeModels({
1785
2557
  label: {},
1786
- withPadding: { type: Boolean }
1787
- },
1788
- emits: ["update:open"],
1789
- setup(__props, { emit: __emit }) {
2558
+ name: {},
2559
+ labelPosition: {}
2560
+ }, {
2561
+ "modelValue": { type: Boolean },
2562
+ "modelModifiers": {}
2563
+ }),
2564
+ emits: ["update:modelValue"],
2565
+ setup(__props) {
1790
2566
  const props = __props;
1791
- const emit = __emit;
1792
- const height = ref(0);
1793
- const open = ref(props.open ?? false);
1794
- const transition = ref(false);
1795
- const innerRef = ref();
1796
- let hideTimeout = null;
1797
- const setOpen = async (value) => {
1798
- open.value = value;
1799
- if (hideTimeout !== null) {
1800
- clearTimeout(hideTimeout);
1801
- hideTimeout = null;
1802
- }
1803
- if (open.value === false && innerRef.value) {
1804
- height.value = innerRef.value.clientHeight;
1805
- }
1806
- transition.value = true;
1807
- await nextTick();
1808
- await new Promise((res) => requestAnimationFrame(res));
1809
- if (open.value) {
1810
- height.value = innerRef.value.clientHeight;
1811
- } else {
1812
- height.value = 0;
1813
- }
1814
- hideTimeout = setTimeout(() => {
1815
- transition.value = false;
1816
- }, 200);
1817
- setTimeout(() => mouseMove = true, 0);
1818
- emit("update:open", open.value);
1819
- };
1820
- const onClick = async () => {
1821
- setOpen(!open.value);
2567
+ const model = useModel(__props, "modelValue");
2568
+ const onClick = (e) => {
2569
+ var _a;
2570
+ if (e instanceof KeyboardEvent && e.code !== "Enter") return;
2571
+ (_a = e.currentTarget.querySelector("input")) == null ? void 0 : _a.click();
1822
2572
  };
1823
- watch(() => props.open, (value) => {
1824
- if (typeof value !== "boolean" || open.value === value) return;
1825
- setOpen(value);
2573
+ const slots = useSlots();
2574
+ const labelPosition = computed(() => {
2575
+ if (!props.label && !slots.label) return "none";
2576
+ if (props.labelPosition === "left") return "left";
2577
+ return "right";
1826
2578
  });
1827
- let mouseMove = false;
1828
- useEventListener("mousedown", () => mouseMove = false);
1829
- const onMouseEnter = (e) => {
1830
- if (e.buttons > 0 && !mouseMove && !document.body.classList.contains("mousedrag")) {
1831
- mouseMove = true;
1832
- onClick();
1833
- }
1834
- };
1835
2579
  return (_ctx, _cache) => {
1836
2580
  return openBlock(), createElementBlock("div", {
1837
- class: normalizeClass(["v-collapse", { open: open.value }])
2581
+ class: normalizeClass(["v-checkbox", { active: model.value }]),
2582
+ role: "checkbox",
2583
+ onClick,
2584
+ onKeydown: onClick
1838
2585
  }, [
1839
- renderSlot(_ctx.$slots, "activator", {
1840
- props: { onClick, open: open.value }
1841
- }, () => [
1842
- createElementVNode("div", {
1843
- class: normalizeClass(["v-collapse__activator", { open: open.value }]),
1844
- onMousedown: onClick,
1845
- onMouseenter: onMouseEnter
1846
- }, [
1847
- createVNode(CollapseArrowIcon),
1848
- createElementVNode("div", null, toDisplayString(props.label), 1)
1849
- ], 34)
1850
- ]),
2586
+ labelPosition.value === "left" ? (openBlock(), createElementBlock("div", _hoisted_1$7, [
2587
+ renderSlot(_ctx.$slots, "label", {}, () => [
2588
+ createTextVNode(toDisplayString(props.label), 1)
2589
+ ])
2590
+ ])) : createCommentVNode("", true),
1851
2591
  createElementVNode("div", {
1852
- class: normalizeClass(["v-collapse__content", { "v-transition": transition.value, withPadding: props.withPadding }]),
1853
- style: normalizeStyle(transition.value ? { height: `${height.value}px` } : void 0)
2592
+ class: normalizeClass(["v-checkbox__icon", { active: model.value }])
1854
2593
  }, [
1855
- transition.value || open.value ? (openBlock(), createElementBlock("div", {
1856
- key: 0,
1857
- ref_key: "innerRef",
1858
- ref: innerRef,
1859
- class: "v-collapse__content-inner"
1860
- }, [
1861
- renderSlot(_ctx.$slots, "default")
1862
- ], 512)) : createCommentVNode("", true)
1863
- ], 6)
1864
- ], 2);
2594
+ createVNode(CheckIcon)
2595
+ ], 2),
2596
+ withDirectives(createElementVNode("input", {
2597
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => model.value = $event),
2598
+ type: "checkbox",
2599
+ name: props.name
2600
+ }, null, 8, _hoisted_2$2), [
2601
+ [vModelCheckbox, model.value]
2602
+ ]),
2603
+ labelPosition.value === "right" ? (openBlock(), createElementBlock("div", _hoisted_3, [
2604
+ renderSlot(_ctx.$slots, "label", {}, () => [
2605
+ createTextVNode(toDisplayString(props.label), 1)
2606
+ ])
2607
+ ])) : createCommentVNode("", true)
2608
+ ], 34);
1865
2609
  };
1866
2610
  }
1867
2611
  });
1868
- const _sfc_main$a = {};
1869
- const _hoisted_1$9 = {
1870
- width: "16",
1871
- height: "16",
1872
- viewBox: "0 0 16 16",
2612
+ const getBlockName = (path) => {
2613
+ if (!path) return void 0;
2614
+ const str = path.split("/").at(-1);
2615
+ return (str == null ? void 0 : str.split(".", 1)[0].replace(/([A-Z])/g, " $1").trimStart()) ?? "Unnamed block";
2616
+ };
2617
+ const capitalize = (text) => {
2618
+ return text[0].toUpperCase() + text.slice(1);
2619
+ };
2620
+ const spaceCamelCase = (str) => {
2621
+ return capitalize(str.replace(/([A-Z])/g, " $1").trimStart());
2622
+ };
2623
+ const _sfc_main$8 = {};
2624
+ const _hoisted_1$6 = {
2625
+ width: "24",
2626
+ height: "24",
2627
+ viewBox: "0 0 24 24",
1873
2628
  fill: "none",
1874
2629
  xmlns: "http://www.w3.org/2000/svg"
1875
2630
  };
1876
- function _sfc_render$4(_ctx, _cache) {
1877
- return openBlock(), createElementBlock("svg", _hoisted_1$9, _cache[0] || (_cache[0] = [
2631
+ function _sfc_render(_ctx, _cache) {
2632
+ return openBlock(), createElementBlock("svg", _hoisted_1$6, _cache[0] || (_cache[0] = [
1878
2633
  createElementVNode("path", {
1879
- d: "M14.364 5.293C14.1764 5.10553 13.9221 5.00021 13.657 5.00021C13.3918 5.00021 13.1375 5.10553 12.95 5.293L7.99995 10.243L3.04995 5.293C2.86135 5.11084 2.60875 5.01005 2.34655 5.01232C2.08435 5.0146 1.83354 5.11977 1.64813 5.30518C1.46272 5.49059 1.35756 5.7414 1.35528 6.0036C1.353 6.26579 1.45379 6.5184 1.63595 6.707L7.29295 12.364C7.48048 12.5515 7.73479 12.6568 7.99995 12.6568C8.26512 12.6568 8.51942 12.5515 8.70695 12.364L14.364 6.707C14.5514 6.51947 14.6567 6.26516 14.6567 6C14.6567 5.73483 14.5514 5.48053 14.364 5.293Z",
2634
+ "fill-rule": "evenodd",
2635
+ "clip-rule": "evenodd",
2636
+ d: "M13.8961 3.02922C14.25 2.67528 14.7238 2.4669 15.2238 2.44523C15.7239 2.42357 16.2139 2.5902 16.5971 2.91222L16.7241 3.02922L20.9671 7.27222C21.3208 7.62608 21.529 8.09964 21.5506 8.59947C21.5723 9.0993 21.4058 9.5891 21.0841 9.97222L20.9671 10.1002L10.6531 20.4142C10.3211 20.7462 9.88282 20.9509 9.41509 20.9922L9.23909 20.9992H4.00609C3.75727 20.9992 3.5172 20.9074 3.33192 20.7413C3.14664 20.5752 3.02919 20.3466 3.00209 20.0992L2.99609 19.9892V14.7562C2.99621 14.2867 3.16153 13.8321 3.46309 13.4722L3.58309 13.3422L13.8961 3.02922ZM12.1701 7.58322L4.99609 14.7572V18.9992H9.24009L16.4141 11.8252L12.1711 7.58222L12.1701 7.58322ZM15.3101 4.44322L13.5841 6.16922L17.8271 10.4122L19.5531 8.68622L15.3101 4.44322Z",
1880
2637
  fill: "currentColor"
1881
2638
  }, null, -1)
1882
2639
  ]));
1883
2640
  }
1884
- const ArrowDownIcon = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["render", _sfc_render$4]]);
1885
- const _hoisted_1$8 = { key: 0 };
1886
- const _hoisted_2$1 = {
1887
- key: 1,
1888
- class: "v-select__placeholder"
1889
- };
1890
- const _hoisted_3$1 = { class: "v-select__menu" };
1891
- const _hoisted_4$1 = {
1892
- key: 0,
1893
- class: "group-title"
1894
- };
1895
- const _hoisted_5 = ["onClick"];
1896
- const _sfc_main$9 = /* @__PURE__ */ defineComponent({
1897
- __name: "VSelect",
1898
- props: {
1899
- items: {},
1900
- modelValue: {},
1901
- placeholder: {},
1902
- nullable: { type: Boolean },
1903
- error: {},
1904
- label: {},
1905
- required: { type: Boolean },
1906
- disabled: { type: Boolean }
1907
- },
2641
+ const EditIcon = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render]]);
2642
+ const _hoisted_1$5 = { class: "v-link-editor__custom" };
2643
+ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
2644
+ __name: "VLinkEditor",
2645
+ props: /* @__PURE__ */ mergeModels({
2646
+ nullable: { type: Boolean }
2647
+ }, {
2648
+ "modelValue": {},
2649
+ "modelModifiers": {}
2650
+ }),
1908
2651
  emits: ["update:modelValue"],
1909
- setup(__props, { emit: __emit }) {
2652
+ setup(__props) {
1910
2653
  const props = __props;
1911
- const emit = __emit;
1912
- const model = useVModel(props, "modelValue", emit, { passive: true, defaultValue: null });
1913
- const currentItem = computed(() => {
1914
- if (model.value === null) return null;
1915
- return props.items.find((item) => typeof item !== "string" && item.id === model.value) ?? null;
2654
+ const model = useModel(__props, "modelValue");
2655
+ const pagesRequest = inject("pagesRequest");
2656
+ const { data } = useRequest(pagesRequest);
2657
+ const linkType = ref();
2658
+ if (model.value && model.value.id) {
2659
+ linkType.value = model.value.id;
2660
+ }
2661
+ const current = getCurrentInstance();
2662
+ watch(linkType, (type) => {
2663
+ if (type === "_external") return;
2664
+ if (type === null) {
2665
+ if (props.nullable) {
2666
+ model.value = null;
2667
+ } else {
2668
+ model.value = { id: "", title: "" };
2669
+ }
2670
+ return;
2671
+ }
2672
+ if (type === "_externalNew") {
2673
+ model.value = { id: "_external", url: "", title: "" };
2674
+ nextTick(() => {
2675
+ const editButton = (current == null ? void 0 : current.vnode.el).querySelector(".edit-button");
2676
+ editButton == null ? void 0 : editButton.dispatchEvent(new MouseEvent("mousedown"));
2677
+ linkType.value = "_external";
2678
+ });
2679
+ } else {
2680
+ const page = data.value.find((item) => item.id === type);
2681
+ model.value = { ...page };
2682
+ }
1916
2683
  });
1917
- const items = computed(() => {
1918
- return props.items;
2684
+ const linkTypes = computed(() => {
2685
+ const arr = [
2686
+ { id: "_externalNew", title: "Внешняя страница..." }
2687
+ ];
2688
+ if (model.value && model.value.id === "_external") {
2689
+ arr.push({ id: "_external", title: model.value.title ? `${model.value.title} [${model.value.url}]` : model.value.url || "Внешняя страница" });
2690
+ }
2691
+ if (data.value) {
2692
+ arr.push("");
2693
+ arr.push(...data.value);
2694
+ }
2695
+ return arr;
1919
2696
  });
1920
- const opened = ref(false);
1921
- const onItemClick = (item) => {
1922
- model.value = item.id;
1923
- opened.value = false;
1924
- };
1925
- const resetValue = () => {
1926
- model.value = null;
1927
- opened.value = false;
1928
- };
1929
2697
  return (_ctx, _cache) => {
1930
- return openBlock(), createBlock(_sfc_main$e, {
1931
- outline: "",
1932
- class: "v-select",
1933
- label: props.label,
1934
- error: props.error,
1935
- disabled: props.disabled,
1936
- required: props.required
2698
+ return openBlock(), createBlock(_sfc_main$k, {
2699
+ class: "v-link-editor",
2700
+ modelValue: linkType.value,
2701
+ "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => linkType.value = $event),
2702
+ items: linkTypes.value,
2703
+ nullable: props.nullable
1937
2704
  }, {
1938
2705
  default: withCtx(() => [
1939
- createVNode(_sfc_main$l, {
1940
- open: opened.value,
1941
- "onUpdate:open": _cache[0] || (_cache[0] = ($event) => opened.value = $event),
1942
- placement: "bottom",
1943
- "fit-anchor": "",
1944
- offset: 8
2706
+ model.value && model.value.id ? (openBlock(), createBlock(_sfc_main$o, {
2707
+ key: 0,
2708
+ offset: 4,
2709
+ placement: "bottom-end"
1945
2710
  }, {
1946
- activator: withCtx(({ props: activatorProps }) => [
1947
- createElementVNode("button", mergeProps({
1948
- class: ["v-select__activator", { opened: opened.value }]
1949
- }, activatorProps), [
1950
- currentItem.value ? (openBlock(), createElementBlock("div", _hoisted_1$8, toDisplayString(currentItem.value.title), 1)) : (openBlock(), createElementBlock("div", _hoisted_2$1, toDisplayString(props.placeholder ?? "Выберите значение"), 1)),
1951
- createVNode(ArrowDownIcon)
1952
- ], 16)
1953
- ]),
1954
- default: withCtx(() => [
1955
- createElementVNode("div", _hoisted_3$1, [
1956
- props.nullable ? (openBlock(), createElementBlock("button", {
1957
- key: 0,
1958
- class: "nullable-item",
1959
- onClick: resetValue
1960
- }, " Пустое значение ")) : createCommentVNode("", true),
1961
- (openBlock(true), createElementBlock(Fragment, null, renderList(items.value, (item) => {
1962
- return openBlock(), createElementBlock(Fragment, null, [
1963
- typeof item === "string" ? (openBlock(), createElementBlock("div", _hoisted_4$1, toDisplayString(item), 1)) : (openBlock(), createElementBlock("button", {
1964
- key: 1,
1965
- onClick: ($event) => onItemClick(item)
1966
- }, [
1967
- renderSlot(_ctx.$slots, "item", { item }, () => [
1968
- createTextVNode(toDisplayString(item.title), 1)
1969
- ])
1970
- ], 8, _hoisted_5))
1971
- ], 64);
1972
- }), 256))
1973
- ])
2711
+ activator: withCtx(({ props: props2 }) => [
2712
+ createVNode(VIconButton, mergeProps(props2, { class: "edit-button" }), {
2713
+ default: withCtx(() => [
2714
+ createVNode(EditIcon)
2715
+ ]),
2716
+ _: 2
2717
+ }, 1040)
1974
2718
  ]),
1975
- _: 3
1976
- }, 8, ["open"])
2719
+ default: withCtx(() => {
2720
+ var _a;
2721
+ return [
2722
+ createElementVNode("div", _hoisted_1$5, [
2723
+ model.value.id === "_external" ? (openBlock(), createBlock(_sfc_main$u, {
2724
+ key: 0,
2725
+ modelValue: model.value.url,
2726
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => model.value.url = $event),
2727
+ label: "URL ссылки",
2728
+ autofocus: ""
2729
+ }, null, 8, ["modelValue"])) : createCommentVNode("", true),
2730
+ model.value.id !== "_external" ? (openBlock(), createBlock(_sfc_main$u, {
2731
+ key: 1,
2732
+ modelValue: model.value.query,
2733
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => model.value.query = $event),
2734
+ label: "Якорь",
2735
+ prefix: (_a = model.value) == null ? void 0 : _a.url
2736
+ }, null, 8, ["modelValue", "prefix"])) : createCommentVNode("", true),
2737
+ createVNode(_sfc_main$u, {
2738
+ modelValue: model.value.title,
2739
+ "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => model.value.title = $event),
2740
+ label: "Заголовок"
2741
+ }, null, 8, ["modelValue"]),
2742
+ createVNode(_sfc_main$9, {
2743
+ modelValue: model.value.openNewTab,
2744
+ "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => model.value.openNewTab = $event),
2745
+ label: "Открывать в новой вкладке"
2746
+ }, null, 8, ["modelValue"])
2747
+ ])
2748
+ ];
2749
+ }),
2750
+ _: 1
2751
+ })) : createCommentVNode("", true)
1977
2752
  ]),
1978
- _: 3
1979
- }, 8, ["label", "error", "disabled", "required"]);
2753
+ _: 1
2754
+ }, 8, ["modelValue", "items", "nullable"]);
1980
2755
  };
1981
2756
  }
1982
2757
  });
1983
- const _hoisted_1$7 = { class: "json-editor__array" };
1984
- const _sfc_main$8 = /* @__PURE__ */ defineComponent({
1985
- __name: "JsonEditorArray",
1986
- props: {
1987
- label: {},
2758
+ const _hoisted_1$4 = {
2759
+ key: 2,
2760
+ class: "json-editor__object"
2761
+ };
2762
+ const _sfc_main$6 = /* @__PURE__ */ defineComponent({
2763
+ __name: "JsonEditor",
2764
+ props: /* @__PURE__ */ mergeModels({
1988
2765
  schema: {},
1989
- modelValue: {},
1990
- expanded: { type: Boolean }
1991
- },
2766
+ name: {},
2767
+ flat: { type: Boolean },
2768
+ expanded: { type: Boolean },
2769
+ nullable: { type: Boolean }
2770
+ }, {
2771
+ "modelValue": {},
2772
+ "modelModifiers": {}
2773
+ }),
1992
2774
  emits: ["update:modelValue"],
1993
- setup(__props, { emit: __emit }) {
1994
- var _a;
2775
+ setup(__props) {
1995
2776
  const props = __props;
1996
- const emit = __emit;
1997
- const childExpanded = ((_a = props.schema.items) == null ? void 0 : _a.type) === "object" && Object.keys(props.schema.items.properties).length < 2;
1998
- const length = ref(0);
1999
- const tempArray = ref([]);
2000
- if (props.schema.type === "array" && props.modelValue) {
2001
- length.value = props.modelValue.length ?? 0;
2002
- tempArray.value = [...props.modelValue];
2003
- }
2004
- watch(tempArray, () => {
2005
- var _a2;
2006
- if (((_a2 = props.schema.items) == null ? void 0 : _a2.type) === "object" && props.modelValue[0] === tempArray.value[0]) return;
2007
- emit("update:modelValue", tempArray.value.slice(0, length.value));
2008
- }, { deep: true });
2009
- watch(length, (length2) => {
2010
- for (let i = tempArray.value.length; i < length2; i++) {
2011
- tempArray.value[i] = props.schema.items ? getDefaultValue(props.schema.items) : null;
2777
+ const childExpanded = props.schema.type === "object" && Object.keys(props.schema.properties).length < 2;
2778
+ const vModel = useModel(__props, "modelValue");
2779
+ if (vModel.value !== null && vModel.value !== void 0) {
2780
+ if (props.schema.type === "object" && typeof vModel.value !== "object") {
2781
+ vModel.value = getDefaultValue(props.schema);
2012
2782
  }
2013
- emit("update:modelValue", tempArray.value.slice(0, length2));
2014
- });
2015
- const label = computed(() => {
2016
- return `${props.label} (${length.value})`;
2017
- });
2783
+ }
2784
+ const getItems = (schema) => {
2785
+ return schema.enum.map((item, index) => {
2786
+ var _a;
2787
+ return {
2788
+ id: item,
2789
+ title: ((_a = schema.enumAlias) == null ? void 0 : _a[index]) ?? spaceCamelCase(item)
2790
+ };
2791
+ });
2792
+ };
2018
2793
  return (_ctx, _cache) => {
2019
- return openBlock(), createElementBlock("div", _hoisted_1$7, [
2020
- createVNode(_sfc_main$b, {
2021
- label: label.value,
2794
+ const _component_JsonEditor = resolveComponent("JsonEditor", true);
2795
+ return props.schema.type === "object" && props.schema.format === "image" ? (openBlock(), createBlock(_sfc_main$b, {
2796
+ key: 0,
2797
+ modelValue: vModel.value,
2798
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => vModel.value = $event),
2799
+ label: props.schema.name ?? props.name,
2800
+ schema: props.schema
2801
+ }, null, 8, ["modelValue", "label", "schema"])) : props.schema.type === "object" && props.schema.format === "link" ? (openBlock(), createBlock(_sfc_main$7, {
2802
+ key: 1,
2803
+ modelValue: vModel.value,
2804
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => vModel.value = $event),
2805
+ label: props.schema.name ?? props.name,
2806
+ schema: props.schema,
2807
+ nullable: props.schema.nullable || props.nullable
2808
+ }, null, 8, ["modelValue", "label", "schema", "nullable"])) : props.schema.type === "object" ? (openBlock(), createElementBlock("div", _hoisted_1$4, [
2809
+ props.flat ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(props.schema.properties, (item, key) => {
2810
+ var _a;
2811
+ return openBlock(), createBlock(_component_JsonEditor, {
2812
+ modelValue: vModel.value[key],
2813
+ "onUpdate:modelValue": ($event) => vModel.value[key] = $event,
2814
+ key,
2815
+ schema: item,
2816
+ expanded: unref(childExpanded),
2817
+ name: unref(spaceCamelCase)(key),
2818
+ nullable: !((_a = props.schema.required) == null ? void 0 : _a.includes(key))
2819
+ }, null, 8, ["modelValue", "onUpdate:modelValue", "schema", "expanded", "name", "nullable"]);
2820
+ }), 128)) : (openBlock(), createBlock(_sfc_main$p, {
2821
+ key: 1,
2822
+ label: props.schema.name ?? props.name,
2022
2823
  open: props.expanded
2023
2824
  }, {
2024
2825
  default: withCtx(() => [
2025
- createVNode(_sfc_main$d, {
2026
- label: "Количество элементов",
2027
- modelValue: length.value,
2028
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => length.value = $event),
2029
- type: "number"
2030
- }, null, 8, ["modelValue"]),
2031
- (openBlock(true), createElementBlock(Fragment, null, renderList(length.value, (index) => {
2032
- return openBlock(), createBlock(_sfc_main$4, {
2033
- key: index,
2034
- schema: props.schema.items,
2035
- name: `${props.schema.itemName ?? "Элемент"} ${index}`,
2036
- modelValue: tempArray.value[index - 1],
2037
- "onUpdate:modelValue": ($event) => tempArray.value[index - 1] = $event,
2038
- expanded: unref(childExpanded)
2039
- }, null, 8, ["schema", "name", "modelValue", "onUpdate:modelValue", "expanded"]);
2826
+ (openBlock(true), createElementBlock(Fragment, null, renderList(props.schema.properties, (item, key) => {
2827
+ var _a;
2828
+ return openBlock(), createBlock(_component_JsonEditor, {
2829
+ modelValue: vModel.value[key],
2830
+ "onUpdate:modelValue": ($event) => vModel.value[key] = $event,
2831
+ key,
2832
+ schema: item,
2833
+ expanded: unref(childExpanded),
2834
+ name: unref(spaceCamelCase)(key),
2835
+ nullable: !((_a = props.schema.required) == null ? void 0 : _a.includes(key))
2836
+ }, null, 8, ["modelValue", "onUpdate:modelValue", "schema", "expanded", "name", "nullable"]);
2040
2837
  }), 128))
2041
2838
  ]),
2042
2839
  _: 1
2043
- }, 8, ["label", "open"])
2044
- ]);
2840
+ }, 8, ["label", "open"]))
2841
+ ])) : props.schema.type === "array" ? (openBlock(), createBlock(_sfc_main$j, {
2842
+ key: 3,
2843
+ modelValue: vModel.value,
2844
+ "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => vModel.value = $event),
2845
+ schema: props.schema,
2846
+ label: props.schema.name ?? props.name,
2847
+ expanded: props.expanded
2848
+ }, null, 8, ["modelValue", "schema", "label", "expanded"])) : props.schema.type === "string" && props.schema.enum ? (openBlock(), createBlock(_sfc_main$k, {
2849
+ key: 4,
2850
+ nullable: props.schema.nullable || props.nullable,
2851
+ items: getItems(props.schema),
2852
+ modelValue: vModel.value,
2853
+ "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => vModel.value = $event),
2854
+ label: props.schema.name ?? props.name
2855
+ }, null, 8, ["nullable", "items", "modelValue", "label"])) : props.schema.type === "boolean" ? (openBlock(), createBlock(_sfc_main$9, {
2856
+ key: 5,
2857
+ modelValue: vModel.value,
2858
+ "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => vModel.value = $event),
2859
+ label: props.schema.name ?? props.name
2860
+ }, null, 8, ["modelValue", "label"])) : (openBlock(), createBlock(_sfc_main$u, {
2861
+ key: 6,
2862
+ modelValue: vModel.value,
2863
+ "onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => vModel.value = $event),
2864
+ label: props.schema.name ?? props.name,
2865
+ multiline: props.schema.multiline
2866
+ }, null, 8, ["modelValue", "label", "multiline"]));
2867
+ };
2868
+ }
2869
+ });
2870
+ const _hoisted_1$3 = { key: 2 };
2871
+ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
2872
+ __name: "BlocksEditor",
2873
+ props: {
2874
+ blocksList: {},
2875
+ blocksMap: {},
2876
+ dataEntries: {},
2877
+ dataEntryScopes: {},
2878
+ activeBlockId: {},
2879
+ state: {}
2880
+ },
2881
+ setup(__props) {
2882
+ const props = __props;
2883
+ const currentTab = ref("blocks");
2884
+ const currentContentBlock = computed(() => {
2885
+ if (!props.activeBlockId) return null;
2886
+ return findBlock(props.state.content, (block) => block.id === props.activeBlockId);
2887
+ });
2888
+ const currentBlock = computed(() => {
2889
+ if (!currentContentBlock.value) return null;
2890
+ return props.blocksMap.get(currentContentBlock.value.blockId);
2891
+ });
2892
+ const currentDataEntry = computed(() => {
2893
+ var _a;
2894
+ if ((_a = props.activeBlockId) == null ? void 0 : _a.startsWith("data:")) {
2895
+ const id = props.activeBlockId.slice(5);
2896
+ return props.dataEntries.find((item) => item.id === id);
2897
+ }
2898
+ return null;
2899
+ });
2900
+ const tabs = computed(() => {
2901
+ var _a, _b;
2902
+ const arr = [
2903
+ { id: "blocks", title: "Блоки" }
2904
+ ];
2905
+ if (currentBlock.value) {
2906
+ arr.push({
2907
+ id: "blockEdit",
2908
+ title: ((_a = currentBlock.value) == null ? void 0 : _a.name) ?? "Unknown Block"
2909
+ });
2910
+ }
2911
+ if (currentDataEntry.value) {
2912
+ arr.push({
2913
+ id: "blockEdit",
2914
+ title: ((_b = currentDataEntry.value) == null ? void 0 : _b.title) ?? "Settings"
2915
+ });
2916
+ }
2917
+ return arr;
2918
+ });
2919
+ watch(() => props.activeBlockId, (blockId, oldBlockId) => {
2920
+ if (blockId && blockId !== oldBlockId) {
2921
+ currentTab.value = "blockEdit";
2922
+ }
2923
+ if (!blockId && (currentTab.value === "blockEdit" || currentTab.value === "settingEdit")) {
2924
+ currentTab.value = "blocks";
2925
+ }
2926
+ if (currentTab.value === "blockEdit" && currentDataEntry.value && props.dataEntryScopes && !props.dataEntryScopes[currentDataEntry.value.id]) {
2927
+ props.dataEntryScopes[currentDataEntry.value.id] = "site";
2928
+ }
2929
+ }, { immediate: true });
2930
+ const settingSelectItems = [
2931
+ { id: "site", title: "Для всего сайта" },
2932
+ { id: "page", title: "Только для этой страницы" }
2933
+ ];
2934
+ return (_ctx, _cache) => {
2935
+ return openBlock(), createElementBlock("div", {
2936
+ class: "editor-blocks-sidebar",
2937
+ onBlockdrop: _cache[4] || (_cache[4] = withModifiers(() => {
2938
+ }, ["stop"]))
2939
+ }, [
2940
+ renderSlot(_ctx.$slots, "default"),
2941
+ createVNode(_sfc_main$s, {
2942
+ modelValue: currentTab.value,
2943
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => currentTab.value = $event),
2944
+ items: tabs.value
2945
+ }, null, 8, ["modelValue", "items"]),
2946
+ createVNode(_sfc_main$r, { page: currentTab.value }, {
2947
+ blocks: withCtx(() => [
2948
+ createVNode(_sfc_main$t, { blocks: _ctx.blocksList }, null, 8, ["blocks"])
2949
+ ]),
2950
+ blockEdit: withCtx(() => [
2951
+ currentBlock.value && currentContentBlock.value ? (openBlock(), createBlock(_sfc_main$6, {
2952
+ key: currentContentBlock.value.id,
2953
+ schema: currentBlock.value.props,
2954
+ modelValue: currentContentBlock.value.data,
2955
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => currentContentBlock.value.data = $event),
2956
+ flat: ""
2957
+ }, null, 8, ["schema", "modelValue"])) : currentDataEntry.value ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [
2958
+ props.dataEntryScopes ? (openBlock(), createBlock(_sfc_main$k, {
2959
+ key: 0,
2960
+ modelValue: props.dataEntryScopes[currentDataEntry.value.id],
2961
+ "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => props.dataEntryScopes[currentDataEntry.value.id] = $event),
2962
+ style: { "margin-bottom": "8px" },
2963
+ label: "Применить настройки",
2964
+ items: settingSelectItems
2965
+ }, null, 8, ["modelValue"])) : createCommentVNode("", true),
2966
+ (openBlock(), createBlock(_sfc_main$6, {
2967
+ key: currentDataEntry.value.id,
2968
+ schema: currentDataEntry.value.props,
2969
+ modelValue: _ctx.state.data[currentDataEntry.value.id],
2970
+ "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => _ctx.state.data[currentDataEntry.value.id] = $event),
2971
+ flat: ""
2972
+ }, null, 8, ["schema", "modelValue"]))
2973
+ ], 64)) : (openBlock(), createElementBlock("div", _hoisted_1$3, "Схема для блока не найдена"))
2974
+ ]),
2975
+ _: 1
2976
+ }, 8, ["page"])
2977
+ ], 32);
2045
2978
  };
2046
2979
  }
2047
2980
  });
2048
- const _sfc_main$7 = {};
2049
- const _hoisted_1$6 = {
2050
- width: "46",
2051
- height: "28",
2052
- viewBox: "0 0 46 28",
2053
- fill: "none",
2054
- xmlns: "http://www.w3.org/2000/svg"
2055
- };
2056
- function _sfc_render$3(_ctx, _cache) {
2057
- return openBlock(), createElementBlock("svg", _hoisted_1$6, _cache[0] || (_cache[0] = [
2058
- createStaticVNode('<mask id="mask0_1044_6" style="mask-type:luminance;" maskUnits="userSpaceOnUse" x="0" y="0" width="46" height="28"><path d="M45.5 0H0.5V28H45.5V0Z" fill="white"></path></mask><g mask="url(#mask0_1044_6)"><path d="M23.5 27.8537C35.9264 27.8537 46 25.6664 46 22.9683C46 20.2702 35.9264 18.083 23.5 18.083C11.0736 18.083 1 20.2702 1 22.9683C1 25.6664 11.0736 27.8537 23.5 27.8537Z" fill="#D7D7D7"></path><path d="M39.6719 9.5459L32.538 1.51859C32.1955 0.971432 31.6956 0.640625 31.169 0.640625H15.831C15.3044 0.640625 14.8045 0.971432 14.462 1.51789L7.32812 9.5466V15.9946H39.6719V9.5459Z" stroke="#A0A0A0" stroke-width="0.703125"></path><path d="M30.2591 11.7594C30.2591 10.6393 30.958 9.71457 31.825 9.71387H39.6719V22.3718C39.6719 23.8534 38.7437 25.0678 37.5977 25.0678H9.40234C8.25625 25.0678 7.32812 23.8527 7.32812 22.3718V9.71387H15.175C16.042 9.71387 16.7409 10.6372 16.7409 11.7573V11.7727C16.7409 12.8928 17.4475 13.7973 18.3138 13.7973H28.6862C29.5525 13.7973 30.2591 12.8845 30.2591 11.7643V11.7594Z" fill="#FAFAFA" stroke="#A0A0A0" stroke-width="0.703125"></path></g>', 2)
2059
- ]));
2060
- }
2061
- const EmptyFileIcon = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["render", _sfc_render$3]]);
2062
- const _sfc_main$6 = {};
2063
- const _hoisted_1$5 = {
2064
- width: "16",
2065
- height: "16",
2066
- viewBox: "0 0 16 16",
2067
- fill: "none",
2068
- xmlns: "http://www.w3.org/2000/svg"
2069
- };
2070
- function _sfc_render$2(_ctx, _cache) {
2071
- return openBlock(), createElementBlock("svg", _hoisted_1$5, _cache[0] || (_cache[0] = [
2072
- createElementVNode("path", {
2073
- d: "M9.31382 7.9L12.8488 4.364C12.9443 4.27176 13.0205 4.16141 13.0729 4.03941C13.1253 3.9174 13.1529 3.78618 13.1541 3.6534C13.1552 3.52062 13.1299 3.38894 13.0796 3.26605C13.0294 3.14315 12.9551 3.0315 12.8612 2.93761C12.7673 2.84371 12.6557 2.76946 12.5328 2.71918C12.4099 2.6689 12.2782 2.6436 12.1454 2.64475C12.0126 2.64591 11.8814 2.67349 11.7594 2.7259C11.6374 2.77831 11.5271 2.85449 11.4348 2.95L7.89882 6.485L4.36382 2.95C4.27157 2.85449 4.16123 2.77831 4.03922 2.7259C3.91722 2.67349 3.786 2.64591 3.65322 2.64475C3.52044 2.6436 3.38876 2.6689 3.26587 2.71918C3.14297 2.76946 3.03132 2.84371 2.93742 2.93761C2.84353 3.0315 2.76928 3.14315 2.719 3.26605C2.66872 3.38894 2.64342 3.52062 2.64457 3.6534C2.64572 3.78618 2.67331 3.9174 2.72572 4.03941C2.77813 4.16141 2.85431 4.27176 2.94982 4.364L6.48482 7.899L2.94982 11.435C2.85431 11.5273 2.77813 11.6376 2.72572 11.7596C2.67331 11.8816 2.64572 12.0128 2.64457 12.1456C2.64342 12.2784 2.66872 12.4101 2.719 12.533C2.76928 12.6559 2.84353 12.7675 2.93742 12.8614C3.03132 12.9553 3.14297 13.0295 3.26587 13.0798C3.38876 13.1301 3.52044 13.1554 3.65322 13.1543C3.786 13.1531 3.91722 13.1255 4.03922 13.0731C4.16123 13.0207 4.27157 12.9445 4.36382 12.849L7.89882 9.314L11.4348 12.849C11.5271 12.9445 11.6374 13.0207 11.7594 13.0731C11.8814 13.1255 12.0126 13.1531 12.1454 13.1543C12.2782 13.1554 12.4099 13.1301 12.5328 13.0798C12.6557 13.0295 12.7673 12.9553 12.8612 12.8614C12.9551 12.7675 13.0294 12.6559 13.0796 12.533C13.1299 12.4101 13.1552 12.2784 13.1541 12.1456C13.1529 12.0128 13.1253 11.8816 13.0729 11.7596C13.0205 11.6376 12.9443 11.5273 12.8488 11.435L9.31382 7.9Z",
2074
- fill: "currentColor"
2075
- }, null, -1)
2076
- ]));
2077
- }
2078
- const CloseMinIcon = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["render", _sfc_render$2]]);
2079
- const _hoisted_1$4 = {
2080
- key: 0,
2081
- class: "v-image-uploader__drag-label"
2082
- };
2083
- const _hoisted_2 = { class: "v-image-uploader__image-preview" };
2084
- const _hoisted_3 = ["src"];
2085
- const _hoisted_4 = { class: "v-image-uploader__image-info" };
2086
- const _sfc_main$5 = /* @__PURE__ */ defineComponent({
2087
- __name: "VImageUploader",
2981
+ const _hoisted_1$2 = ["onBlockdrop", "onMousedown", "onMouseenter", "onClick", "onContextmenu"];
2982
+ const _hoisted_2$1 = ["onBlockdrop"];
2983
+ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
2984
+ __name: "ContentHierarchy",
2088
2985
  props: {
2089
- accept: {},
2090
- schema: {},
2091
- modelValue: {},
2092
- error: {},
2093
- label: {},
2094
- required: { type: Boolean },
2095
- disabled: { type: Boolean }
2986
+ contentBlocks: {},
2987
+ blocksMap: {},
2988
+ hoverBlockId: {},
2989
+ activeBlockId: {}
2096
2990
  },
2097
- emits: ["update:modelValue"],
2991
+ emits: ["update:hoverBlockId", "update:activeBlockId"],
2098
2992
  setup(__props, { emit: __emit }) {
2099
2993
  const props = __props;
2100
2994
  const emit = __emit;
2101
- const fileUploader = inject("fileUploader");
2102
- const addFile = async (file) => {
2103
- emit("update:modelValue", { src: URL.createObjectURL(file), file, name: file.name });
2104
- if (fileUploader) {
2105
- const resp = await fileUploader(file);
2106
- emit("update:modelValue", { src: resp.src, previewSrc: resp.previewSrc, name: resp.name });
2107
- }
2108
- };
2109
- const drag = ref(false);
2110
- const onDragOver = (e) => {
2111
- var _a, _b, _c;
2112
- if ((_c = (_b = (_a = e.dataTransfer) == null ? void 0 : _a.types) == null ? void 0 : _b[0]) == null ? void 0 : _c.startsWith("text")) return;
2113
- e.preventDefault();
2114
- drag.value = true;
2115
- };
2116
- const onDragLeave = (e) => {
2117
- var _a;
2118
- if (e.relatedTarget === e.currentTarget || ((_a = e.relatedTarget) == null ? void 0 : _a.parentElement) === e.currentTarget) return;
2119
- drag.value = false;
2995
+ const flatBlocks = computed(() => {
2996
+ const arr = [];
2997
+ const collectBlocks = (items, intent = 0, parent = null) => {
2998
+ for (let i = 0; i < items.length; i++) {
2999
+ const data = items[i];
3000
+ if (data.blockId.startsWith("__dev")) continue;
3001
+ const block = props.blocksMap.get(data.blockId);
3002
+ if (!block) {
3003
+ arr.push({
3004
+ content: data,
3005
+ key: data.id,
3006
+ intent,
3007
+ hasSlots: false,
3008
+ hasMultipleSlots: false,
3009
+ block: {},
3010
+ parent
3011
+ });
3012
+ continue;
3013
+ }
3014
+ arr.push({
3015
+ content: data,
3016
+ key: data.id,
3017
+ intent,
3018
+ hasSlots: hasSlots(block),
3019
+ hasMultipleSlots: hasMultipleSlots(block),
3020
+ block,
3021
+ parent
3022
+ });
3023
+ forEachChildren(block, data, (blocks) => {
3024
+ collectBlocks(blocks, intent + 1, data);
3025
+ });
3026
+ }
3027
+ };
3028
+ collectBlocks(props.contentBlocks);
3029
+ return arr;
3030
+ });
3031
+ const drag = useDraggableItem();
3032
+ const dragMode = inject("dragMode");
3033
+ const onItemMouseDown = (e, item) => {
3034
+ if (e.button !== 0) return;
3035
+ const target = e.currentTarget;
3036
+ drag(e, {
3037
+ onStart(item2) {
3038
+ target.setAttribute("data-source-drag", "");
3039
+ item2.classList.add("drag");
3040
+ document.body.classList.add("mousedrag");
3041
+ dragMode.value = true;
3042
+ },
3043
+ onEnd(e2) {
3044
+ var _a;
3045
+ document.body.classList.remove("mousedrag");
3046
+ target.removeAttribute("data-source-drag");
3047
+ if (e2.target !== target) {
3048
+ (_a = e2.target) == null ? void 0 : _a.dispatchEvent(new BlockDropEvent(item.block, item.content));
3049
+ }
3050
+ dragMode.value = false;
3051
+ }
3052
+ });
2120
3053
  };
2121
- const onDrop = (e) => {
2122
- e.preventDefault();
2123
- drag.value = false;
2124
- for (const item of e.dataTransfer.items) {
2125
- if (item.kind !== "file") continue;
2126
- const file = item.getAsFile();
2127
- if (!file) continue;
2128
- addFile(file);
3054
+ const containerRef = ref();
3055
+ const places = shallowReactive([]);
3056
+ watch(dragMode, (dragMode2) => {
3057
+ if (!dragMode2 || !containerRef.value) {
3058
+ places.length = 0;
3059
+ return;
2129
3060
  }
2130
- };
2131
- const fileDialog = useFileDialog({
2132
- accept: props.accept ?? "image/*",
2133
- multiple: false
2134
- });
2135
- fileDialog.onChange((files) => {
2136
- if (!files || files.length === 0) return;
2137
- for (const file of files) {
2138
- addFile(file);
3061
+ const containerRect = containerRef.value.getBoundingClientRect();
3062
+ places.length = 0;
3063
+ const children = Array.from(containerRef.value.children).filter((child) => child.classList.contains("page-editor-hierarchy__item"));
3064
+ let lastRectHeight = 0;
3065
+ let lastRectBottom = containerRect.top;
3066
+ for (let i = 0; i < children.length + 1; i++) {
3067
+ const child = children[i];
3068
+ const rect = i === children.length ? { top: lastRectBottom, height: containerRect.bottom - lastRectBottom, bottom: 0 } : child.getBoundingClientRect();
3069
+ let top = lastRectHeight * 0.2;
3070
+ let bottom = rect.height * 0.2;
3071
+ if (i > 0 && !flatBlocks.value[i - 1].hasSlots) {
3072
+ top = lastRectHeight * 0.5;
3073
+ }
3074
+ if (i === children.length) {
3075
+ bottom = rect.height;
3076
+ } else if (!flatBlocks.value[i].hasSlots) {
3077
+ bottom = rect.height * 0.5;
3078
+ }
3079
+ places.push({
3080
+ index: i,
3081
+ style: {
3082
+ top: rect.top - containerRect.top + containerRef.value.scrollTop - top + "px",
3083
+ paddingTop: top - 1 + "px",
3084
+ height: top + bottom + "px"
3085
+ }
3086
+ });
3087
+ lastRectHeight = rect.height;
3088
+ lastRectBottom = rect.bottom;
2139
3089
  }
2140
- fileDialog.reset();
2141
3090
  });
2142
- const removeImage = () => {
2143
- emit("update:modelValue", getDefaultValue(props.schema));
3091
+ const onItemBlockDrop = (e, item) => {
3092
+ if (e.content) {
3093
+ deleteBlock(props.contentBlocks, e.content);
3094
+ }
3095
+ if (item.hasSlots) {
3096
+ const contentBlock = e.content ?? createContentBlock(e.block);
3097
+ createContentBlockChild(props.blocksMap, contentBlock, item.content, -1);
3098
+ }
2144
3099
  };
2145
- return (_ctx, _cache) => {
2146
- return openBlock(), createBlock(_sfc_main$e, {
2147
- class: normalizeClass(["v-image-uploader", { drag: drag.value }]),
2148
- error: _ctx.error,
2149
- label: _ctx.label,
2150
- required: _ctx.required,
2151
- disabled: _ctx.disabled,
2152
- outline: "",
2153
- onDrop,
2154
- onDragover: onDragOver,
2155
- onDragleave: onDragLeave
2156
- }, {
2157
- default: withCtx(() => [
2158
- drag.value ? (openBlock(), createElementBlock("div", _hoisted_1$4, "Отпустите файл здесь")) : !props.modelValue || props.modelValue.src === unref(defaultImageSrc) ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [
2159
- createVNode(EmptyFileIcon),
2160
- createElementVNode("div", null, [
2161
- createElementVNode("a", {
2162
- onClick: _cache[0] || (_cache[0] = ($event) => unref(fileDialog).open())
2163
- }, "Загрузите изображение"),
2164
- _cache[1] || (_cache[1] = createElementVNode("br", null, null, -1)),
2165
- _cache[2] || (_cache[2] = createTextVNode("или перетащите сюда "))
2166
- ])
2167
- ], 64)) : (openBlock(), createElementBlock(Fragment, { key: 2 }, [
2168
- createElementVNode("div", _hoisted_2, [
2169
- createElementVNode("img", {
2170
- src: props.modelValue.previewSrc ?? props.modelValue.src,
2171
- alt: "Preview Image"
2172
- }, null, 8, _hoisted_3),
2173
- createElementVNode("button", { onClick: removeImage }, [
2174
- createVNode(CloseMinIcon)
2175
- ])
2176
- ]),
2177
- createElementVNode("div", _hoisted_4, [
2178
- createElementVNode("div", null, toDisplayString(props.modelValue.name), 1)
2179
- ])
2180
- ], 64))
2181
- ]),
2182
- _: 1
2183
- }, 8, ["class", "error", "label", "required", "disabled"]);
3100
+ const onPlaceBlockDrop = (e, _index, dublicate = false) => {
3101
+ e.stopPropagation();
3102
+ let index = _index;
3103
+ let content = e.content;
3104
+ if (content && !dublicate) {
3105
+ const sourceIndex = flatBlocks.value.findIndex((item) => item.content === content);
3106
+ if (sourceIndex === index || sourceIndex === index - 1) return;
3107
+ if (index > sourceIndex && sourceIndex !== -1) index--;
3108
+ deleteBlock(props.contentBlocks, content);
3109
+ }
3110
+ if (content && dublicate) {
3111
+ content = cloneDeep(content);
3112
+ changeBlockId(content, e.block);
3113
+ }
3114
+ const contentBlock = content ?? createContentBlock(e.block);
3115
+ if (index >= flatBlocks.value.length) {
3116
+ props.contentBlocks.push(contentBlock);
3117
+ } else {
3118
+ const blockEntry = flatBlocks.value[index];
3119
+ if (blockEntry.parent === null) {
3120
+ const index2 = props.contentBlocks.indexOf(blockEntry.content);
3121
+ props.contentBlocks.splice(index2, 0, contentBlock);
3122
+ } else {
3123
+ const index2 = getBlockIndex(blockEntry.parent, blockEntry.content);
3124
+ createContentBlockChild(props.blocksMap, contentBlock, blockEntry.parent, index2);
3125
+ }
3126
+ }
3127
+ };
3128
+ const contextMenu = useContextMenu((content) => {
3129
+ var _a;
3130
+ return [
3131
+ content !== null && { title: "Дублировать блок", onClick() {
3132
+ const index = flatBlocks.value.findIndex((item) => item.content === content);
3133
+ const block = props.blocksMap.get(content.blockId);
3134
+ onPlaceBlockDrop(new BlockDropEvent(block, content), index, true);
3135
+ } },
3136
+ content !== null && { title: "Копировать блок", async onClick() {
3137
+ const blob = new Blob([JSON.stringify(content)], { type: "text/plain" });
3138
+ await navigator.clipboard.write([
3139
+ new ClipboardItem({ "text/plain": blob })
3140
+ ]);
3141
+ } },
3142
+ content && ((_a = props.blocksMap.get(content.blockId)) == null ? void 0 : _a.slots) && {
3143
+ title: `Вставить блок как дочерний`,
3144
+ onClick: () => placeBlockFromClipboard(content)
3145
+ },
3146
+ {
3147
+ title: "Вставить блок ниже",
3148
+ onClick: async () => {
3149
+ const index = flatBlocks.value.findIndex((item) => item.content === content);
3150
+ const [contentData, block] = await getBlockFromClipboard();
3151
+ if (!contentData || !block) return;
3152
+ onPlaceBlockDrop(new BlockDropEvent(block, contentData), index + 1, false);
3153
+ }
3154
+ },
3155
+ content !== null && {
3156
+ title: "Удалить блок",
3157
+ onClick: () => {
3158
+ deleteBlock(props.contentBlocks, content);
3159
+ if (props.activeBlockId === content.id) {
3160
+ emit("update:activeBlockId", null);
3161
+ }
3162
+ if (props.hoverBlockId === content.id) {
3163
+ emit("update:hoverBlockId", null);
3164
+ }
3165
+ }
3166
+ }
3167
+ ];
3168
+ });
3169
+ const getBlockFromClipboard = async () => {
3170
+ const resp = await navigator.clipboard.read();
3171
+ if (!resp[0].types.includes("text/plain")) return [null, null];
3172
+ const entry = await resp[0].getType("text/plain");
3173
+ const text = await entry.text();
3174
+ if (!text.startsWith("{")) return [null, null];
3175
+ const contentData = JSON.parse(text);
3176
+ const block = props.blocksMap.get(contentData.blockId) ?? null;
3177
+ if (block) {
3178
+ changeBlockId(contentData, block);
3179
+ }
3180
+ return [contentData, block];
3181
+ };
3182
+ const placeBlockFromClipboard = async (content) => {
3183
+ const [contentData, block] = await getBlockFromClipboard();
3184
+ if (!contentData || !block) return;
3185
+ try {
3186
+ if (content !== null) {
3187
+ const index = flatBlocks.value.findIndex((item) => item.content === content);
3188
+ if (flatBlocks.value[index].hasSlots) {
3189
+ onItemBlockDrop(new BlockDropEvent(block, contentData), flatBlocks.value[index]);
3190
+ } else {
3191
+ onPlaceBlockDrop(new BlockDropEvent(block, contentData), index);
3192
+ }
3193
+ } else {
3194
+ onPlaceBlockDrop(new BlockDropEvent(block, contentData), flatBlocks.value.length);
3195
+ }
3196
+ } catch (e) {
3197
+ console.warn(e);
3198
+ }
3199
+ };
3200
+ return (_ctx, _cache) => {
3201
+ return openBlock(), createElementBlock("div", {
3202
+ ref_key: "containerRef",
3203
+ ref: containerRef,
3204
+ class: "page-editor-hierarchy",
3205
+ onClick: _cache[1] || (_cache[1] = withModifiers(($event) => emit("update:activeBlockId", null), ["self"]))
3206
+ }, [
3207
+ (openBlock(true), createElementBlock(Fragment, null, renderList(flatBlocks.value, (item) => {
3208
+ return openBlock(), createElementBlock("div", {
3209
+ class: normalizeClass(["page-editor-hierarchy__item", { active: props.activeBlockId === item.content.id, hover: props.hoverBlockId === item.content.id }]),
3210
+ style: normalizeStyle({ paddingLeft: `${16 + item.intent * 16}px` }),
3211
+ onBlockdrop: ($event) => onItemBlockDrop($event, item),
3212
+ onMousedown: ($event) => onItemMouseDown($event, item),
3213
+ onMouseenter: ($event) => emit("update:hoverBlockId", item.content.id),
3214
+ onMouseleave: _cache[0] || (_cache[0] = ($event) => emit("update:hoverBlockId", null)),
3215
+ onClick: ($event) => emit("update:activeBlockId", item.content.id),
3216
+ onContextmenu: withModifiers(($event) => unref(contextMenu).open($event, item.content), ["stop"])
3217
+ }, toDisplayString(item.block.name), 47, _hoisted_1$2);
3218
+ }), 256)),
3219
+ (openBlock(true), createElementBlock(Fragment, null, renderList(unref(places), (item) => {
3220
+ return openBlock(), createElementBlock("div", {
3221
+ class: "page-editor-hierarhy__place",
3222
+ style: normalizeStyle(item.style),
3223
+ onBlockdrop: ($event) => onPlaceBlockDrop($event, item.index)
3224
+ }, null, 44, _hoisted_2$1);
3225
+ }), 256)),
3226
+ createVNode(_sfc_main$f, normalizeProps(guardReactiveProps(unref(contextMenu).props)), null, 16)
3227
+ ], 512);
2184
3228
  };
2185
3229
  }
2186
3230
  });
2187
- const getBlockName = (path) => {
2188
- if (!path) return void 0;
2189
- const str = path.split("/").at(-1);
2190
- return (str == null ? void 0 : str.split(".", 1)[0].replace(/([A-Z])/g, " $1").trimStart()) ?? "Unnamed block";
2191
- };
2192
- const capitalize = (text) => {
2193
- return text[0].toUpperCase() + text.slice(1);
2194
- };
2195
- const spaceCamelCase = (str) => {
2196
- return capitalize(str.replace(/([A-Z])/g, " $1").trimStart());
2197
- };
2198
- const _hoisted_1$3 = {
2199
- key: 1,
2200
- class: "json-editor__object"
2201
- };
2202
- const _sfc_main$4 = /* @__PURE__ */ defineComponent({
2203
- __name: "JsonEditor",
3231
+ const _hoisted_1$1 = { key: 0 };
3232
+ const _hoisted_2 = ["onClick"];
3233
+ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
3234
+ __name: "ContentSettings",
2204
3235
  props: /* @__PURE__ */ mergeModels({
2205
- schema: {},
2206
- name: {},
2207
- flat: { type: Boolean },
2208
- expanded: { type: Boolean }
3236
+ dataEntries: {}
2209
3237
  }, {
2210
3238
  "modelValue": {},
2211
3239
  "modelModifiers": {}
@@ -2213,112 +3241,58 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
2213
3241
  emits: ["update:modelValue"],
2214
3242
  setup(__props) {
2215
3243
  const props = __props;
2216
- const childExpanded = props.schema.type === "object" && Object.keys(props.schema.properties).length < 2;
2217
- const vModel = useModel(__props, "modelValue");
2218
- const getItems = (schema) => {
2219
- return schema.enum.map((item, index) => {
2220
- var _a;
2221
- return {
2222
- id: item,
2223
- title: ((_a = schema.enumAlias) == null ? void 0 : _a[index]) ?? spaceCamelCase(item)
2224
- };
2225
- });
3244
+ const model = useModel(__props, "modelValue");
3245
+ return (_ctx, _cache) => {
3246
+ return props.dataEntries.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_1$1, [
3247
+ (openBlock(true), createElementBlock(Fragment, null, renderList(props.dataEntries, (item) => {
3248
+ var _a;
3249
+ return openBlock(), createElementBlock("div", {
3250
+ class: normalizeClass(["page-editor-hierarchy__item", { active: ((_a = model.value) == null ? void 0 : _a.slice(5)) === item.id }]),
3251
+ onClick: ($event) => model.value = "data:" + item.id
3252
+ }, toDisplayString(item.title ?? item.id), 11, _hoisted_2);
3253
+ }), 256))
3254
+ ])) : createCommentVNode("", true);
2226
3255
  };
3256
+ }
3257
+ });
3258
+ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
3259
+ __name: "HierarchySidebar",
3260
+ props: {
3261
+ state: {},
3262
+ blocksMap: {},
3263
+ control: {},
3264
+ dataEntries: {}
3265
+ },
3266
+ setup(__props) {
3267
+ const props = __props;
2227
3268
  return (_ctx, _cache) => {
2228
- const _component_JsonEditor = resolveComponent("JsonEditor", true);
2229
- return props.schema.type === "object" && props.schema.format === "image" ? (openBlock(), createBlock(_sfc_main$5, {
2230
- key: 0,
2231
- modelValue: vModel.value,
2232
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => vModel.value = $event),
2233
- label: props.schema.name ?? props.name,
2234
- schema: props.schema
2235
- }, null, 8, ["modelValue", "label", "schema"])) : props.schema.type === "object" ? (openBlock(), createElementBlock("div", _hoisted_1$3, [
2236
- props.flat ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(props.schema.properties, (item, key) => {
2237
- return openBlock(), createBlock(_component_JsonEditor, {
2238
- modelValue: vModel.value[key],
2239
- "onUpdate:modelValue": ($event) => vModel.value[key] = $event,
2240
- key,
2241
- schema: item,
2242
- expanded: unref(childExpanded),
2243
- name: unref(spaceCamelCase)(key)
2244
- }, null, 8, ["modelValue", "onUpdate:modelValue", "schema", "expanded", "name"]);
2245
- }), 128)) : (openBlock(), createBlock(_sfc_main$b, {
2246
- key: 1,
2247
- label: props.schema.name ?? props.name,
2248
- open: props.expanded
2249
- }, {
2250
- default: withCtx(() => [
2251
- (openBlock(true), createElementBlock(Fragment, null, renderList(props.schema.properties, (item, key) => {
2252
- return openBlock(), createBlock(_component_JsonEditor, {
2253
- modelValue: vModel.value[key],
2254
- "onUpdate:modelValue": ($event) => vModel.value[key] = $event,
2255
- key,
2256
- schema: item,
2257
- expanded: unref(childExpanded),
2258
- name: unref(spaceCamelCase)(key)
2259
- }, null, 8, ["modelValue", "onUpdate:modelValue", "schema", "expanded", "name"]);
2260
- }), 128))
2261
- ]),
2262
- _: 1
2263
- }, 8, ["label", "open"]))
2264
- ])) : props.schema.type === "array" ? (openBlock(), createBlock(_sfc_main$8, {
2265
- key: 2,
2266
- modelValue: vModel.value,
2267
- "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => vModel.value = $event),
2268
- schema: props.schema,
2269
- label: props.schema.name ?? props.name,
2270
- expanded: props.expanded
2271
- }, null, 8, ["modelValue", "schema", "label", "expanded"])) : props.schema.type === "string" && props.schema.enum ? (openBlock(), createBlock(_sfc_main$9, {
2272
- key: 3,
2273
- items: getItems(props.schema),
2274
- modelValue: vModel.value,
2275
- "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => vModel.value = $event),
2276
- label: props.schema.name ?? props.name
2277
- }, null, 8, ["items", "modelValue", "label"])) : (openBlock(), createBlock(_sfc_main$d, {
2278
- key: 4,
2279
- modelValue: vModel.value,
2280
- "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => vModel.value = $event),
2281
- label: props.schema.name ?? props.name,
2282
- multiline: props.schema.multiline
2283
- }, null, 8, ["modelValue", "label", "multiline"]));
3269
+ return openBlock(), createElementBlock("div", {
3270
+ class: "editor-hierarchy",
3271
+ onBlockdrop: _cache[3] || (_cache[3] = withModifiers(() => {
3272
+ }, ["stop"]))
3273
+ }, [
3274
+ renderSlot(_ctx.$slots, "default"),
3275
+ _cache[4] || (_cache[4] = createElementVNode("div", { class: "title" }, "Настройки", -1)),
3276
+ createVNode(_sfc_main$3, {
3277
+ modelValue: props.control.activeBlockId.value,
3278
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => props.control.activeBlockId.value = $event),
3279
+ dataEntries: props.dataEntries
3280
+ }, null, 8, ["modelValue", "dataEntries"]),
3281
+ _cache[5] || (_cache[5] = createElementVNode("div", { class: "title" }, "Блоки", -1)),
3282
+ createVNode(_sfc_main$4, {
3283
+ "hover-block-id": props.control.hoverBlockId.value,
3284
+ "onUpdate:hoverBlockId": _cache[1] || (_cache[1] = ($event) => props.control.hoverBlockId.value = $event),
3285
+ "active-block-id": props.control.activeBlockId.value,
3286
+ "onUpdate:activeBlockId": _cache[2] || (_cache[2] = ($event) => props.control.activeBlockId.value = $event),
3287
+ "content-blocks": props.state.content,
3288
+ "blocks-map": props.blocksMap
3289
+ }, null, 8, ["hover-block-id", "active-block-id", "content-blocks", "blocks-map"])
3290
+ ], 32);
2284
3291
  };
2285
3292
  }
2286
3293
  });
2287
- const _sfc_main$3 = {};
2288
- const _hoisted_1$2 = {
2289
- width: "16",
2290
- height: "16",
2291
- viewBox: "0 0 16 16",
2292
- fill: "none",
2293
- xmlns: "http://www.w3.org/2000/svg"
2294
- };
2295
- function _sfc_render$1(_ctx, _cache) {
2296
- return openBlock(), createElementBlock("svg", _hoisted_1$2, _cache[0] || (_cache[0] = [
2297
- createElementVNode("path", {
2298
- d: "M10.707 14.364C10.8945 14.1764 10.9998 13.9221 10.9998 13.657C10.9998 13.3918 10.8945 13.1375 10.707 12.95L5.75705 7.99995L10.707 3.04995C10.8892 2.86135 10.99 2.60875 10.9877 2.34655C10.9854 2.08435 10.8803 1.83354 10.6949 1.64813C10.5095 1.46272 10.2586 1.35756 9.99645 1.35528C9.73425 1.353 9.48165 1.45379 9.29305 1.63595L3.63605 7.29295C3.44858 7.48048 3.34326 7.73479 3.34326 7.99995C3.34326 8.26512 3.44858 8.51942 3.63605 8.70695L9.29305 14.364C9.48058 14.5514 9.73488 14.6567 10 14.6567C10.2652 14.6567 10.5195 14.5514 10.707 14.364Z",
2299
- fill: "currentColor"
2300
- }, null, -1)
2301
- ]));
2302
- }
2303
- const ChevronLeftIcon = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["render", _sfc_render$1]]);
2304
- const _sfc_main$2 = {};
2305
- const _hoisted_1$1 = {
2306
- width: "16",
2307
- height: "16",
2308
- viewBox: "0 0 16 16",
2309
- fill: "none",
2310
- xmlns: "http://www.w3.org/2000/svg"
2311
- };
2312
- function _sfc_render(_ctx, _cache) {
2313
- return openBlock(), createElementBlock("svg", _hoisted_1$1, _cache[0] || (_cache[0] = [
2314
- createElementVNode("path", {
2315
- d: "M5.29295 1.63605C5.10548 1.82358 5.00017 2.07788 5.00017 2.34305C5.00017 2.60821 5.10548 2.86252 5.29295 3.05005L10.243 8.00005L5.29295 12.95C5.11079 13.1387 5.01 13.3913 5.01228 13.6534C5.01456 13.9156 5.11972 14.1665 5.30513 14.3519C5.49054 14.5373 5.74135 14.6424 6.00355 14.6447C6.26575 14.647 6.51835 14.5462 6.70695 14.364L12.364 8.70705C12.5514 8.51952 12.6567 8.26521 12.6567 8.00005C12.6567 7.73488 12.5514 7.48058 12.364 7.29305L6.70695 1.63605C6.51942 1.44858 6.26512 1.34326 5.99995 1.34326C5.73479 1.34326 5.48048 1.44858 5.29295 1.63605Z",
2316
- fill: "currentColor"
2317
- }, null, -1)
2318
- ]));
2319
- }
2320
- const ChevronRightIcon = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["render", _sfc_render]]);
2321
3294
  const useControlComponent = (_activeBlockId) => {
3295
+ let dragMode = false;
2322
3296
  let lastRoot = document.body;
2323
3297
  const hoverBlockId = shallowRef(null);
2324
3298
  const activeBlockId = shallowRef(null);
@@ -2327,6 +3301,7 @@ const useControlComponent = (_activeBlockId) => {
2327
3301
  let lastStateKey = "";
2328
3302
  let blocksHover = [];
2329
3303
  const onIframeBlockMouseEnter = (e) => {
3304
+ if (dragMode) return;
2330
3305
  hoverBlockElement.value = e.currentTarget;
2331
3306
  const blockId = hoverBlockElement.value.getAttribute("data-block-id") ?? null;
2332
3307
  hoverBlockId.value = blockId;
@@ -2355,6 +3330,7 @@ const useControlComponent = (_activeBlockId) => {
2355
3330
  e.stopPropagation();
2356
3331
  e.preventDefault();
2357
3332
  };
3333
+ const elements = shallowRef([]);
2358
3334
  const update = (root) => {
2359
3335
  lastRoot = root;
2360
3336
  const arr = Array.from(root.querySelectorAll("[data-block-id]"));
@@ -2366,6 +3342,7 @@ const useControlComponent = (_activeBlockId) => {
2366
3342
  item.addEventListener("mouseleave", onIframeBlockMouseLeave);
2367
3343
  item.addEventListener("click", onIframeBlockClick);
2368
3344
  }
3345
+ elements.value = arr;
2369
3346
  };
2370
3347
  watch(hoverBlockId, (hoverBlockId2) => {
2371
3348
  var _a;
@@ -2394,13 +3371,80 @@ const useControlComponent = (_activeBlockId) => {
2394
3371
  if (!blockId) return;
2395
3372
  activeBlockElement.value = lastRoot.querySelector(`[data-block-id="${blockId}"]`) ?? null;
2396
3373
  };
3374
+ let placeElements = [];
3375
+ const insertedPlace = shallowRef(null);
3376
+ const onMouseMove = (e) => {
3377
+ var _a;
3378
+ if (!dragMode) {
3379
+ return;
3380
+ }
3381
+ if (e.currentTarget !== e.target && findParent(e.target, (item) => item.classList.contains("editor-component"))) {
3382
+ insertedPlace.value = null;
3383
+ return;
3384
+ }
3385
+ let index = 0;
3386
+ for (let item of placeElements) {
3387
+ if (e.clientY + window.scrollY < (item.top + item.bottom) * 0.5) {
3388
+ break;
3389
+ }
3390
+ index++;
3391
+ }
3392
+ if (index === placeElements.length) {
3393
+ insertedPlace.value = { prepentBlockId: null, top: ((_a = placeElements[index - 1]) == null ? void 0 : _a.bottom) ?? 0 };
3394
+ } else {
3395
+ insertedPlace.value = { prepentBlockId: placeElements[index].id, top: placeElements[index].top };
3396
+ }
3397
+ };
3398
+ const onMouseLeave = () => {
3399
+ insertedPlace.value = null;
3400
+ };
3401
+ const updatePlaceElements = () => {
3402
+ placeElements = elements.value.map((item) => {
3403
+ var _a;
3404
+ const rect = item.getBoundingClientRect();
3405
+ const width = ((_a = item.parentElement) == null ? void 0 : _a.scrollWidth) ?? rect.width;
3406
+ const style = window.getComputedStyle(item);
3407
+ const top = rect.top + window.scrollY - parseInt(style.marginTop);
3408
+ const bottom = rect.bottom + window.scrollY;
3409
+ return { id: item.getAttribute("data-block-id"), top, bottom, width };
3410
+ });
3411
+ placeElements.sort((a, b) => a.top - b.top);
3412
+ };
3413
+ let mouseMoveRoot = null;
3414
+ const setDragMode = (_dragMode) => {
3415
+ dragMode = _dragMode;
3416
+ if (dragMode) {
3417
+ updatePlaceElements();
3418
+ lastRoot.addEventListener("mousemove", onMouseMove);
3419
+ mouseMoveRoot = lastRoot;
3420
+ } else {
3421
+ mouseMoveRoot == null ? void 0 : mouseMoveRoot.removeEventListener("mousemove", onMouseMove);
3422
+ insertedPlace.value = null;
3423
+ }
3424
+ };
3425
+ const onScroll = () => {
3426
+ var _a;
3427
+ if (dragMode) {
3428
+ updatePlaceElements();
3429
+ if ((_a = insertedPlace.value) == null ? void 0 : _a.prepentBlockId) {
3430
+ const index = placeElements.findIndex((item) => item.id === insertedPlace.value.prepentBlockId);
3431
+ insertedPlace.value = { ...insertedPlace.value, top: placeElements[index].top };
3432
+ }
3433
+ }
3434
+ };
2397
3435
  return {
2398
3436
  update,
2399
3437
  hoverBlockElement,
2400
3438
  activeBlockElement,
2401
3439
  activeBlockId,
2402
3440
  hoverBlockId,
2403
- updateActiveElement
3441
+ updateActiveElement,
3442
+ elements,
3443
+ insertedPlace,
3444
+ onMouseMove,
3445
+ onMouseLeave,
3446
+ setDragMode,
3447
+ onScroll
2404
3448
  };
2405
3449
  };
2406
3450
  registerAlias("image", { type: "object", format: "image", properties: { src: "string", previewSrc: "string?" } });
@@ -2423,54 +3467,18 @@ addUpdateListener((module) => {
2423
3467
  }));
2424
3468
  });
2425
3469
  const processState = (state) => {
2426
- walkTree(state.content, (block) => {
2427
- if (block.id) {
2428
- block.id = uid();
2429
- }
2430
- if (!block.data) {
2431
- block.data = {};
2432
- }
2433
- block.data["data-block-id"] = block.id;
2434
- const schema = blocksMap.value.get(block.blockId);
2435
- if (!schema) return;
2436
- walkSchema(block.data, schema.props, (value, schema2, key, parent, isRequired) => {
2437
- if (key && isRequired && !schema2.nullable && (value === null || value === void 0)) {
2438
- parent[key] = getDefaultValue(schema2);
2439
- }
2440
- });
2441
- });
2442
- return state;
2443
- };
2444
- const saveState = (newState) => {
2445
- const state = cloneDeep(newState);
2446
- walkTree(state.content, (block) => {
2447
- if (!block.data) return;
2448
- delete block.data["data-block-id"];
2449
- const schema = blocksMap.value.get(block.blockId);
2450
- if (!schema) return;
2451
- walkSchema(block.data, schema.props, (value, schema2, key, parent) => {
2452
- if (schema2.type === "object" && schema2.format === "image" && value.src === defaultImageSrc && key && parent) {
2453
- parent[key] = null;
2454
- }
2455
- });
2456
- });
3470
+ processBlocks(state.content, blocksMap.value);
2457
3471
  return state;
2458
3472
  };
2459
3473
  const _sfc_main$1 = /* @__PURE__ */ defineComponent({
2460
3474
  __name: "PageSelector",
2461
3475
  setup(__props) {
2462
- const currentPage = ref(window.state.dev.currentPage);
2463
- const availablePages = window.state.dev.availablePages;
2464
- const pages = availablePages.map((item) => ({
2465
- id: item,
2466
- title: item
2467
- }));
2468
- if (!availablePages.includes(currentPage.value)) {
2469
- pages.push({
2470
- id: currentPage.value,
2471
- title: currentPage.value
2472
- });
2473
- }
3476
+ const pagesRequest = inject("pagesRequest");
3477
+ const { data } = useRequest(pagesRequest);
3478
+ const currentPage = ref();
3479
+ const pages = computed(() => {
3480
+ return data.value ?? [];
3481
+ });
2474
3482
  watch(currentPage, async (newPage) => {
2475
3483
  var _a;
2476
3484
  const resp = await fetch(`/${newPage}`);
@@ -2482,32 +3490,30 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
2482
3490
  window.history.pushState({}, "", newPage === "index" ? "/" : `/${newPage}`);
2483
3491
  });
2484
3492
  return (_ctx, _cache) => {
2485
- return openBlock(), createBlock(_sfc_main$9, {
3493
+ return openBlock(), createBlock(_sfc_main$k, {
2486
3494
  modelValue: currentPage.value,
2487
3495
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => currentPage.value = $event),
2488
- items: unref(pages)
3496
+ items: pages.value
2489
3497
  }, null, 8, ["modelValue", "items"]);
2490
3498
  };
2491
3499
  }
2492
3500
  });
2493
- const _hoisted_1 = { key: 1 };
3501
+ const _hoisted_1 = { class: "editor-hierarchy__header" };
2494
3502
  const _sfc_main = /* @__PURE__ */ defineComponent({
2495
3503
  __name: "EditorApp",
2496
3504
  setup(__props) {
2497
3505
  const controlsOpened = ref(true);
2498
3506
  const dragMode = ref(false);
2499
3507
  provide("dragMode", dragMode);
2500
- const contentBlocks = computed(() => window.state.content);
3508
+ const state = reactive(processState(JSON.parse(JSON.stringify(window.state))));
3509
+ const contentBlocks = computed(() => state.content);
2501
3510
  useEventListener(document, "blockdrop", (e) => {
2502
- if (e.content) {
2503
- return;
2504
- }
2505
- contentBlocks.value.push(createContentBlock(e.block));
3511
+ var _a;
3512
+ if (e.content) return;
3513
+ insertBlockBefore(e.block, contentBlocks.value, (_a = control.insertedPlace.value) == null ? void 0 : _a.prepentBlockId);
2506
3514
  });
2507
3515
  const control = useControlComponent();
2508
- watch(contentBlocks, () => {
2509
- control.update(window.document.body);
2510
- }, { deep: true, flush: "post" });
3516
+ watch(dragMode, control.setDragMode);
2511
3517
  watch(blocksList, () => {
2512
3518
  control.update(window.document.body);
2513
3519
  control.updateActiveElement();
@@ -2515,47 +3521,19 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2515
3521
  onMounted(() => {
2516
3522
  control.update(window.document.body);
2517
3523
  });
2518
- const currentContentBlock = computed(() => {
2519
- if (!control.activeBlockId.value) return null;
2520
- return findBlock(contentBlocks.value, (block) => block.id === control.activeBlockId.value);
2521
- });
2522
- const currentBlock = computed(() => {
2523
- if (!currentContentBlock.value) return null;
2524
- return blocksMap.value.get(currentContentBlock.value.blockId);
2525
- });
2526
- const currentTab = ref("blocks");
2527
- const tabs = computed(() => {
2528
- var _a;
2529
- const arr = [
2530
- { id: "blocks", title: "Блоки" }
2531
- ];
2532
- if (currentContentBlock.value) {
2533
- arr.push({
2534
- id: "blockEdit",
2535
- title: ((_a = currentBlock.value) == null ? void 0 : _a.name) ?? "Unknown Block"
2536
- });
2537
- }
2538
- return arr;
2539
- });
2540
- watch(currentContentBlock, (block) => {
2541
- if (block) {
2542
- currentTab.value = "blockEdit";
2543
- } else {
2544
- if (currentTab.value === "blockEdit") {
2545
- currentTab.value = "blocks";
2546
- }
2547
- }
2548
- });
2549
- useKeyDownLayer("Escape", () => !!control.activeBlockId.value, () => control.activeBlockId.value = null);
2550
- watchDebounced(window.state, (newState, oldState) => {
2551
- var _a, _b;
2552
- if (((_a = newState == null ? void 0 : newState.dev) == null ? void 0 : _a.currentPage) !== ((_b = oldState == null ? void 0 : oldState.dev) == null ? void 0 : _b.currentPage)) {
2553
- return;
2554
- }
2555
- const state = saveState(newState);
3524
+ watch(state, (state2) => {
3525
+ const val = JSON.parse(JSON.stringify(state2));
3526
+ window.postMessage({ type: "update:state", payload: val });
3527
+ setTimeout(() => control.update(window.document.body), 50);
3528
+ }, { immediate: true });
3529
+ watchDebounced(state, (newState, oldState) => {
3530
+ const state2 = cloneDeep(newState);
3531
+ const scopedData = splitData(state2.data, dataEntryScopes.value);
3532
+ state2.data = scopedData["page"];
3533
+ saveBlocks(state2.content, blocksMap.value);
2556
3534
  fetch("/@mechanica/save", {
2557
3535
  method: "POST",
2558
- body: JSON.stringify(state),
3536
+ body: JSON.stringify(state2),
2559
3537
  headers: { "content-type": "application-json" }
2560
3538
  });
2561
3539
  }, { debounce: 500 });
@@ -2568,80 +3546,82 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2568
3546
  const obj = await resp.json();
2569
3547
  return obj;
2570
3548
  });
3549
+ provide("fileRequest", async () => {
3550
+ const resp = await fetch("/@mechanica/images");
3551
+ return await resp.json();
3552
+ });
3553
+ provide("pagesRequest", async () => {
3554
+ const resp = await fetch("/@mechanica/pages");
3555
+ return await resp.json();
3556
+ });
3557
+ const dataEntries2 = inject("dataEntries");
3558
+ const dataEntryScopes = ref(state.dataEntryScopes ?? {});
3559
+ useKeyDownLayer("Escape", () => !!control.activeBlockId.value, () => control.activeBlockId.value = null);
2571
3560
  return (_ctx, _cache) => {
2572
3561
  return openBlock(), createElementBlock(Fragment, null, [
2573
3562
  createVNode(Transition, null, {
2574
3563
  default: withCtx(() => [
2575
- controlsOpened.value ? (openBlock(), createElementBlock("div", {
3564
+ controlsOpened.value ? (openBlock(), createBlock(_sfc_main$2, {
2576
3565
  key: 0,
2577
- class: "editor-sidebar-left editor-hierarchy editor-component",
2578
- onBlockdrop: _cache[3] || (_cache[3] = withModifiers(() => {
2579
- }, ["stop"]))
2580
- }, [
2581
- createVNode(_sfc_main$1),
2582
- _cache[10] || (_cache[10] = createElementVNode("div", { class: "title" }, "Блоки", -1)),
2583
- createVNode(_sfc_main$i, {
2584
- "hover-block-id": unref(control).hoverBlockId.value,
2585
- "onUpdate:hoverBlockId": _cache[0] || (_cache[0] = ($event) => unref(control).hoverBlockId.value = $event),
2586
- "active-block-id": unref(control).activeBlockId.value,
2587
- "onUpdate:activeBlockId": _cache[1] || (_cache[1] = ($event) => unref(control).activeBlockId.value = $event),
2588
- "content-blocks": contentBlocks.value,
2589
- "blocks-map": unref(blocksMap)
2590
- }, null, 8, ["hover-block-id", "active-block-id", "content-blocks", "blocks-map"]),
2591
- createElementVNode("button", {
2592
- class: "editor-sidebar__close-button",
2593
- onClick: _cache[2] || (_cache[2] = ($event) => controlsOpened.value = false)
2594
- }, [
2595
- createVNode(ChevronLeftIcon)
2596
- ])
2597
- ], 32)) : createCommentVNode("", true)
3566
+ control: unref(control),
3567
+ state,
3568
+ "blocks-map": unref(blocksMap),
3569
+ "data-entries": unref(dataEntries2),
3570
+ class: "editor-sidebar-left editor-component"
3571
+ }, {
3572
+ default: withCtx(() => [
3573
+ createElementVNode("div", _hoisted_1, [
3574
+ createVNode(_sfc_main$1, { class: "pages-selector" })
3575
+ ]),
3576
+ createElementVNode("button", {
3577
+ class: "editor-sidebar__close-button",
3578
+ onClick: _cache[0] || (_cache[0] = ($event) => controlsOpened.value = false)
3579
+ }, [
3580
+ createVNode(ChevronLeftIcon)
3581
+ ])
3582
+ ]),
3583
+ _: 1
3584
+ }, 8, ["control", "state", "blocks-map", "data-entries"])) : createCommentVNode("", true)
2598
3585
  ]),
2599
3586
  _: 1
2600
3587
  }),
2601
- controlsOpened.value ? (openBlock(), createBlock(_sfc_main$h, {
3588
+ controlsOpened.value ? (openBlock(), createBlock(_sfc_main$z, {
2602
3589
  key: 0,
2603
3590
  element: unref(control).hoverBlockElement.value
2604
3591
  }, null, 8, ["element"])) : createCommentVNode("", true),
2605
- controlsOpened.value ? (openBlock(), createBlock(_sfc_main$h, {
3592
+ controlsOpened.value ? (openBlock(), createBlock(_sfc_main$z, {
2606
3593
  key: 1,
2607
3594
  element: unref(control).activeBlockElement.value,
2608
3595
  resizable: ""
2609
3596
  }, null, 8, ["element"])) : createCommentVNode("", true),
3597
+ unref(control).insertedPlace.value ? (openBlock(), createBlock(_sfc_main$y, {
3598
+ key: 2,
3599
+ top: unref(control).insertedPlace.value.top
3600
+ }, null, 8, ["top"])) : createCommentVNode("", true),
2610
3601
  createVNode(Transition, null, {
2611
3602
  default: withCtx(() => [
2612
- controlsOpened.value ? (openBlock(), createElementBlock("div", {
3603
+ controlsOpened.value ? (openBlock(), createBlock(_sfc_main$5, {
2613
3604
  key: 0,
2614
- class: "editor-sidebar-right editor-blocks-sidebar editor-component",
2615
- onBlockdrop: _cache[7] || (_cache[7] = withModifiers(() => {
2616
- }, ["stop"]))
2617
- }, [
2618
- createElementVNode("button", {
2619
- class: "editor-sidebar__close-button right",
2620
- onClick: _cache[4] || (_cache[4] = ($event) => controlsOpened.value = false)
2621
- }, [
2622
- createVNode(ChevronRightIcon)
3605
+ class: "editor-sidebar-right editor-component",
3606
+ onBlockdrop: _cache[2] || (_cache[2] = withModifiers(() => {
3607
+ }, ["stop"])),
3608
+ state,
3609
+ "blocks-list": unref(blocksList),
3610
+ "blocks-map": unref(blocksMap),
3611
+ "active-block-id": unref(control).activeBlockId.value,
3612
+ "data-entries": unref(dataEntries2),
3613
+ dataEntryScopes: dataEntryScopes.value
3614
+ }, {
3615
+ default: withCtx(() => [
3616
+ createElementVNode("button", {
3617
+ class: "editor-sidebar__close-button right",
3618
+ onClick: _cache[1] || (_cache[1] = ($event) => controlsOpened.value = false)
3619
+ }, [
3620
+ createVNode(ChevronRightIcon)
3621
+ ])
2623
3622
  ]),
2624
- createVNode(_sfc_main$g, {
2625
- modelValue: currentTab.value,
2626
- "onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => currentTab.value = $event),
2627
- items: tabs.value
2628
- }, null, 8, ["modelValue", "items"]),
2629
- createVNode(_sfc_main$f, { page: currentTab.value }, {
2630
- blocks: withCtx(() => [
2631
- createVNode(_sfc_main$m, { blocks: unref(blocksList) }, null, 8, ["blocks"])
2632
- ]),
2633
- blockEdit: withCtx(() => [
2634
- currentBlock.value && currentContentBlock.value ? (openBlock(), createBlock(_sfc_main$4, {
2635
- key: currentContentBlock.value.id,
2636
- schema: currentBlock.value.props,
2637
- modelValue: currentContentBlock.value.data,
2638
- "onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => currentContentBlock.value.data = $event),
2639
- flat: ""
2640
- }, null, 8, ["schema", "modelValue"])) : (openBlock(), createElementBlock("div", _hoisted_1, "Схема для блока не найдена"))
2641
- ]),
2642
- _: 1
2643
- }, 8, ["page"])
2644
- ], 32)) : createCommentVNode("", true)
3623
+ _: 1
3624
+ }, 8, ["state", "blocks-list", "blocks-map", "active-block-id", "data-entries", "dataEntryScopes"])) : createCommentVNode("", true)
2645
3625
  ]),
2646
3626
  _: 1
2647
3627
  }),
@@ -2650,7 +3630,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2650
3630
  !controlsOpened.value ? (openBlock(), createElementBlock("div", {
2651
3631
  key: 0,
2652
3632
  class: "editor-sidebar__close-button editor-component fixed",
2653
- onClick: _cache[8] || (_cache[8] = ($event) => controlsOpened.value = true)
3633
+ onClick: _cache[3] || (_cache[3] = ($event) => controlsOpened.value = true)
2654
3634
  }, [
2655
3635
  createVNode(ChevronRightIcon)
2656
3636
  ])) : createCommentVNode("", true)
@@ -2662,22 +3642,32 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
2662
3642
  !controlsOpened.value ? (openBlock(), createElementBlock("div", {
2663
3643
  key: 0,
2664
3644
  class: "editor-sidebar__close-button editor-component right fixed",
2665
- onClick: _cache[9] || (_cache[9] = ($event) => controlsOpened.value = true)
3645
+ onClick: _cache[4] || (_cache[4] = ($event) => controlsOpened.value = true)
2666
3646
  }, [
2667
3647
  createVNode(ChevronLeftIcon)
2668
3648
  ])) : createCommentVNode("", true)
2669
3649
  ]),
2670
3650
  _: 1
2671
- })
3651
+ }),
3652
+ createVNode(_sfc_main$e)
2672
3653
  ], 64);
2673
3654
  };
2674
3655
  }
2675
3656
  });
2676
- window.state = reactive(processState(window.state));
2677
3657
  const mountDiv = document.createElement("div");
2678
3658
  mountDiv.id = "data-mechanics-editor";
2679
3659
  document.body.append(mountDiv);
3660
+ const dataEntries = reactive([]);
2680
3661
  document.addEventListener("DOMContentLoaded", () => {
2681
- createApp(_sfc_main).mount(mountDiv);
3662
+ createApp(_sfc_main).provide("dataEntries", dataEntries).use(createDialogSystem()).mount(mountDiv);
2682
3663
  });
3664
+ globalThis._registerData = (dataEntry) => {
3665
+ dataEntry.props = unfoldSchema(dataEntry.props);
3666
+ const exists = dataEntries.find((item) => item.id === dataEntry.id);
3667
+ if (exists) {
3668
+ Object.assign(exists, dataEntry);
3669
+ } else {
3670
+ dataEntries.push(dataEntry);
3671
+ }
3672
+ };
2683
3673
  //# sourceMappingURL=editor.js.map