@tmagic/editor 1.4.4 → 1.4.6
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/style.css +2 -2
- package/dist/tmagic-editor.js +2393 -2242
- package/dist/tmagic-editor.umd.cjs +2403 -2248
- package/package.json +27 -27
- package/src/editorProps.ts +5 -1
- package/src/fields/DataSourceFieldSelect.vue +3 -41
- package/src/fields/EventSelect.vue +30 -9
- package/src/hooks/use-code-block-edit.ts +0 -2
- package/src/hooks/use-stage.ts +1 -1
- package/src/index.ts +1 -0
- package/src/initService.ts +12 -2
- package/src/layouts/workspace/viewer/Stage.vue +7 -6
- package/src/services/codeBlock.ts +77 -9
- package/src/services/dataSource.ts +53 -4
- package/src/services/editor.ts +2 -2
- package/src/services/props.ts +10 -5
- package/src/services/stageOverlay.ts +1 -0
- package/src/type.ts +1 -0
- package/src/utils/content-menu.ts +7 -3
- package/src/utils/data-source/index.ts +39 -3
- package/src/utils/editor.ts +16 -7
- package/types/components/CodeBlockEditor.vue.d.ts +21 -34
- package/types/components/CodeParams.vue.d.ts +2 -2
- package/types/components/ContentMenu.vue.d.ts +1 -1
- package/types/components/FloatingBox.vue.d.ts +41 -38
- package/types/components/ScrollViewer.vue.d.ts +1 -1
- package/types/components/ToolButton.vue.d.ts +4 -4
- package/types/components/Tree.vue.d.ts +2 -2
- package/types/editorProps.d.ts +5 -1
- package/types/fields/CodeLink.vue.d.ts +2 -2
- package/types/fields/DataSourceFields.vue.d.ts +32 -78
- package/types/fields/DataSourceInput.vue.d.ts +2 -2
- package/types/fields/DataSourceMethods.vue.d.ts +2 -2
- package/types/fields/DataSourceMocks.vue.d.ts +31 -76
- package/types/fields/KeyValue.vue.d.ts +2 -2
- package/types/fields/UISelect.vue.d.ts +2 -2
- package/types/hooks/use-code-block-edit.d.ts +18 -6
- package/types/hooks/use-data-source-edit.d.ts +18 -6
- package/types/hooks/use-data-source-method.d.ts +18 -6
- package/types/index.d.ts +1 -0
- package/types/layouts/CodeEditor.vue.d.ts +1 -1
- package/types/layouts/PropsPanel.vue.d.ts +14 -14
- package/types/layouts/sidebar/data-source/DataSourceConfigPanel.vue.d.ts +20 -30
- package/types/layouts/sidebar/layer/LayerMenu.vue.d.ts +6 -6
- package/types/layouts/workspace/viewer/Stage.vue.d.ts +4 -4
- package/types/layouts/workspace/viewer/ViewerMenu.vue.d.ts +6 -6
- package/types/services/codeBlock.d.ts +22 -2
- package/types/services/dataSource.d.ts +13 -1
- package/types/services/ui.d.ts +1 -1
- package/types/type.d.ts +1 -0
- package/types/utils/data-source/index.d.ts +3 -2
- package/types/utils/editor.d.ts +2 -0
package/dist/tmagic-editor.js
CHANGED
|
@@ -8,13 +8,13 @@ import * as monaco from 'monaco-editor';
|
|
|
8
8
|
import { MContainer, MForm, filterFunction, createValues, MFormBox, MCascader, MSelect, MPanel } from '@tmagic/form';
|
|
9
9
|
import { HookCodeType, HookType, NodeType, ActionType } from '@tmagic/schema';
|
|
10
10
|
import { MagicTable } from '@tmagic/table';
|
|
11
|
-
import { toLine, guid, isPage, isPageFragment, isPop,
|
|
11
|
+
import { toLine, guid, getNodePath, getValueByKeyPath, setValueByKeyPath, isPage, isPageFragment, isPop, isNumber, calcValueByFontsize, convertToNumber, getDefaultValueFromFields, DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX, DATA_SOURCE_FIELDS_CHANGE_EVENT_PREFIX, getKeys, addClassName, removeClassName, removeClassNameByClassName, getNodes } from '@tmagic/utils';
|
|
12
12
|
import VanillaMoveable from 'moveable';
|
|
13
|
-
import { Watcher, DepTargetType,
|
|
13
|
+
import { Watcher, DepTargetType, createRelatedTargetForCopy, createCodeBlockTarget, createDataSourceTarget, createDataSourceMethodTarget, createDataSourceCondTarget } from '@tmagic/dep';
|
|
14
14
|
export { DepTargetType } from '@tmagic/dep';
|
|
15
15
|
import { EventEmitter } from 'events';
|
|
16
16
|
import Gesto from 'gesto';
|
|
17
|
-
import StageCore, { GuidesType, getOffset,
|
|
17
|
+
import StageCore, { GuidesType, getOffset, RenderType, CONTAINER_HIGHLIGHT_CLASS_NAME, ContainerHighlightType } from '@tmagic/stage';
|
|
18
18
|
import { DEFAULT_EVENTS, DEFAULT_METHODS } from '@tmagic/core';
|
|
19
19
|
import KeyController from 'keycon';
|
|
20
20
|
|
|
@@ -505,362 +505,94 @@ const _sfc_main$Q = /* @__PURE__ */ defineComponent({
|
|
|
505
505
|
}
|
|
506
506
|
});
|
|
507
507
|
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
rules: [
|
|
524
|
-
{
|
|
525
|
-
required: true,
|
|
526
|
-
message: "请输入名称"
|
|
508
|
+
const compose = (middleware, isAsync) => {
|
|
509
|
+
if (!Array.isArray(middleware))
|
|
510
|
+
throw new TypeError("Middleware 必须是一个数组!");
|
|
511
|
+
for (const fn of middleware) {
|
|
512
|
+
if (typeof fn !== "function")
|
|
513
|
+
throw new TypeError("Middleware 必须由函数组成!");
|
|
514
|
+
}
|
|
515
|
+
return (args, next) => {
|
|
516
|
+
let index = -1;
|
|
517
|
+
return dispatch(0);
|
|
518
|
+
function dispatch(i) {
|
|
519
|
+
if (i <= index) {
|
|
520
|
+
const error = new Error("next() 被多次调用");
|
|
521
|
+
if (isAsync) {
|
|
522
|
+
return Promise.reject(error);
|
|
527
523
|
}
|
|
528
|
-
|
|
529
|
-
},
|
|
530
|
-
{
|
|
531
|
-
name: "description",
|
|
532
|
-
text: "描述"
|
|
533
|
-
}
|
|
534
|
-
];
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
const HttpFormConfig = [
|
|
538
|
-
{
|
|
539
|
-
name: "autoFetch",
|
|
540
|
-
text: "自动请求",
|
|
541
|
-
type: "switch",
|
|
542
|
-
defaultValue: true
|
|
543
|
-
},
|
|
544
|
-
{
|
|
545
|
-
name: "responseOptions",
|
|
546
|
-
items: [
|
|
547
|
-
{
|
|
548
|
-
name: "dataPath",
|
|
549
|
-
text: "数据路径"
|
|
524
|
+
throw error;
|
|
550
525
|
}
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
text: "URL"
|
|
561
|
-
},
|
|
562
|
-
{
|
|
563
|
-
name: "method",
|
|
564
|
-
text: "Method",
|
|
565
|
-
type: "select",
|
|
566
|
-
options: [
|
|
567
|
-
{ text: "GET", value: "GET" },
|
|
568
|
-
{ text: "POST", value: "POST" },
|
|
569
|
-
{ text: "PUT", value: "PUT" },
|
|
570
|
-
{ text: "DELETE", value: "DELETE" }
|
|
571
|
-
]
|
|
572
|
-
},
|
|
573
|
-
{
|
|
574
|
-
name: "params",
|
|
575
|
-
type: "key-value",
|
|
576
|
-
defaultValue: {},
|
|
577
|
-
text: "参数"
|
|
578
|
-
},
|
|
579
|
-
{
|
|
580
|
-
name: "data",
|
|
581
|
-
type: "key-value",
|
|
582
|
-
defaultValue: {},
|
|
583
|
-
advanced: true,
|
|
584
|
-
text: "请求体"
|
|
585
|
-
},
|
|
586
|
-
{
|
|
587
|
-
name: "headers",
|
|
588
|
-
type: "key-value",
|
|
589
|
-
defaultValue: {},
|
|
590
|
-
text: "请求头"
|
|
526
|
+
index = i;
|
|
527
|
+
let fn = middleware[i];
|
|
528
|
+
if (i === middleware.length && next)
|
|
529
|
+
fn = next;
|
|
530
|
+
if (!fn) {
|
|
531
|
+
if (isAsync) {
|
|
532
|
+
return Promise.resolve();
|
|
533
|
+
}
|
|
534
|
+
return;
|
|
591
535
|
}
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
536
|
+
if (isAsync) {
|
|
537
|
+
try {
|
|
538
|
+
return Promise.resolve(fn(...args, dispatch.bind(null, i + 1)));
|
|
539
|
+
} catch (err) {
|
|
540
|
+
return Promise.reject(err);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
try {
|
|
544
|
+
return fn(...args, dispatch.bind(null, i + 1));
|
|
545
|
+
} catch (err) {
|
|
546
|
+
throw err;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
};
|
|
550
|
+
};
|
|
595
551
|
|
|
596
|
-
const
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
{
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
type: "data-source-fields",
|
|
608
|
-
defaultValue: () => []
|
|
609
|
-
}
|
|
610
|
-
]
|
|
611
|
-
},
|
|
612
|
-
{
|
|
613
|
-
title: "方法定义",
|
|
614
|
-
items: [
|
|
615
|
-
{
|
|
616
|
-
name: "methods",
|
|
617
|
-
type: "data-source-methods",
|
|
618
|
-
defaultValue: () => []
|
|
619
|
-
}
|
|
620
|
-
]
|
|
621
|
-
},
|
|
622
|
-
{
|
|
623
|
-
title: "事件配置",
|
|
624
|
-
display: false,
|
|
625
|
-
items: [
|
|
626
|
-
{
|
|
627
|
-
name: "events",
|
|
628
|
-
src: "datasource",
|
|
629
|
-
type: "event-select"
|
|
630
|
-
}
|
|
631
|
-
]
|
|
632
|
-
},
|
|
633
|
-
{
|
|
634
|
-
title: "mock数据",
|
|
635
|
-
items: [
|
|
636
|
-
{
|
|
637
|
-
name: "mocks",
|
|
638
|
-
type: "data-source-mocks",
|
|
639
|
-
defaultValue: () => []
|
|
640
|
-
}
|
|
641
|
-
]
|
|
642
|
-
},
|
|
643
|
-
{
|
|
644
|
-
title: "请求参数裁剪",
|
|
645
|
-
display: (formState, { model }) => model.type === "http",
|
|
646
|
-
items: [
|
|
647
|
-
{
|
|
648
|
-
name: "beforeRequest",
|
|
649
|
-
type: "vs-code",
|
|
650
|
-
parse: true,
|
|
651
|
-
height: "600px"
|
|
652
|
-
}
|
|
653
|
-
]
|
|
654
|
-
},
|
|
655
|
-
{
|
|
656
|
-
title: "响应数据裁剪",
|
|
657
|
-
display: (formState, { model }) => model.type === "http",
|
|
658
|
-
items: [
|
|
659
|
-
{
|
|
660
|
-
name: "afterResponse",
|
|
661
|
-
type: "vs-code",
|
|
662
|
-
parse: true,
|
|
663
|
-
height: "600px"
|
|
664
|
-
}
|
|
665
|
-
]
|
|
552
|
+
const methodName = (prefix, name) => `${prefix}${name[0].toUpperCase()}${name.substring(1)}`;
|
|
553
|
+
const isError = (error) => Object.prototype.toString.call(error) === "[object Error]";
|
|
554
|
+
const doAction = (args, scope, sourceMethod, beforeMethodName, afterMethodName, fn) => {
|
|
555
|
+
try {
|
|
556
|
+
let beforeArgs = args;
|
|
557
|
+
for (const beforeMethod of scope.pluginOptionsList[beforeMethodName]) {
|
|
558
|
+
beforeArgs = beforeMethod(...beforeArgs) || [];
|
|
559
|
+
if (isError(beforeArgs))
|
|
560
|
+
throw beforeArgs;
|
|
561
|
+
if (!Array.isArray(beforeArgs)) {
|
|
562
|
+
beforeArgs = [beforeArgs];
|
|
666
563
|
}
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
]
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
return fillConfig$1(configs[type] || []);
|
|
564
|
+
}
|
|
565
|
+
let returnValue = fn(beforeArgs, sourceMethod.bind(scope));
|
|
566
|
+
for (const afterMethod of scope.pluginOptionsList[afterMethodName]) {
|
|
567
|
+
returnValue = afterMethod(returnValue, ...beforeArgs);
|
|
568
|
+
if (isError(returnValue))
|
|
569
|
+
throw returnValue;
|
|
570
|
+
}
|
|
571
|
+
return returnValue;
|
|
572
|
+
} catch (error) {
|
|
573
|
+
throw error;
|
|
678
574
|
}
|
|
679
575
|
};
|
|
680
|
-
const
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
* // 请求方法 GET/POST
|
|
701
|
-
* method?: Method;
|
|
702
|
-
* }
|
|
703
|
-
*
|
|
704
|
-
* context:上下文对象
|
|
705
|
-
*
|
|
706
|
-
* interface Content {
|
|
707
|
-
* app: AppCore;
|
|
708
|
-
* dataSource: HttpDataSource;
|
|
709
|
-
* }
|
|
710
|
-
*
|
|
711
|
-
* return: HttpOptions
|
|
712
|
-
*/
|
|
713
|
-
|
|
714
|
-
// 此处的返回值会作为这个接口的入参
|
|
715
|
-
return options;
|
|
716
|
-
}`,
|
|
717
|
-
afterResponse: `(response, context) => {
|
|
718
|
-
/**
|
|
719
|
-
* 用户可以直接编写函数,在原始接口返回之后,会运行该函数,将这个函数的返回值作为该数据源接口的返回
|
|
720
|
-
|
|
721
|
-
* context:上下文对象
|
|
722
|
-
*
|
|
723
|
-
* interface Content {
|
|
724
|
-
* app: AppCore;
|
|
725
|
-
* dataSource: HttpDataSource;
|
|
726
|
-
* }
|
|
727
|
-
*
|
|
728
|
-
*/
|
|
729
|
-
|
|
730
|
-
// 此处的返回值会作为这个接口的返回值
|
|
731
|
-
return response;
|
|
732
|
-
}`,
|
|
733
|
-
...values
|
|
734
|
-
};
|
|
735
|
-
};
|
|
736
|
-
const getDisplayField = (dataSources, key) => {
|
|
737
|
-
const displayState = [];
|
|
738
|
-
const matches = key.matchAll(/\$\{([\s\S]+?)\}/g);
|
|
739
|
-
let index = 0;
|
|
740
|
-
for (const match of matches) {
|
|
741
|
-
if (typeof match.index === "undefined")
|
|
742
|
-
break;
|
|
743
|
-
displayState.push({
|
|
744
|
-
type: "text",
|
|
745
|
-
value: key.substring(index, match.index)
|
|
746
|
-
});
|
|
747
|
-
let dsText = "";
|
|
748
|
-
let ds;
|
|
749
|
-
let fields;
|
|
750
|
-
match[1].split(".").forEach((item, index2) => {
|
|
751
|
-
if (index2 === 0) {
|
|
752
|
-
ds = dataSources.find((ds2) => ds2.id === item);
|
|
753
|
-
dsText += ds?.title || item;
|
|
754
|
-
fields = ds?.fields;
|
|
755
|
-
return;
|
|
756
|
-
}
|
|
757
|
-
const field = fields?.find((field2) => field2.name === item);
|
|
758
|
-
fields = field?.fields;
|
|
759
|
-
dsText += `.${field?.title || item}`;
|
|
760
|
-
});
|
|
761
|
-
displayState.push({
|
|
762
|
-
type: "var",
|
|
763
|
-
value: dsText
|
|
764
|
-
});
|
|
765
|
-
index = match.index + match[0].length;
|
|
766
|
-
}
|
|
767
|
-
if (index < key.length) {
|
|
768
|
-
displayState.push({
|
|
769
|
-
type: "text",
|
|
770
|
-
value: key.substring(index)
|
|
771
|
-
});
|
|
772
|
-
}
|
|
773
|
-
return displayState;
|
|
774
|
-
};
|
|
775
|
-
|
|
776
|
-
const compose = (middleware, isAsync) => {
|
|
777
|
-
if (!Array.isArray(middleware))
|
|
778
|
-
throw new TypeError("Middleware 必须是一个数组!");
|
|
779
|
-
for (const fn of middleware) {
|
|
780
|
-
if (typeof fn !== "function")
|
|
781
|
-
throw new TypeError("Middleware 必须由函数组成!");
|
|
782
|
-
}
|
|
783
|
-
return (args, next) => {
|
|
784
|
-
let index = -1;
|
|
785
|
-
return dispatch(0);
|
|
786
|
-
function dispatch(i) {
|
|
787
|
-
if (i <= index) {
|
|
788
|
-
const error = new Error("next() 被多次调用");
|
|
789
|
-
if (isAsync) {
|
|
790
|
-
return Promise.reject(error);
|
|
791
|
-
}
|
|
792
|
-
throw error;
|
|
793
|
-
}
|
|
794
|
-
index = i;
|
|
795
|
-
let fn = middleware[i];
|
|
796
|
-
if (i === middleware.length && next)
|
|
797
|
-
fn = next;
|
|
798
|
-
if (!fn) {
|
|
799
|
-
if (isAsync) {
|
|
800
|
-
return Promise.resolve();
|
|
801
|
-
}
|
|
802
|
-
return;
|
|
803
|
-
}
|
|
804
|
-
if (isAsync) {
|
|
805
|
-
try {
|
|
806
|
-
return Promise.resolve(fn(...args, dispatch.bind(null, i + 1)));
|
|
807
|
-
} catch (err) {
|
|
808
|
-
return Promise.reject(err);
|
|
809
|
-
}
|
|
810
|
-
}
|
|
811
|
-
try {
|
|
812
|
-
return fn(...args, dispatch.bind(null, i + 1));
|
|
813
|
-
} catch (err) {
|
|
814
|
-
throw err;
|
|
815
|
-
}
|
|
816
|
-
}
|
|
817
|
-
};
|
|
818
|
-
};
|
|
819
|
-
|
|
820
|
-
const methodName = (prefix, name) => `${prefix}${name[0].toUpperCase()}${name.substring(1)}`;
|
|
821
|
-
const isError = (error) => Object.prototype.toString.call(error) === "[object Error]";
|
|
822
|
-
const doAction = (args, scope, sourceMethod, beforeMethodName, afterMethodName, fn) => {
|
|
823
|
-
try {
|
|
824
|
-
let beforeArgs = args;
|
|
825
|
-
for (const beforeMethod of scope.pluginOptionsList[beforeMethodName]) {
|
|
826
|
-
beforeArgs = beforeMethod(...beforeArgs) || [];
|
|
827
|
-
if (isError(beforeArgs))
|
|
828
|
-
throw beforeArgs;
|
|
829
|
-
if (!Array.isArray(beforeArgs)) {
|
|
830
|
-
beforeArgs = [beforeArgs];
|
|
831
|
-
}
|
|
832
|
-
}
|
|
833
|
-
let returnValue = fn(beforeArgs, sourceMethod.bind(scope));
|
|
834
|
-
for (const afterMethod of scope.pluginOptionsList[afterMethodName]) {
|
|
835
|
-
returnValue = afterMethod(returnValue, ...beforeArgs);
|
|
836
|
-
if (isError(returnValue))
|
|
837
|
-
throw returnValue;
|
|
838
|
-
}
|
|
839
|
-
return returnValue;
|
|
840
|
-
} catch (error) {
|
|
841
|
-
throw error;
|
|
842
|
-
}
|
|
843
|
-
};
|
|
844
|
-
const doAsyncAction = async (args, scope, sourceMethod, beforeMethodName, afterMethodName, fn) => {
|
|
845
|
-
try {
|
|
846
|
-
let beforeArgs = args;
|
|
847
|
-
for (const beforeMethod of scope.pluginOptionsList[beforeMethodName]) {
|
|
848
|
-
beforeArgs = await beforeMethod(...beforeArgs) || [];
|
|
849
|
-
if (isError(beforeArgs))
|
|
850
|
-
throw beforeArgs;
|
|
851
|
-
if (!Array.isArray(beforeArgs)) {
|
|
852
|
-
beforeArgs = [beforeArgs];
|
|
853
|
-
}
|
|
854
|
-
}
|
|
855
|
-
let returnValue = await fn(beforeArgs, sourceMethod.bind(scope));
|
|
856
|
-
for (const afterMethod of scope.pluginOptionsList[afterMethodName]) {
|
|
857
|
-
returnValue = await afterMethod(returnValue, ...beforeArgs);
|
|
858
|
-
if (isError(returnValue))
|
|
859
|
-
throw returnValue;
|
|
860
|
-
}
|
|
861
|
-
return returnValue;
|
|
862
|
-
} catch (error) {
|
|
863
|
-
throw error;
|
|
576
|
+
const doAsyncAction = async (args, scope, sourceMethod, beforeMethodName, afterMethodName, fn) => {
|
|
577
|
+
try {
|
|
578
|
+
let beforeArgs = args;
|
|
579
|
+
for (const beforeMethod of scope.pluginOptionsList[beforeMethodName]) {
|
|
580
|
+
beforeArgs = await beforeMethod(...beforeArgs) || [];
|
|
581
|
+
if (isError(beforeArgs))
|
|
582
|
+
throw beforeArgs;
|
|
583
|
+
if (!Array.isArray(beforeArgs)) {
|
|
584
|
+
beforeArgs = [beforeArgs];
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
let returnValue = await fn(beforeArgs, sourceMethod.bind(scope));
|
|
588
|
+
for (const afterMethod of scope.pluginOptionsList[afterMethodName]) {
|
|
589
|
+
returnValue = await afterMethod(returnValue, ...beforeArgs);
|
|
590
|
+
if (isError(returnValue))
|
|
591
|
+
throw returnValue;
|
|
592
|
+
}
|
|
593
|
+
return returnValue;
|
|
594
|
+
} catch (error) {
|
|
595
|
+
throw error;
|
|
864
596
|
}
|
|
865
597
|
};
|
|
866
598
|
class BaseService extends EventEmitter {
|
|
@@ -936,590 +668,500 @@ class BaseService extends EventEmitter {
|
|
|
936
668
|
}
|
|
937
669
|
}
|
|
938
670
|
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
"
|
|
944
|
-
"getFormValue",
|
|
945
|
-
"setFormValue",
|
|
946
|
-
"getFormEvent",
|
|
947
|
-
"setFormEvent",
|
|
948
|
-
"getFormMethod",
|
|
949
|
-
"setFormMethod",
|
|
950
|
-
"add",
|
|
951
|
-
"update",
|
|
952
|
-
"remove",
|
|
953
|
-
"createId"
|
|
954
|
-
]
|
|
955
|
-
};
|
|
956
|
-
class DataSource extends BaseService {
|
|
957
|
-
state = reactive({
|
|
958
|
-
datasourceTypeList: [],
|
|
959
|
-
dataSources: [],
|
|
960
|
-
editable: true,
|
|
961
|
-
configs: {},
|
|
962
|
-
values: {},
|
|
963
|
-
events: {},
|
|
964
|
-
methods: {}
|
|
965
|
-
});
|
|
966
|
-
constructor() {
|
|
967
|
-
super(canUsePluginMethods$6.sync.map((methodName) => ({ name: methodName, isAsync: false })));
|
|
671
|
+
class Dep extends BaseService {
|
|
672
|
+
watcher = new Watcher({ initialTargets: reactive({}) });
|
|
673
|
+
removeTargets(type = DepTargetType.DEFAULT) {
|
|
674
|
+
this.watcher.removeTargets(type);
|
|
675
|
+
this.emit("remove-target");
|
|
968
676
|
}
|
|
969
|
-
|
|
970
|
-
this.
|
|
677
|
+
getTargets(type = DepTargetType.DEFAULT) {
|
|
678
|
+
return this.watcher.getTargets(type);
|
|
971
679
|
}
|
|
972
|
-
|
|
973
|
-
return this.
|
|
680
|
+
getTarget(id, type = DepTargetType.DEFAULT) {
|
|
681
|
+
return this.watcher.getTarget(id, type);
|
|
974
682
|
}
|
|
975
|
-
|
|
976
|
-
|
|
683
|
+
addTarget(target) {
|
|
684
|
+
this.watcher.addTarget(target);
|
|
685
|
+
this.emit("add-target", target);
|
|
977
686
|
}
|
|
978
|
-
|
|
979
|
-
this.
|
|
687
|
+
removeTarget(id, type = DepTargetType.DEFAULT) {
|
|
688
|
+
this.watcher.removeTarget(id, type);
|
|
689
|
+
this.emit("remove-target");
|
|
980
690
|
}
|
|
981
|
-
|
|
982
|
-
|
|
691
|
+
clearTargets() {
|
|
692
|
+
this.watcher.clearTargets();
|
|
983
693
|
}
|
|
984
|
-
|
|
985
|
-
this.
|
|
694
|
+
collect(nodes, deep = false, type) {
|
|
695
|
+
this.watcher.collect(nodes, deep, type);
|
|
696
|
+
this.emit("collected", nodes, deep);
|
|
986
697
|
}
|
|
987
|
-
|
|
988
|
-
return this.
|
|
698
|
+
clear(nodes) {
|
|
699
|
+
return this.watcher.clear(nodes);
|
|
989
700
|
}
|
|
990
|
-
|
|
991
|
-
this.
|
|
701
|
+
clearByType(type, nodes) {
|
|
702
|
+
return this.watcher.clearByType(type, nodes);
|
|
992
703
|
}
|
|
993
|
-
|
|
994
|
-
return this.
|
|
704
|
+
hasTarget(id, type = DepTargetType.DEFAULT) {
|
|
705
|
+
return this.watcher.hasTarget(id, type);
|
|
995
706
|
}
|
|
996
|
-
|
|
997
|
-
this.
|
|
707
|
+
hasSpecifiedTypeTarget(type = DepTargetType.DEFAULT) {
|
|
708
|
+
return this.watcher.hasSpecifiedTypeTarget(type);
|
|
998
709
|
}
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
710
|
+
}
|
|
711
|
+
const depService = new Dep();
|
|
712
|
+
|
|
713
|
+
const canUsePluginMethods$6 = {
|
|
714
|
+
async: [
|
|
715
|
+
"setPropsConfig",
|
|
716
|
+
"getPropsConfig",
|
|
717
|
+
"setPropsValue",
|
|
718
|
+
"getPropsValue",
|
|
719
|
+
"fillConfig",
|
|
720
|
+
"getDefaultPropsValue"
|
|
721
|
+
],
|
|
722
|
+
sync: ["createId", "setNewItemId"]
|
|
723
|
+
};
|
|
724
|
+
class Props extends BaseService {
|
|
725
|
+
state = reactive({
|
|
726
|
+
propsConfigMap: {},
|
|
727
|
+
propsValueMap: {},
|
|
728
|
+
relateIdMap: {}
|
|
729
|
+
});
|
|
730
|
+
constructor() {
|
|
731
|
+
super([
|
|
732
|
+
...canUsePluginMethods$6.async.map((methodName) => ({ name: methodName, isAsync: true })),
|
|
733
|
+
...canUsePluginMethods$6.sync.map((methodName) => ({ name: methodName, isAsync: false }))
|
|
734
|
+
]);
|
|
1007
735
|
}
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
this.emit("
|
|
1013
|
-
return config;
|
|
736
|
+
setPropsConfigs(configs) {
|
|
737
|
+
Object.keys(configs).forEach((type) => {
|
|
738
|
+
this.setPropsConfig(toLine(type), configs[type]);
|
|
739
|
+
});
|
|
740
|
+
this.emit("props-configs-change");
|
|
1014
741
|
}
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
const index = dataSources.findIndex((ds) => ds.id === id);
|
|
1018
|
-
dataSources.splice(index, 1);
|
|
1019
|
-
this.emit("remove", id);
|
|
742
|
+
async fillConfig(config, labelWidth) {
|
|
743
|
+
return fillConfig(config, typeof labelWidth !== "function" ? labelWidth : "80px");
|
|
1020
744
|
}
|
|
1021
|
-
|
|
1022
|
-
|
|
745
|
+
async setPropsConfig(type, config) {
|
|
746
|
+
this.state.propsConfigMap[toLine(type)] = await this.fillConfig(Array.isArray(config) ? config : [config]);
|
|
1023
747
|
}
|
|
1024
|
-
|
|
1025
|
-
|
|
748
|
+
/**
|
|
749
|
+
* 获取指点类型的组件属性表单配置
|
|
750
|
+
* @param type 组件类型
|
|
751
|
+
* @returns 组件属性表单配置
|
|
752
|
+
*/
|
|
753
|
+
async getPropsConfig(type) {
|
|
754
|
+
if (type === "area") {
|
|
755
|
+
return await this.getPropsConfig("button");
|
|
756
|
+
}
|
|
757
|
+
return cloneDeep(this.state.propsConfigMap[toLine(type)] || await this.fillConfig([]));
|
|
758
|
+
}
|
|
759
|
+
setPropsValues(values) {
|
|
760
|
+
Object.keys(values).forEach((type) => {
|
|
761
|
+
this.setPropsValue(toLine(type), values[type]);
|
|
762
|
+
});
|
|
763
|
+
}
|
|
764
|
+
/**
|
|
765
|
+
* 为指点类型组件设置组件初始值
|
|
766
|
+
* @param type 组件类型
|
|
767
|
+
* @param value 组件初始值
|
|
768
|
+
*/
|
|
769
|
+
async setPropsValue(type, value) {
|
|
770
|
+
this.state.propsValueMap[toLine(type)] = value;
|
|
771
|
+
}
|
|
772
|
+
/**
|
|
773
|
+
* 获取指定类型的组件初始值
|
|
774
|
+
* @param type 组件类型
|
|
775
|
+
* @returns 组件初始值
|
|
776
|
+
*/
|
|
777
|
+
async getPropsValue(componentType, { inputEvent, ...defaultValue } = {}) {
|
|
778
|
+
const type = toLine(componentType);
|
|
779
|
+
if (type === "area") {
|
|
780
|
+
const value = await this.getPropsValue("button");
|
|
781
|
+
value.className = "action-area";
|
|
782
|
+
value.text = "";
|
|
783
|
+
if (value.style) {
|
|
784
|
+
value.style.backgroundColor = "rgba(255, 255, 255, 0)";
|
|
785
|
+
}
|
|
786
|
+
return value;
|
|
787
|
+
}
|
|
788
|
+
const id = this.createId(type);
|
|
789
|
+
const defaultPropsValue = this.getDefaultPropsValue(type);
|
|
790
|
+
const data = this.setNewItemId(
|
|
791
|
+
cloneDeep({
|
|
792
|
+
type,
|
|
793
|
+
...defaultValue
|
|
794
|
+
})
|
|
795
|
+
);
|
|
796
|
+
return {
|
|
797
|
+
id,
|
|
798
|
+
...defaultPropsValue,
|
|
799
|
+
...mergeWith({}, cloneDeep(this.state.propsValueMap[type] || {}), data)
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
createId(type) {
|
|
803
|
+
return `${type}_${guid()}`;
|
|
804
|
+
}
|
|
805
|
+
/**
|
|
806
|
+
* 将组件与组件的子元素配置中的id都设置成一个新的ID
|
|
807
|
+
* 如果没有相同ID并且force为false则保持不变
|
|
808
|
+
* @param {Object} config 组件配置
|
|
809
|
+
* @param {Boolean} force 是否强制设置新的ID
|
|
810
|
+
*/
|
|
811
|
+
/* eslint no-param-reassign: ["error", { "props": false }] */
|
|
812
|
+
setNewItemId(config, force = true) {
|
|
813
|
+
if (force || editorService.getNodeById(config.id)) {
|
|
814
|
+
const newId = this.createId(config.type || "component");
|
|
815
|
+
this.setRelateId(config.id, newId);
|
|
816
|
+
config.id = newId;
|
|
817
|
+
}
|
|
818
|
+
if (config.items && Array.isArray(config.items)) {
|
|
819
|
+
for (const item of config.items) {
|
|
820
|
+
this.setNewItemId(item);
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
return config;
|
|
824
|
+
}
|
|
825
|
+
/**
|
|
826
|
+
* 获取默认属性配置
|
|
827
|
+
* @param type 组件类型
|
|
828
|
+
* @returns Object
|
|
829
|
+
*/
|
|
830
|
+
getDefaultPropsValue(type) {
|
|
831
|
+
return ["page", "container"].includes(type) ? {
|
|
832
|
+
type,
|
|
833
|
+
layout: "absolute",
|
|
834
|
+
style: {},
|
|
835
|
+
name: type,
|
|
836
|
+
items: []
|
|
837
|
+
} : {
|
|
838
|
+
type,
|
|
839
|
+
style: {},
|
|
840
|
+
name: type
|
|
841
|
+
};
|
|
1026
842
|
}
|
|
1027
843
|
resetState() {
|
|
1028
|
-
this.
|
|
844
|
+
this.state.propsConfigMap = {};
|
|
845
|
+
this.state.propsValueMap = {};
|
|
846
|
+
}
|
|
847
|
+
/**
|
|
848
|
+
* 替换关联ID
|
|
849
|
+
* @param originConfigs 原组件配置
|
|
850
|
+
* @param targetConfigs 待替换的组件配置
|
|
851
|
+
*/
|
|
852
|
+
replaceRelateId(originConfigs, targetConfigs) {
|
|
853
|
+
const relateIdMap = this.getRelateIdMap();
|
|
854
|
+
if (Object.keys(relateIdMap).length === 0)
|
|
855
|
+
return;
|
|
856
|
+
depService.clearByType(DepTargetType.RELATED_COMP_WHEN_COPY);
|
|
857
|
+
depService.collect(originConfigs, true, DepTargetType.RELATED_COMP_WHEN_COPY);
|
|
858
|
+
const target = depService.getTarget(DepTargetType.RELATED_COMP_WHEN_COPY, DepTargetType.RELATED_COMP_WHEN_COPY);
|
|
859
|
+
if (!target)
|
|
860
|
+
return;
|
|
861
|
+
originConfigs.forEach((config) => {
|
|
862
|
+
const newId = relateIdMap[config.id];
|
|
863
|
+
const path = getNodePath(newId, targetConfigs);
|
|
864
|
+
const targetConfig = path[path.length - 1];
|
|
865
|
+
if (!targetConfig)
|
|
866
|
+
return;
|
|
867
|
+
target.deps[config.id]?.keys?.forEach((fullKey) => {
|
|
868
|
+
const relateOriginId = getValueByKeyPath(fullKey, config);
|
|
869
|
+
const relateTargetId = relateIdMap[relateOriginId];
|
|
870
|
+
if (!relateTargetId)
|
|
871
|
+
return;
|
|
872
|
+
setValueByKeyPath(fullKey, relateTargetId, targetConfig);
|
|
873
|
+
});
|
|
874
|
+
if (config.items && Array.isArray(config.items)) {
|
|
875
|
+
this.replaceRelateId(config.items, targetConfigs);
|
|
876
|
+
}
|
|
877
|
+
});
|
|
878
|
+
}
|
|
879
|
+
/**
|
|
880
|
+
* 清除setNewItemId前后映射关系
|
|
881
|
+
*/
|
|
882
|
+
clearRelateId() {
|
|
883
|
+
this.state.relateIdMap = {};
|
|
1029
884
|
}
|
|
1030
885
|
destroy() {
|
|
1031
|
-
this.removeAllListeners();
|
|
1032
886
|
this.resetState();
|
|
887
|
+
this.removeAllListeners();
|
|
1033
888
|
this.removeAllPlugins();
|
|
1034
889
|
}
|
|
1035
890
|
usePlugin(options) {
|
|
1036
891
|
super.usePlugin(options);
|
|
1037
892
|
}
|
|
893
|
+
/**
|
|
894
|
+
* 获取setNewItemId前后映射关系
|
|
895
|
+
* @param oldId 原组件ID
|
|
896
|
+
* @returns 新旧ID映射
|
|
897
|
+
*/
|
|
898
|
+
getRelateIdMap() {
|
|
899
|
+
return this.state.relateIdMap;
|
|
900
|
+
}
|
|
901
|
+
/**
|
|
902
|
+
* 记录setNewItemId前后映射关系
|
|
903
|
+
* @param oldId 原组件ID
|
|
904
|
+
* @param newId 分配的新ID
|
|
905
|
+
*/
|
|
906
|
+
setRelateId(oldId, newId) {
|
|
907
|
+
this.state.relateIdMap[oldId] = newId;
|
|
908
|
+
}
|
|
1038
909
|
}
|
|
1039
|
-
const
|
|
910
|
+
const propsService = new Props();
|
|
1040
911
|
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
{
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
const styleTabConfig = {
|
|
1058
|
-
title: "样式",
|
|
1059
|
-
items: [
|
|
1060
|
-
{
|
|
1061
|
-
name: "style",
|
|
1062
|
-
items: [
|
|
1063
|
-
{
|
|
1064
|
-
type: "fieldset",
|
|
1065
|
-
legend: "位置",
|
|
1066
|
-
items: [
|
|
1067
|
-
{
|
|
1068
|
-
type: "data-source-field-select",
|
|
1069
|
-
name: "position",
|
|
1070
|
-
text: "固定定位",
|
|
1071
|
-
checkStrictly: false,
|
|
1072
|
-
dataSourceFieldType: ["string"],
|
|
1073
|
-
fieldConfig: {
|
|
1074
|
-
type: "checkbox",
|
|
1075
|
-
activeValue: "fixed",
|
|
1076
|
-
inactiveValue: "absolute",
|
|
1077
|
-
defaultValue: "absolute"
|
|
1078
|
-
}
|
|
1079
|
-
},
|
|
1080
|
-
{
|
|
1081
|
-
type: "data-source-field-select",
|
|
1082
|
-
name: "left",
|
|
1083
|
-
text: "left",
|
|
1084
|
-
checkStrictly: false,
|
|
1085
|
-
dataSourceFieldType: ["string", "number"],
|
|
1086
|
-
fieldConfig: {
|
|
1087
|
-
type: "text"
|
|
1088
|
-
}
|
|
1089
|
-
},
|
|
1090
|
-
{
|
|
1091
|
-
type: "data-source-field-select",
|
|
1092
|
-
name: "top",
|
|
1093
|
-
text: "top",
|
|
1094
|
-
checkStrictly: false,
|
|
1095
|
-
dataSourceFieldType: ["string", "number"],
|
|
1096
|
-
fieldConfig: {
|
|
1097
|
-
type: "text"
|
|
1098
|
-
},
|
|
1099
|
-
disabled: (vm, { model }) => model.position === "fixed" && model._magic_position === "fixedBottom"
|
|
1100
|
-
},
|
|
1101
|
-
{
|
|
1102
|
-
type: "data-source-field-select",
|
|
1103
|
-
name: "right",
|
|
1104
|
-
text: "right",
|
|
1105
|
-
checkStrictly: false,
|
|
1106
|
-
dataSourceFieldType: ["string", "number"],
|
|
1107
|
-
fieldConfig: {
|
|
1108
|
-
type: "text"
|
|
1109
|
-
}
|
|
1110
|
-
},
|
|
1111
|
-
{
|
|
1112
|
-
type: "data-source-field-select",
|
|
1113
|
-
name: "bottom",
|
|
1114
|
-
text: "bottom",
|
|
1115
|
-
checkStrictly: false,
|
|
1116
|
-
dataSourceFieldType: ["string", "number"],
|
|
1117
|
-
fieldConfig: {
|
|
1118
|
-
type: "text"
|
|
1119
|
-
},
|
|
1120
|
-
disabled: (vm, { model }) => model.position === "fixed" && model._magic_position === "fixedTop"
|
|
1121
|
-
}
|
|
1122
|
-
]
|
|
1123
|
-
},
|
|
1124
|
-
{
|
|
1125
|
-
type: "fieldset",
|
|
1126
|
-
legend: "盒子",
|
|
1127
|
-
items: [
|
|
1128
|
-
{
|
|
1129
|
-
type: "data-source-field-select",
|
|
1130
|
-
name: "width",
|
|
1131
|
-
text: "宽度",
|
|
1132
|
-
checkStrictly: false,
|
|
1133
|
-
dataSourceFieldType: ["string", "number"],
|
|
1134
|
-
fieldConfig: {
|
|
1135
|
-
type: "text"
|
|
1136
|
-
}
|
|
1137
|
-
},
|
|
1138
|
-
{
|
|
1139
|
-
type: "data-source-field-select",
|
|
1140
|
-
name: "height",
|
|
1141
|
-
text: "高度",
|
|
1142
|
-
checkStrictly: false,
|
|
1143
|
-
dataSourceFieldType: ["string", "number"],
|
|
1144
|
-
fieldConfig: {
|
|
1145
|
-
type: "text"
|
|
1146
|
-
}
|
|
1147
|
-
},
|
|
1148
|
-
{
|
|
1149
|
-
type: "data-source-field-select",
|
|
1150
|
-
text: "overflow",
|
|
1151
|
-
name: "overflow",
|
|
1152
|
-
checkStrictly: false,
|
|
1153
|
-
dataSourceFieldType: ["string"],
|
|
1154
|
-
fieldConfig: {
|
|
1155
|
-
type: "select",
|
|
1156
|
-
options: [
|
|
1157
|
-
{ text: "visible", value: "visible" },
|
|
1158
|
-
{ text: "hidden", value: "hidden" },
|
|
1159
|
-
{ text: "clip", value: "clip" },
|
|
1160
|
-
{ text: "scroll", value: "scroll" },
|
|
1161
|
-
{ text: "auto", value: "auto" },
|
|
1162
|
-
{ text: "overlay", value: "overlay" }
|
|
1163
|
-
]
|
|
1164
|
-
}
|
|
1165
|
-
}
|
|
1166
|
-
]
|
|
1167
|
-
},
|
|
1168
|
-
{
|
|
1169
|
-
type: "fieldset",
|
|
1170
|
-
legend: "边框",
|
|
1171
|
-
items: [
|
|
1172
|
-
{
|
|
1173
|
-
type: "data-source-field-select",
|
|
1174
|
-
name: "borderWidth",
|
|
1175
|
-
text: "宽度",
|
|
1176
|
-
defaultValue: "0",
|
|
1177
|
-
checkStrictly: false,
|
|
1178
|
-
dataSourceFieldType: ["string", "number"],
|
|
1179
|
-
fieldConfig: {
|
|
1180
|
-
type: "text"
|
|
1181
|
-
}
|
|
1182
|
-
},
|
|
1183
|
-
{
|
|
1184
|
-
type: "data-source-field-select",
|
|
1185
|
-
name: "borderColor",
|
|
1186
|
-
text: "颜色",
|
|
1187
|
-
checkStrictly: false,
|
|
1188
|
-
dataSourceFieldType: ["string"],
|
|
1189
|
-
fieldConfig: {
|
|
1190
|
-
type: "text"
|
|
1191
|
-
}
|
|
1192
|
-
},
|
|
1193
|
-
{
|
|
1194
|
-
type: "data-source-field-select",
|
|
1195
|
-
name: "borderStyle",
|
|
1196
|
-
text: "样式",
|
|
1197
|
-
defaultValue: "none",
|
|
1198
|
-
checkStrictly: false,
|
|
1199
|
-
dataSourceFieldType: ["string"],
|
|
1200
|
-
fieldConfig: {
|
|
1201
|
-
type: "select",
|
|
1202
|
-
options: [
|
|
1203
|
-
{ text: "none", value: "none" },
|
|
1204
|
-
{ text: "hidden", value: "hidden" },
|
|
1205
|
-
{ text: "dotted", value: "dotted" },
|
|
1206
|
-
{ text: "dashed", value: "dashed" },
|
|
1207
|
-
{ text: "solid", value: "solid" },
|
|
1208
|
-
{ text: "double", value: "double" },
|
|
1209
|
-
{ text: "groove", value: "groove" },
|
|
1210
|
-
{ text: "ridge", value: "ridge" },
|
|
1211
|
-
{ text: "inset", value: "inset" },
|
|
1212
|
-
{ text: "outset", value: "outset" }
|
|
1213
|
-
]
|
|
1214
|
-
}
|
|
1215
|
-
}
|
|
1216
|
-
]
|
|
1217
|
-
},
|
|
1218
|
-
{
|
|
1219
|
-
type: "fieldset",
|
|
1220
|
-
legend: "背景",
|
|
1221
|
-
items: [
|
|
1222
|
-
{
|
|
1223
|
-
type: "data-source-field-select",
|
|
1224
|
-
name: "backgroundImage",
|
|
1225
|
-
text: "背景图",
|
|
1226
|
-
checkStrictly: false,
|
|
1227
|
-
dataSourceFieldType: ["string"],
|
|
1228
|
-
fieldConfig: {
|
|
1229
|
-
type: "text"
|
|
1230
|
-
}
|
|
1231
|
-
},
|
|
1232
|
-
{
|
|
1233
|
-
type: "data-source-field-select",
|
|
1234
|
-
name: "backgroundColor",
|
|
1235
|
-
text: "背景颜色",
|
|
1236
|
-
checkStrictly: false,
|
|
1237
|
-
dataSourceFieldType: ["string"],
|
|
1238
|
-
fieldConfig: {
|
|
1239
|
-
type: "colorPicker"
|
|
1240
|
-
}
|
|
1241
|
-
},
|
|
1242
|
-
{
|
|
1243
|
-
type: "data-source-field-select",
|
|
1244
|
-
name: "backgroundRepeat",
|
|
1245
|
-
text: "背景图重复",
|
|
1246
|
-
defaultValue: "no-repeat",
|
|
1247
|
-
checkStrictly: false,
|
|
1248
|
-
dataSourceFieldType: ["string"],
|
|
1249
|
-
fieldConfig: {
|
|
1250
|
-
type: "select",
|
|
1251
|
-
options: [
|
|
1252
|
-
{ text: "repeat", value: "repeat" },
|
|
1253
|
-
{ text: "repeat-x", value: "repeat-x" },
|
|
1254
|
-
{ text: "repeat-y", value: "repeat-y" },
|
|
1255
|
-
{ text: "no-repeat", value: "no-repeat" },
|
|
1256
|
-
{ text: "inherit", value: "inherit" }
|
|
1257
|
-
]
|
|
1258
|
-
}
|
|
1259
|
-
},
|
|
1260
|
-
{
|
|
1261
|
-
type: "data-source-field-select",
|
|
1262
|
-
name: "backgroundSize",
|
|
1263
|
-
text: "背景图大小",
|
|
1264
|
-
defaultValue: "100% 100%",
|
|
1265
|
-
checkStrictly: false,
|
|
1266
|
-
dataSourceFieldType: ["string"],
|
|
1267
|
-
fieldConfig: {
|
|
1268
|
-
type: "text"
|
|
1269
|
-
}
|
|
1270
|
-
}
|
|
1271
|
-
]
|
|
1272
|
-
},
|
|
1273
|
-
{
|
|
1274
|
-
type: "fieldset",
|
|
1275
|
-
legend: "字体",
|
|
1276
|
-
items: [
|
|
1277
|
-
{
|
|
1278
|
-
type: "data-source-field-select",
|
|
1279
|
-
name: "color",
|
|
1280
|
-
text: "颜色",
|
|
1281
|
-
checkStrictly: false,
|
|
1282
|
-
dataSourceFieldType: ["string"],
|
|
1283
|
-
fieldConfig: {
|
|
1284
|
-
type: "colorPicker"
|
|
1285
|
-
}
|
|
1286
|
-
},
|
|
1287
|
-
{
|
|
1288
|
-
type: "data-source-field-select",
|
|
1289
|
-
name: "fontSize",
|
|
1290
|
-
text: "大小",
|
|
1291
|
-
checkStrictly: false,
|
|
1292
|
-
dataSourceFieldType: ["string", "number"],
|
|
1293
|
-
fieldConfig: {
|
|
1294
|
-
type: "text"
|
|
1295
|
-
}
|
|
1296
|
-
},
|
|
1297
|
-
{
|
|
1298
|
-
type: "data-source-field-select",
|
|
1299
|
-
name: "fontWeight",
|
|
1300
|
-
text: "粗细",
|
|
1301
|
-
checkStrictly: false,
|
|
1302
|
-
dataSourceFieldType: ["string", "number"],
|
|
1303
|
-
fieldConfig: {
|
|
1304
|
-
type: "text"
|
|
1305
|
-
}
|
|
1306
|
-
}
|
|
1307
|
-
]
|
|
1308
|
-
},
|
|
1309
|
-
{
|
|
1310
|
-
type: "fieldset",
|
|
1311
|
-
legend: "变形",
|
|
1312
|
-
name: "transform",
|
|
1313
|
-
items: [
|
|
1314
|
-
{
|
|
1315
|
-
type: "data-source-field-select",
|
|
1316
|
-
name: "rotate",
|
|
1317
|
-
text: "旋转角度",
|
|
1318
|
-
checkStrictly: false,
|
|
1319
|
-
dataSourceFieldType: ["string"],
|
|
1320
|
-
fieldConfig: {
|
|
1321
|
-
type: "text"
|
|
1322
|
-
}
|
|
1323
|
-
},
|
|
1324
|
-
{
|
|
1325
|
-
type: "data-source-field-select",
|
|
1326
|
-
name: "scale",
|
|
1327
|
-
text: "缩放",
|
|
1328
|
-
checkStrictly: false,
|
|
1329
|
-
dataSourceFieldType: ["number", "string"],
|
|
1330
|
-
fieldConfig: {
|
|
1331
|
-
type: "text"
|
|
1332
|
-
}
|
|
1333
|
-
}
|
|
1334
|
-
]
|
|
1335
|
-
}
|
|
1336
|
-
]
|
|
1337
|
-
}
|
|
1338
|
-
]
|
|
1339
|
-
};
|
|
1340
|
-
const eventTabConfig = {
|
|
1341
|
-
title: "事件",
|
|
1342
|
-
items: [
|
|
1343
|
-
{
|
|
1344
|
-
name: "events",
|
|
1345
|
-
src: "component",
|
|
1346
|
-
labelWidth: "100px",
|
|
1347
|
-
type: "event-select"
|
|
1348
|
-
}
|
|
1349
|
-
]
|
|
1350
|
-
};
|
|
1351
|
-
const advancedTabConfig = {
|
|
1352
|
-
title: "高级",
|
|
1353
|
-
lazy: true,
|
|
1354
|
-
items: [
|
|
1355
|
-
{
|
|
1356
|
-
name: "created",
|
|
1357
|
-
text: "created",
|
|
1358
|
-
type: "code-select"
|
|
1359
|
-
},
|
|
1360
|
-
{
|
|
1361
|
-
name: "mounted",
|
|
1362
|
-
text: "mounted",
|
|
1363
|
-
type: "code-select"
|
|
1364
|
-
}
|
|
1365
|
-
]
|
|
1366
|
-
};
|
|
1367
|
-
const displayTabConfig = {
|
|
1368
|
-
title: "显示条件",
|
|
1369
|
-
display: (vm, { model }) => model.type !== "page",
|
|
1370
|
-
items: [
|
|
1371
|
-
{
|
|
1372
|
-
type: "groupList",
|
|
1373
|
-
name: "displayConds",
|
|
1374
|
-
titlePrefix: "条件组",
|
|
1375
|
-
expandAll: true,
|
|
1376
|
-
items: [
|
|
1377
|
-
{
|
|
1378
|
-
type: "table",
|
|
1379
|
-
name: "cond",
|
|
1380
|
-
items: [
|
|
1381
|
-
{
|
|
1382
|
-
type: "data-source-field-select",
|
|
1383
|
-
name: "field",
|
|
1384
|
-
value: "key",
|
|
1385
|
-
label: "字段",
|
|
1386
|
-
checkStrictly: false,
|
|
1387
|
-
dataSourceFieldType: ["string", "number", "boolean", "any"]
|
|
1388
|
-
},
|
|
1389
|
-
{
|
|
1390
|
-
type: "select",
|
|
1391
|
-
options: (mForm, { model }) => {
|
|
1392
|
-
const [id, ...fieldNames] = model.field;
|
|
1393
|
-
const ds = dataSourceService.getDataSourceById(id);
|
|
1394
|
-
let fields = ds?.fields || [];
|
|
1395
|
-
let type = "";
|
|
1396
|
-
(fieldNames || []).forEach((fieldName) => {
|
|
1397
|
-
const field = fields.find((f) => f.name === fieldName);
|
|
1398
|
-
fields = field?.fields || [];
|
|
1399
|
-
type = field?.type || "";
|
|
1400
|
-
});
|
|
1401
|
-
if (type === "array") {
|
|
1402
|
-
return arrayOptions;
|
|
1403
|
-
}
|
|
1404
|
-
if (type === "boolean") {
|
|
1405
|
-
return [
|
|
1406
|
-
{ text: "是", value: "is" },
|
|
1407
|
-
{ text: "不是", value: "not" }
|
|
1408
|
-
];
|
|
1409
|
-
}
|
|
1410
|
-
if (type === "number") {
|
|
1411
|
-
return [...eqOptions, ...numberOptions];
|
|
1412
|
-
}
|
|
1413
|
-
if (type === "string") {
|
|
1414
|
-
return [...arrayOptions, ...eqOptions];
|
|
1415
|
-
}
|
|
1416
|
-
return [...arrayOptions, ...eqOptions, ...numberOptions];
|
|
1417
|
-
},
|
|
1418
|
-
label: "条件",
|
|
1419
|
-
name: "op"
|
|
1420
|
-
},
|
|
1421
|
-
{
|
|
1422
|
-
label: "值",
|
|
1423
|
-
items: [
|
|
1424
|
-
{
|
|
1425
|
-
name: "value",
|
|
1426
|
-
type: (mForm, { model }) => {
|
|
1427
|
-
const [id, ...fieldNames] = model.field;
|
|
1428
|
-
const ds = dataSourceService.getDataSourceById(id);
|
|
1429
|
-
let fields = ds?.fields || [];
|
|
1430
|
-
let type = "";
|
|
1431
|
-
(fieldNames || []).forEach((fieldName) => {
|
|
1432
|
-
const field = fields.find((f) => f.name === fieldName);
|
|
1433
|
-
fields = field?.fields || [];
|
|
1434
|
-
type = field?.type || "";
|
|
1435
|
-
});
|
|
1436
|
-
if (type === "number") {
|
|
1437
|
-
return "number";
|
|
1438
|
-
}
|
|
1439
|
-
if (type === "boolean") {
|
|
1440
|
-
return "select";
|
|
1441
|
-
}
|
|
1442
|
-
return "text";
|
|
1443
|
-
},
|
|
1444
|
-
options: [
|
|
1445
|
-
{ text: "true", value: true },
|
|
1446
|
-
{ text: "false", value: false }
|
|
1447
|
-
],
|
|
1448
|
-
display: (vm, { model }) => !["between", "not_between"].includes(model.op)
|
|
1449
|
-
},
|
|
1450
|
-
{
|
|
1451
|
-
name: "range",
|
|
1452
|
-
type: "number-range",
|
|
1453
|
-
display: (vm, { model }) => ["between", "not_between"].includes(model.op)
|
|
1454
|
-
}
|
|
1455
|
-
]
|
|
1456
|
-
}
|
|
1457
|
-
]
|
|
1458
|
-
}
|
|
1459
|
-
]
|
|
912
|
+
class UndoRedo {
|
|
913
|
+
elementList;
|
|
914
|
+
listCursor;
|
|
915
|
+
listMaxSize;
|
|
916
|
+
constructor(listMaxSize = 20) {
|
|
917
|
+
const minListMaxSize = 2;
|
|
918
|
+
this.elementList = [];
|
|
919
|
+
this.listCursor = 0;
|
|
920
|
+
this.listMaxSize = listMaxSize > minListMaxSize ? listMaxSize : minListMaxSize;
|
|
921
|
+
}
|
|
922
|
+
pushElement(element) {
|
|
923
|
+
this.elementList.splice(this.listCursor, this.elementList.length - this.listCursor, cloneDeep(element));
|
|
924
|
+
this.listCursor += 1;
|
|
925
|
+
if (this.elementList.length > this.listMaxSize) {
|
|
926
|
+
this.elementList.shift();
|
|
927
|
+
this.listCursor -= 1;
|
|
1460
928
|
}
|
|
1461
|
-
]
|
|
1462
|
-
};
|
|
1463
|
-
const fillConfig = (config = [], labelWidth = "80px") => [
|
|
1464
|
-
{
|
|
1465
|
-
type: "tab",
|
|
1466
|
-
labelWidth,
|
|
1467
|
-
items: [
|
|
1468
|
-
{
|
|
1469
|
-
title: "属性",
|
|
1470
|
-
items: [
|
|
1471
|
-
// 组件类型,必须要有
|
|
1472
|
-
{
|
|
1473
|
-
text: "type",
|
|
1474
|
-
name: "type",
|
|
1475
|
-
type: "hidden"
|
|
1476
|
-
},
|
|
1477
|
-
// 组件id,必须要有
|
|
1478
|
-
{
|
|
1479
|
-
name: "id",
|
|
1480
|
-
type: "display",
|
|
1481
|
-
text: "id"
|
|
1482
|
-
},
|
|
1483
|
-
{
|
|
1484
|
-
name: "name",
|
|
1485
|
-
text: "组件名称"
|
|
1486
|
-
},
|
|
1487
|
-
...config
|
|
1488
|
-
]
|
|
1489
|
-
},
|
|
1490
|
-
{ ...styleTabConfig },
|
|
1491
|
-
{ ...eventTabConfig },
|
|
1492
|
-
{ ...advancedTabConfig },
|
|
1493
|
-
{ ...displayTabConfig }
|
|
1494
|
-
]
|
|
1495
929
|
}
|
|
1496
|
-
|
|
930
|
+
canUndo() {
|
|
931
|
+
return this.listCursor > 1;
|
|
932
|
+
}
|
|
933
|
+
// 返回undo后的当前元素
|
|
934
|
+
undo() {
|
|
935
|
+
if (!this.canUndo()) {
|
|
936
|
+
return null;
|
|
937
|
+
}
|
|
938
|
+
this.listCursor -= 1;
|
|
939
|
+
return this.getCurrentElement();
|
|
940
|
+
}
|
|
941
|
+
canRedo() {
|
|
942
|
+
return this.elementList.length > this.listCursor;
|
|
943
|
+
}
|
|
944
|
+
// 返回redo后的当前元素
|
|
945
|
+
redo() {
|
|
946
|
+
if (!this.canRedo()) {
|
|
947
|
+
return null;
|
|
948
|
+
}
|
|
949
|
+
this.listCursor += 1;
|
|
950
|
+
return this.getCurrentElement();
|
|
951
|
+
}
|
|
952
|
+
getCurrentElement() {
|
|
953
|
+
if (this.listCursor < 1) {
|
|
954
|
+
return null;
|
|
955
|
+
}
|
|
956
|
+
return cloneDeep(this.elementList[this.listCursor - 1]);
|
|
957
|
+
}
|
|
958
|
+
}
|
|
1497
959
|
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
960
|
+
class History extends BaseService {
|
|
961
|
+
state = reactive({
|
|
962
|
+
pageSteps: {},
|
|
963
|
+
pageId: void 0,
|
|
964
|
+
canRedo: false,
|
|
965
|
+
canUndo: false
|
|
966
|
+
});
|
|
967
|
+
constructor() {
|
|
968
|
+
super([]);
|
|
969
|
+
this.on("change", this.setCanUndoRedo);
|
|
970
|
+
}
|
|
971
|
+
reset() {
|
|
972
|
+
this.state.pageSteps = {};
|
|
973
|
+
this.resetPage();
|
|
974
|
+
}
|
|
975
|
+
resetPage() {
|
|
976
|
+
this.state.pageId = void 0;
|
|
977
|
+
this.state.canRedo = false;
|
|
978
|
+
this.state.canUndo = false;
|
|
979
|
+
}
|
|
980
|
+
changePage(page) {
|
|
981
|
+
if (!page)
|
|
982
|
+
return;
|
|
983
|
+
this.state.pageId = page.id;
|
|
984
|
+
if (!this.state.pageSteps[this.state.pageId]) {
|
|
985
|
+
const undoRedo = new UndoRedo();
|
|
986
|
+
undoRedo.pushElement({
|
|
987
|
+
data: page,
|
|
988
|
+
modifiedNodeIds: /* @__PURE__ */ new Map(),
|
|
989
|
+
nodeId: page.id
|
|
990
|
+
});
|
|
991
|
+
this.state.pageSteps[this.state.pageId] = undoRedo;
|
|
992
|
+
}
|
|
993
|
+
this.setCanUndoRedo();
|
|
994
|
+
this.emit("page-change", this.state.pageSteps[this.state.pageId]);
|
|
995
|
+
}
|
|
996
|
+
resetState() {
|
|
997
|
+
this.state.pageId = void 0;
|
|
998
|
+
this.state.pageSteps = {};
|
|
999
|
+
this.state.canRedo = false;
|
|
1000
|
+
this.state.canUndo = false;
|
|
1001
|
+
}
|
|
1002
|
+
push(state) {
|
|
1003
|
+
const undoRedo = this.getUndoRedo();
|
|
1004
|
+
if (!undoRedo)
|
|
1005
|
+
return null;
|
|
1006
|
+
undoRedo.pushElement(state);
|
|
1007
|
+
this.emit("change", state);
|
|
1008
|
+
return state;
|
|
1009
|
+
}
|
|
1010
|
+
undo() {
|
|
1011
|
+
const undoRedo = this.getUndoRedo();
|
|
1012
|
+
if (!undoRedo)
|
|
1013
|
+
return null;
|
|
1014
|
+
const state = undoRedo.undo();
|
|
1015
|
+
this.emit("change", state);
|
|
1016
|
+
return state;
|
|
1017
|
+
}
|
|
1018
|
+
redo() {
|
|
1019
|
+
const undoRedo = this.getUndoRedo();
|
|
1020
|
+
if (!undoRedo)
|
|
1021
|
+
return null;
|
|
1022
|
+
const state = undoRedo.redo();
|
|
1023
|
+
this.emit("change", state);
|
|
1024
|
+
return state;
|
|
1025
|
+
}
|
|
1026
|
+
destroy() {
|
|
1027
|
+
this.resetState();
|
|
1028
|
+
this.removeAllListeners();
|
|
1029
|
+
this.removeAllPlugins();
|
|
1030
|
+
}
|
|
1031
|
+
getUndoRedo() {
|
|
1032
|
+
if (!this.state.pageId)
|
|
1033
|
+
return null;
|
|
1034
|
+
return this.state.pageSteps[this.state.pageId];
|
|
1035
|
+
}
|
|
1036
|
+
setCanUndoRedo() {
|
|
1037
|
+
const undoRedo = this.getUndoRedo();
|
|
1038
|
+
this.state.canRedo = undoRedo?.canRedo() || false;
|
|
1039
|
+
this.state.canUndo = undoRedo?.canUndo() || false;
|
|
1501
1040
|
}
|
|
1041
|
+
}
|
|
1042
|
+
const historyService = new History();
|
|
1043
|
+
|
|
1044
|
+
var Protocol = /* @__PURE__ */ ((Protocol2) => {
|
|
1045
|
+
Protocol2["OBJECT"] = "object";
|
|
1046
|
+
Protocol2["JSON"] = "json";
|
|
1047
|
+
Protocol2["STRING"] = "string";
|
|
1048
|
+
Protocol2["NUMBER"] = "number";
|
|
1049
|
+
Protocol2["BOOLEAN"] = "boolean";
|
|
1050
|
+
return Protocol2;
|
|
1051
|
+
})(Protocol || {});
|
|
1052
|
+
const canUsePluginMethods$5 = {
|
|
1053
|
+
async: [],
|
|
1054
|
+
sync: ["getStorage", "getNamespace", "clear", "getItem", "removeItem", "setItem"]
|
|
1502
1055
|
};
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1056
|
+
class WebStorage extends BaseService {
|
|
1057
|
+
storage = globalThis.localStorage;
|
|
1058
|
+
namespace = "tmagic";
|
|
1059
|
+
constructor() {
|
|
1060
|
+
super(canUsePluginMethods$5.sync.map((methodName) => ({ name: methodName, isAsync: false })));
|
|
1061
|
+
}
|
|
1062
|
+
/**
|
|
1063
|
+
* 获取数据存储对象,可以通过
|
|
1064
|
+
* const storageService = new StorageService();
|
|
1065
|
+
* storageService.usePlugin({
|
|
1066
|
+
* // 替换存储对象为 sessionStorage
|
|
1067
|
+
* async afterGetStorage(): Promise<Storage> {
|
|
1068
|
+
* return window.sessionStorage;
|
|
1069
|
+
* },
|
|
1070
|
+
* });
|
|
1071
|
+
*/
|
|
1072
|
+
getStorage() {
|
|
1073
|
+
return this.storage;
|
|
1074
|
+
}
|
|
1075
|
+
getNamespace() {
|
|
1076
|
+
return this.namespace;
|
|
1077
|
+
}
|
|
1078
|
+
/**
|
|
1079
|
+
* 清理,支持storageService.usePlugin
|
|
1080
|
+
*/
|
|
1081
|
+
clear() {
|
|
1082
|
+
const storage = this.getStorage();
|
|
1083
|
+
storage.clear();
|
|
1084
|
+
}
|
|
1085
|
+
/**
|
|
1086
|
+
* 获取存储项,支持storageService.usePlugin
|
|
1087
|
+
*/
|
|
1088
|
+
getItem(key, options = {}) {
|
|
1089
|
+
const storage = this.getStorage();
|
|
1090
|
+
const namespace = this.getNamespace();
|
|
1091
|
+
const { protocol = options.protocol, item } = this.getValueAndProtocol(
|
|
1092
|
+
storage.getItem(`${options.namespace || namespace}:${key}`)
|
|
1093
|
+
);
|
|
1094
|
+
if (item === null)
|
|
1095
|
+
return null;
|
|
1096
|
+
switch (protocol) {
|
|
1097
|
+
case "object" /* OBJECT */:
|
|
1098
|
+
return getConfig("parseDSL")(`(${item})`);
|
|
1099
|
+
case "json" /* JSON */:
|
|
1100
|
+
return JSON.parse(item);
|
|
1101
|
+
case "number" /* NUMBER */:
|
|
1102
|
+
return Number(item);
|
|
1103
|
+
case "boolean" /* BOOLEAN */:
|
|
1104
|
+
return Boolean(item);
|
|
1105
|
+
default:
|
|
1106
|
+
return item;
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
/**
|
|
1110
|
+
* 获取指定索引位置的key
|
|
1111
|
+
*/
|
|
1112
|
+
key(index) {
|
|
1113
|
+
const storage = this.getStorage();
|
|
1114
|
+
return storage.key(index);
|
|
1115
|
+
}
|
|
1116
|
+
/**
|
|
1117
|
+
* 移除存储项,支持storageService.usePlugin
|
|
1118
|
+
*/
|
|
1119
|
+
removeItem(key, options = {}) {
|
|
1120
|
+
const storage = this.getStorage();
|
|
1121
|
+
const namespace = this.getNamespace();
|
|
1122
|
+
storage.removeItem(`${options.namespace || namespace}:${key}`);
|
|
1506
1123
|
}
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1124
|
+
/**
|
|
1125
|
+
* 设置存储项,支持storageService.usePlugin
|
|
1126
|
+
*/
|
|
1127
|
+
setItem(key, value, options = {}) {
|
|
1128
|
+
const storage = this.getStorage();
|
|
1129
|
+
const namespace = this.getNamespace();
|
|
1130
|
+
let item = value;
|
|
1131
|
+
const protocol = options.protocol ? `${options.protocol}:` : "";
|
|
1132
|
+
if (typeof value === "string" /* STRING */ || typeof value === "number" /* NUMBER */) {
|
|
1133
|
+
item = `${protocol}${value}`;
|
|
1134
|
+
} else {
|
|
1135
|
+
item = `${protocol}${serialize(value)}`;
|
|
1136
|
+
}
|
|
1137
|
+
storage.setItem(`${options.namespace || namespace}:${key}`, item);
|
|
1511
1138
|
}
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
console.debug("magic editor: ", ...args);
|
|
1139
|
+
destroy() {
|
|
1140
|
+
this.removeAllListeners();
|
|
1141
|
+
this.removeAllPlugins();
|
|
1516
1142
|
}
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
if (process.env.NODE_ENV === "development") {
|
|
1520
|
-
console.error("magic editor: ", ...args);
|
|
1143
|
+
usePlugin(options) {
|
|
1144
|
+
super.usePlugin(options);
|
|
1521
1145
|
}
|
|
1522
|
-
|
|
1146
|
+
getValueAndProtocol(value) {
|
|
1147
|
+
let protocol = "";
|
|
1148
|
+
if (value === null) {
|
|
1149
|
+
return {
|
|
1150
|
+
item: value,
|
|
1151
|
+
protocol
|
|
1152
|
+
};
|
|
1153
|
+
}
|
|
1154
|
+
const item = value.replace(new RegExp(`^(${Object.values(Protocol).join("|")})(:)(.+)`), (_$0, $1, _$2, $3) => {
|
|
1155
|
+
protocol = $1;
|
|
1156
|
+
return $3;
|
|
1157
|
+
});
|
|
1158
|
+
return {
|
|
1159
|
+
protocol,
|
|
1160
|
+
item
|
|
1161
|
+
};
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
const storageService = new WebStorage();
|
|
1523
1165
|
|
|
1524
1166
|
var ColumnLayout = /* @__PURE__ */ ((ColumnLayout2) => {
|
|
1525
1167
|
ColumnLayout2["LEFT"] = "left";
|
|
@@ -1588,6 +1230,8 @@ var DragType = /* @__PURE__ */ ((DragType2) => {
|
|
|
1588
1230
|
const UI_SELECT_MODE_EVENT_NAME = "ui-select";
|
|
1589
1231
|
|
|
1590
1232
|
const COPY_STORAGE_KEY = "$MagicEditorCopyData";
|
|
1233
|
+
const COPY_CODE_STORAGE_KEY = "$MagicEditorCopyCode";
|
|
1234
|
+
const COPY_DS_STORAGE_KEY = "$MagicEditorCopyDataSource";
|
|
1591
1235
|
const getPageList = (root) => {
|
|
1592
1236
|
if (!root)
|
|
1593
1237
|
return [];
|
|
@@ -1634,11 +1278,13 @@ const getMiddleTop = (node, parentNode, stage) => {
|
|
|
1634
1278
|
height = 0;
|
|
1635
1279
|
}
|
|
1636
1280
|
const { height: parentHeight } = parentNode.style;
|
|
1281
|
+
const { scrollTop = 0, wrapperHeight } = stage.mask;
|
|
1282
|
+
const wrapperHeightDeal = calcValueByFontsize(stage.renderer.getDocument(), wrapperHeight);
|
|
1283
|
+
const scrollTopDeal = calcValueByFontsize(stage.renderer.getDocument(), scrollTop);
|
|
1637
1284
|
if (isPage(parentNode)) {
|
|
1638
|
-
|
|
1639
|
-
return (wrapperHeight - height) / 2 + scrollTop;
|
|
1285
|
+
return (wrapperHeightDeal - height) / 2 + scrollTopDeal;
|
|
1640
1286
|
}
|
|
1641
|
-
return (parentHeight - height) / 2;
|
|
1287
|
+
return (Math.min(parentHeight, wrapperHeightDeal) - height) / 2;
|
|
1642
1288
|
};
|
|
1643
1289
|
const getInitPositionStyle = (style = {}, layout) => {
|
|
1644
1290
|
if (layout === Layout.ABSOLUTE) {
|
|
@@ -1739,8 +1385,12 @@ const fixNodeLeft = (config, parent, doc) => {
|
|
|
1739
1385
|
const el = doc.getElementById(`${config.id}`);
|
|
1740
1386
|
const parentEl = doc.getElementById(`${parent.id}`);
|
|
1741
1387
|
const left = Number(config.style?.left) || 0;
|
|
1742
|
-
if (el && parentEl
|
|
1743
|
-
|
|
1388
|
+
if (el && parentEl) {
|
|
1389
|
+
const calcParentOffsetWidth = calcValueByFontsize(doc, parentEl.offsetWidth);
|
|
1390
|
+
const calcElOffsetWidth = calcValueByFontsize(doc, el.offsetWidth);
|
|
1391
|
+
if (calcElOffsetWidth + left > calcParentOffsetWidth) {
|
|
1392
|
+
return calcParentOffsetWidth - calcElOffsetWidth;
|
|
1393
|
+
}
|
|
1744
1394
|
}
|
|
1745
1395
|
return config.style.left;
|
|
1746
1396
|
};
|
|
@@ -1768,1421 +1418,1855 @@ const traverseNode = (node, cb, parents = []) => {
|
|
|
1768
1418
|
}
|
|
1769
1419
|
};
|
|
1770
1420
|
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
return this.watcher.getTarget(id, type);
|
|
1782
|
-
}
|
|
1783
|
-
addTarget(target) {
|
|
1784
|
-
this.watcher.addTarget(target);
|
|
1785
|
-
this.emit("add-target", target);
|
|
1786
|
-
}
|
|
1787
|
-
removeTarget(id, type = DepTargetType.DEFAULT) {
|
|
1788
|
-
this.watcher.removeTarget(id, type);
|
|
1789
|
-
this.emit("remove-target");
|
|
1790
|
-
}
|
|
1791
|
-
clearTargets() {
|
|
1792
|
-
this.watcher.clearTargets();
|
|
1793
|
-
}
|
|
1794
|
-
collect(nodes, deep = false, type) {
|
|
1795
|
-
this.watcher.collect(nodes, deep, type);
|
|
1796
|
-
this.emit("collected", nodes, deep);
|
|
1797
|
-
}
|
|
1798
|
-
clear(nodes) {
|
|
1799
|
-
return this.watcher.clear(nodes);
|
|
1800
|
-
}
|
|
1801
|
-
clearByType(type, nodes) {
|
|
1802
|
-
return this.watcher.clearByType(type, nodes);
|
|
1803
|
-
}
|
|
1804
|
-
hasTarget(id, type = DepTargetType.DEFAULT) {
|
|
1805
|
-
return this.watcher.hasTarget(id, type);
|
|
1806
|
-
}
|
|
1807
|
-
hasSpecifiedTypeTarget(type = DepTargetType.DEFAULT) {
|
|
1808
|
-
return this.watcher.hasSpecifiedTypeTarget(type);
|
|
1809
|
-
}
|
|
1810
|
-
}
|
|
1811
|
-
const depService = new Dep();
|
|
1812
|
-
|
|
1813
|
-
const canUsePluginMethods$5 = {
|
|
1814
|
-
async: [
|
|
1815
|
-
"setPropsConfig",
|
|
1816
|
-
"getPropsConfig",
|
|
1817
|
-
"setPropsValue",
|
|
1818
|
-
"getPropsValue",
|
|
1819
|
-
"fillConfig",
|
|
1820
|
-
"getDefaultPropsValue"
|
|
1821
|
-
],
|
|
1822
|
-
sync: ["createId", "setNewItemId"]
|
|
1823
|
-
};
|
|
1824
|
-
class Props extends BaseService {
|
|
1825
|
-
state = reactive({
|
|
1826
|
-
propsConfigMap: {},
|
|
1827
|
-
propsValueMap: {},
|
|
1828
|
-
relateIdMap: {}
|
|
1829
|
-
});
|
|
1830
|
-
constructor() {
|
|
1831
|
-
super([
|
|
1832
|
-
...canUsePluginMethods$5.async.map((methodName) => ({ name: methodName, isAsync: true })),
|
|
1833
|
-
...canUsePluginMethods$5.sync.map((methodName) => ({ name: methodName, isAsync: false }))
|
|
1834
|
-
]);
|
|
1835
|
-
}
|
|
1836
|
-
setPropsConfigs(configs) {
|
|
1837
|
-
Object.keys(configs).forEach((type) => {
|
|
1838
|
-
this.setPropsConfig(toLine(type), configs[type]);
|
|
1839
|
-
});
|
|
1840
|
-
this.emit("props-configs-change");
|
|
1841
|
-
}
|
|
1842
|
-
async fillConfig(config, labelWidth) {
|
|
1843
|
-
return fillConfig(config, typeof labelWidth !== "function" ? labelWidth : "80px");
|
|
1844
|
-
}
|
|
1845
|
-
async setPropsConfig(type, config) {
|
|
1846
|
-
this.state.propsConfigMap[toLine(type)] = await this.fillConfig(Array.isArray(config) ? config : [config]);
|
|
1847
|
-
}
|
|
1848
|
-
/**
|
|
1849
|
-
* 获取指点类型的组件属性表单配置
|
|
1850
|
-
* @param type 组件类型
|
|
1851
|
-
* @returns 组件属性表单配置
|
|
1852
|
-
*/
|
|
1853
|
-
async getPropsConfig(type) {
|
|
1854
|
-
if (type === "area") {
|
|
1855
|
-
return await this.getPropsConfig("button");
|
|
1421
|
+
const beforePaste = (position, config) => {
|
|
1422
|
+
if (!config[0]?.style)
|
|
1423
|
+
return config;
|
|
1424
|
+
const curNode = editorService.get("node");
|
|
1425
|
+
const { left: referenceLeft, top: referenceTop } = config[0].style;
|
|
1426
|
+
const pasteConfigs = config.map((configItem) => {
|
|
1427
|
+
const { offsetX = 0, offsetY = 0, ...positionClone } = position;
|
|
1428
|
+
let pastePosition = positionClone;
|
|
1429
|
+
if (!isEmpty(pastePosition) && curNode?.items) {
|
|
1430
|
+
pastePosition = getPositionInContainer(pastePosition, curNode.id);
|
|
1856
1431
|
}
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
}
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
*/
|
|
1869
|
-
async setPropsValue(type, value) {
|
|
1870
|
-
this.state.propsValueMap[toLine(type)] = value;
|
|
1871
|
-
}
|
|
1872
|
-
/**
|
|
1873
|
-
* 获取指定类型的组件初始值
|
|
1874
|
-
* @param type 组件类型
|
|
1875
|
-
* @returns 组件初始值
|
|
1876
|
-
*/
|
|
1877
|
-
async getPropsValue(componentType, { inputEvent, ...defaultValue } = {}) {
|
|
1878
|
-
const type = toLine(componentType);
|
|
1879
|
-
if (type === "area") {
|
|
1880
|
-
const value = await this.getPropsValue("button");
|
|
1881
|
-
value.className = "action-area";
|
|
1882
|
-
value.text = "";
|
|
1883
|
-
if (value.style) {
|
|
1884
|
-
value.style.backgroundColor = "rgba(255, 255, 255, 0)";
|
|
1432
|
+
if (pastePosition.left && configItem.style?.left) {
|
|
1433
|
+
pastePosition.left = configItem.style.left - referenceLeft + pastePosition.left;
|
|
1434
|
+
}
|
|
1435
|
+
if (pastePosition.top && configItem.style?.top) {
|
|
1436
|
+
pastePosition.top = configItem.style?.top - referenceTop + pastePosition.top;
|
|
1437
|
+
}
|
|
1438
|
+
const pasteConfig = propsService.setNewItemId(configItem, false);
|
|
1439
|
+
if (pasteConfig.style) {
|
|
1440
|
+
const { left, top } = pasteConfig.style;
|
|
1441
|
+
if (typeof left === "number" || !!left && !isNaN(Number(left))) {
|
|
1442
|
+
pasteConfig.style.left = Number(left) + offsetX;
|
|
1885
1443
|
}
|
|
1886
|
-
|
|
1444
|
+
if (typeof top === "number" || !!top && !isNaN(Number(top))) {
|
|
1445
|
+
pasteConfig.style.top = Number(top) + offsetY;
|
|
1446
|
+
}
|
|
1447
|
+
pasteConfig.style = {
|
|
1448
|
+
...pasteConfig.style,
|
|
1449
|
+
...pastePosition
|
|
1450
|
+
};
|
|
1887
1451
|
}
|
|
1888
|
-
const
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1452
|
+
const root = editorService.get("root");
|
|
1453
|
+
if ((isPage(pasteConfig) || isPageFragment(pasteConfig)) && root) {
|
|
1454
|
+
pasteConfig.name = generatePageNameByApp(root, isPage(pasteConfig) ? NodeType.PAGE : NodeType.PAGE_FRAGMENT);
|
|
1455
|
+
}
|
|
1456
|
+
return pasteConfig;
|
|
1457
|
+
});
|
|
1458
|
+
return pasteConfigs;
|
|
1459
|
+
};
|
|
1460
|
+
const getPositionInContainer = (position = {}, id) => {
|
|
1461
|
+
let { left = 0, top = 0 } = position;
|
|
1462
|
+
const parentEl = editorService.get("stage")?.renderer?.contentWindow?.document.getElementById(`${id}`);
|
|
1463
|
+
const parentElRect = parentEl?.getBoundingClientRect();
|
|
1464
|
+
left = left - (parentElRect?.left || 0);
|
|
1465
|
+
top = top - (parentElRect?.top || 0);
|
|
1466
|
+
return {
|
|
1467
|
+
left,
|
|
1468
|
+
top
|
|
1469
|
+
};
|
|
1470
|
+
};
|
|
1471
|
+
const getAddParent = (node) => {
|
|
1472
|
+
const curNode = editorService.get("node");
|
|
1473
|
+
let parentNode;
|
|
1474
|
+
if (isPage(node)) {
|
|
1475
|
+
parentNode = editorService.get("root");
|
|
1476
|
+
} else if (curNode?.items) {
|
|
1477
|
+
parentNode = curNode;
|
|
1478
|
+
} else if (curNode?.id) {
|
|
1479
|
+
parentNode = editorService.getParentById(curNode.id, false);
|
|
1480
|
+
}
|
|
1481
|
+
return parentNode;
|
|
1482
|
+
};
|
|
1483
|
+
const getDefaultConfig = async (addNode, parentNode) => {
|
|
1484
|
+
const { type, inputEvent, ...config } = addNode;
|
|
1485
|
+
const layout = await editorService.getLayout(toRaw(parentNode), addNode);
|
|
1486
|
+
const newNode = { ...toRaw(await propsService.getPropsValue(type, config)) };
|
|
1487
|
+
newNode.style = getInitPositionStyle(newNode.style, layout);
|
|
1488
|
+
return newNode;
|
|
1489
|
+
};
|
|
1490
|
+
|
|
1491
|
+
const canUsePluginMethods$4 = {
|
|
1492
|
+
async: [
|
|
1493
|
+
"getLayout",
|
|
1494
|
+
"highlight",
|
|
1495
|
+
"select",
|
|
1496
|
+
"multiSelect",
|
|
1497
|
+
"doAdd",
|
|
1498
|
+
"add",
|
|
1499
|
+
"doRemove",
|
|
1500
|
+
"remove",
|
|
1501
|
+
"doUpdate",
|
|
1502
|
+
"update",
|
|
1503
|
+
"sort",
|
|
1504
|
+
"copy",
|
|
1505
|
+
"paste",
|
|
1506
|
+
"doPaste",
|
|
1507
|
+
"doAlignCenter",
|
|
1508
|
+
"alignCenter",
|
|
1509
|
+
"moveLayer",
|
|
1510
|
+
"moveToContainer",
|
|
1511
|
+
"dragTo",
|
|
1512
|
+
"undo",
|
|
1513
|
+
"redo",
|
|
1514
|
+
"move"
|
|
1515
|
+
],
|
|
1516
|
+
sync: []
|
|
1517
|
+
};
|
|
1518
|
+
class Editor extends BaseService {
|
|
1519
|
+
state = reactive({
|
|
1520
|
+
root: null,
|
|
1521
|
+
page: null,
|
|
1522
|
+
parent: null,
|
|
1523
|
+
node: null,
|
|
1524
|
+
nodes: [],
|
|
1525
|
+
stage: null,
|
|
1526
|
+
stageLoading: true,
|
|
1527
|
+
highlightNode: null,
|
|
1528
|
+
modifiedNodeIds: /* @__PURE__ */ new Map(),
|
|
1529
|
+
pageLength: 0,
|
|
1530
|
+
pageFragmentLength: 0,
|
|
1531
|
+
disabledMultiSelect: false
|
|
1532
|
+
});
|
|
1533
|
+
isHistoryStateChange = false;
|
|
1534
|
+
constructor() {
|
|
1535
|
+
super(
|
|
1536
|
+
canUsePluginMethods$4.async.map((methodName) => ({ name: methodName, isAsync: true })),
|
|
1537
|
+
// 需要注意循环依赖问题,如果函数间有相互调用的话,不能设置为串行调用
|
|
1538
|
+
["select", "update", "moveLayer"]
|
|
1895
1539
|
);
|
|
1896
|
-
return {
|
|
1897
|
-
id,
|
|
1898
|
-
...defaultPropsValue,
|
|
1899
|
-
...mergeWith({}, cloneDeep(this.state.propsValueMap[type] || {}), data)
|
|
1900
|
-
};
|
|
1901
|
-
}
|
|
1902
|
-
createId(type) {
|
|
1903
|
-
return `${type}_${guid()}`;
|
|
1904
1540
|
}
|
|
1905
1541
|
/**
|
|
1906
|
-
*
|
|
1907
|
-
*
|
|
1908
|
-
* @param
|
|
1909
|
-
* @param {Boolean} force 是否强制设置新的ID
|
|
1542
|
+
* 设置当前指点节点配置
|
|
1543
|
+
* @param name 'root' | 'page' | 'parent' | 'node' | 'highlightNode' | 'nodes' | 'stage' | 'modifiedNodeIds' | 'pageLength' | 'pageFragmentLength
|
|
1544
|
+
* @param value MNode
|
|
1910
1545
|
*/
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
this.
|
|
1916
|
-
config.id = newId;
|
|
1546
|
+
set(name, value) {
|
|
1547
|
+
const preValue = this.state[name];
|
|
1548
|
+
this.state[name] = value;
|
|
1549
|
+
if (name === "nodes" && Array.isArray(value)) {
|
|
1550
|
+
this.set("node", value[0]);
|
|
1917
1551
|
}
|
|
1918
|
-
if (
|
|
1919
|
-
|
|
1920
|
-
|
|
1552
|
+
if (name === "root") {
|
|
1553
|
+
if (Array.isArray(value)) {
|
|
1554
|
+
throw new Error("root 不能为数组");
|
|
1555
|
+
}
|
|
1556
|
+
if (value && isObject(value)) {
|
|
1557
|
+
const app = value;
|
|
1558
|
+
this.state.pageLength = getPageList(app).length || 0;
|
|
1559
|
+
this.state.pageFragmentLength = getPageFragmentList(app).length || 0;
|
|
1560
|
+
this.state.stageLoading = this.state.pageLength !== 0;
|
|
1561
|
+
} else {
|
|
1562
|
+
this.state.pageLength = 0;
|
|
1563
|
+
this.state.pageFragmentLength = 0;
|
|
1564
|
+
this.state.stageLoading = false;
|
|
1921
1565
|
}
|
|
1566
|
+
this.emit("root-change", value, preValue);
|
|
1922
1567
|
}
|
|
1923
|
-
return config;
|
|
1924
1568
|
}
|
|
1925
1569
|
/**
|
|
1926
|
-
*
|
|
1927
|
-
* @param
|
|
1928
|
-
* @returns
|
|
1570
|
+
* 获取当前指点节点配置
|
|
1571
|
+
* @param name 'root' | 'page' | 'parent' | 'node' | 'highlightNode' | 'nodes' | 'stage' | 'modifiedNodeIds' | 'pageLength' | 'pageFragmentLength'
|
|
1572
|
+
* @returns MNode
|
|
1929
1573
|
*/
|
|
1930
|
-
|
|
1931
|
-
return [
|
|
1932
|
-
type,
|
|
1933
|
-
layout: "absolute",
|
|
1934
|
-
style: {},
|
|
1935
|
-
name: type,
|
|
1936
|
-
items: []
|
|
1937
|
-
} : {
|
|
1938
|
-
type,
|
|
1939
|
-
style: {},
|
|
1940
|
-
name: type
|
|
1941
|
-
};
|
|
1942
|
-
}
|
|
1943
|
-
resetState() {
|
|
1944
|
-
this.state.propsConfigMap = {};
|
|
1945
|
-
this.state.propsValueMap = {};
|
|
1574
|
+
get(name) {
|
|
1575
|
+
return this.state[name];
|
|
1946
1576
|
}
|
|
1947
1577
|
/**
|
|
1948
|
-
*
|
|
1949
|
-
* @param
|
|
1950
|
-
* @param
|
|
1578
|
+
* 根据id获取组件、组件的父组件以及组件所属的页面节点
|
|
1579
|
+
* @param {number | string} id 组件id
|
|
1580
|
+
* @param {boolean} raw 是否使用toRaw
|
|
1581
|
+
* @returns {EditorNodeInfo}
|
|
1951
1582
|
*/
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
if (
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1583
|
+
getNodeInfo(id, raw = true) {
|
|
1584
|
+
let root = this.get("root");
|
|
1585
|
+
if (raw) {
|
|
1586
|
+
root = toRaw(root);
|
|
1587
|
+
}
|
|
1588
|
+
const info = {
|
|
1589
|
+
node: null,
|
|
1590
|
+
parent: null,
|
|
1591
|
+
page: null
|
|
1592
|
+
};
|
|
1593
|
+
if (!root)
|
|
1594
|
+
return info;
|
|
1595
|
+
if (id === root.id) {
|
|
1596
|
+
info.node = root;
|
|
1597
|
+
return info;
|
|
1598
|
+
}
|
|
1599
|
+
const path = getNodePath(id, root.items);
|
|
1600
|
+
if (!path.length)
|
|
1601
|
+
return info;
|
|
1602
|
+
path.unshift(root);
|
|
1603
|
+
info.node = path[path.length - 1];
|
|
1604
|
+
info.parent = path[path.length - 2];
|
|
1605
|
+
path.forEach((item) => {
|
|
1606
|
+
if (isPage(item) || isPageFragment(item)) {
|
|
1607
|
+
info.page = item;
|
|
1963
1608
|
return;
|
|
1964
|
-
|
|
1965
|
-
const relateOriginId = getValueByKeyPath(fullKey, config);
|
|
1966
|
-
const relateTargetId = relateIdMap[relateOriginId];
|
|
1967
|
-
if (!relateTargetId)
|
|
1968
|
-
return;
|
|
1969
|
-
setValueByKeyPath(fullKey, relateTargetId, targetConfig);
|
|
1970
|
-
});
|
|
1609
|
+
}
|
|
1971
1610
|
});
|
|
1611
|
+
return info;
|
|
1972
1612
|
}
|
|
1973
1613
|
/**
|
|
1974
|
-
*
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
}
|
|
1979
|
-
destroy() {
|
|
1980
|
-
this.resetState();
|
|
1981
|
-
this.removeAllListeners();
|
|
1982
|
-
this.removeAllPlugins();
|
|
1983
|
-
}
|
|
1984
|
-
usePlugin(options) {
|
|
1985
|
-
super.usePlugin(options);
|
|
1986
|
-
}
|
|
1987
|
-
/**
|
|
1988
|
-
* 获取setNewItemId前后映射关系
|
|
1989
|
-
* @param oldId 原组件ID
|
|
1990
|
-
* @returns 新旧ID映射
|
|
1614
|
+
* 根据ID获取指点节点配置
|
|
1615
|
+
* @param id 组件ID
|
|
1616
|
+
* @param {boolean} raw 是否使用toRaw
|
|
1617
|
+
* @returns 组件节点配置
|
|
1991
1618
|
*/
|
|
1992
|
-
|
|
1993
|
-
|
|
1619
|
+
getNodeById(id, raw = true) {
|
|
1620
|
+
const { node } = this.getNodeInfo(id, raw);
|
|
1621
|
+
return node;
|
|
1994
1622
|
}
|
|
1995
1623
|
/**
|
|
1996
|
-
*
|
|
1997
|
-
* @param
|
|
1998
|
-
* @param
|
|
1624
|
+
* 根据ID获取指点节点的父节点配置
|
|
1625
|
+
* @param id 组件ID
|
|
1626
|
+
* @param {boolean} raw 是否使用toRaw
|
|
1627
|
+
* @returns 指点组件的父节点配置
|
|
1999
1628
|
*/
|
|
2000
|
-
|
|
2001
|
-
this.
|
|
2002
|
-
|
|
2003
|
-
}
|
|
2004
|
-
const propsService = new Props();
|
|
2005
|
-
|
|
2006
|
-
class UndoRedo {
|
|
2007
|
-
elementList;
|
|
2008
|
-
listCursor;
|
|
2009
|
-
listMaxSize;
|
|
2010
|
-
constructor(listMaxSize = 20) {
|
|
2011
|
-
const minListMaxSize = 2;
|
|
2012
|
-
this.elementList = [];
|
|
2013
|
-
this.listCursor = 0;
|
|
2014
|
-
this.listMaxSize = listMaxSize > minListMaxSize ? listMaxSize : minListMaxSize;
|
|
2015
|
-
}
|
|
2016
|
-
pushElement(element) {
|
|
2017
|
-
this.elementList.splice(this.listCursor, this.elementList.length - this.listCursor, cloneDeep(element));
|
|
2018
|
-
this.listCursor += 1;
|
|
2019
|
-
if (this.elementList.length > this.listMaxSize) {
|
|
2020
|
-
this.elementList.shift();
|
|
2021
|
-
this.listCursor -= 1;
|
|
2022
|
-
}
|
|
2023
|
-
}
|
|
2024
|
-
canUndo() {
|
|
2025
|
-
return this.listCursor > 1;
|
|
2026
|
-
}
|
|
2027
|
-
// 返回undo后的当前元素
|
|
2028
|
-
undo() {
|
|
2029
|
-
if (!this.canUndo()) {
|
|
2030
|
-
return null;
|
|
2031
|
-
}
|
|
2032
|
-
this.listCursor -= 1;
|
|
2033
|
-
return this.getCurrentElement();
|
|
2034
|
-
}
|
|
2035
|
-
canRedo() {
|
|
2036
|
-
return this.elementList.length > this.listCursor;
|
|
2037
|
-
}
|
|
2038
|
-
// 返回redo后的当前元素
|
|
2039
|
-
redo() {
|
|
2040
|
-
if (!this.canRedo()) {
|
|
2041
|
-
return null;
|
|
2042
|
-
}
|
|
2043
|
-
this.listCursor += 1;
|
|
2044
|
-
return this.getCurrentElement();
|
|
2045
|
-
}
|
|
2046
|
-
getCurrentElement() {
|
|
2047
|
-
if (this.listCursor < 1) {
|
|
2048
|
-
return null;
|
|
2049
|
-
}
|
|
2050
|
-
return cloneDeep(this.elementList[this.listCursor - 1]);
|
|
2051
|
-
}
|
|
2052
|
-
}
|
|
2053
|
-
|
|
2054
|
-
class History extends BaseService {
|
|
2055
|
-
state = reactive({
|
|
2056
|
-
pageSteps: {},
|
|
2057
|
-
pageId: void 0,
|
|
2058
|
-
canRedo: false,
|
|
2059
|
-
canUndo: false
|
|
2060
|
-
});
|
|
2061
|
-
constructor() {
|
|
2062
|
-
super([]);
|
|
2063
|
-
this.on("change", this.setCanUndoRedo);
|
|
2064
|
-
}
|
|
2065
|
-
reset() {
|
|
2066
|
-
this.state.pageSteps = {};
|
|
2067
|
-
this.resetPage();
|
|
2068
|
-
}
|
|
2069
|
-
resetPage() {
|
|
2070
|
-
this.state.pageId = void 0;
|
|
2071
|
-
this.state.canRedo = false;
|
|
2072
|
-
this.state.canUndo = false;
|
|
1629
|
+
getParentById(id, raw = true) {
|
|
1630
|
+
const { parent } = this.getNodeInfo(id, raw);
|
|
1631
|
+
return parent;
|
|
2073
1632
|
}
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
if (
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
modifiedNodeIds: /* @__PURE__ */ new Map(),
|
|
2083
|
-
nodeId: page.id
|
|
2084
|
-
});
|
|
2085
|
-
this.state.pageSteps[this.state.pageId] = undoRedo;
|
|
1633
|
+
/**
|
|
1634
|
+
* 只有容器拥有布局
|
|
1635
|
+
*/
|
|
1636
|
+
async getLayout(parent, node) {
|
|
1637
|
+
if (node && typeof node !== "function" && isFixed(node))
|
|
1638
|
+
return Layout.FIXED;
|
|
1639
|
+
if (parent.layout) {
|
|
1640
|
+
return parent.layout;
|
|
2086
1641
|
}
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
this.state.pageId = void 0;
|
|
2092
|
-
this.state.pageSteps = {};
|
|
2093
|
-
this.state.canRedo = false;
|
|
2094
|
-
this.state.canUndo = false;
|
|
1642
|
+
if (!parent.style?.position) {
|
|
1643
|
+
return Layout.RELATIVE;
|
|
1644
|
+
}
|
|
1645
|
+
return Layout.ABSOLUTE;
|
|
2095
1646
|
}
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
1647
|
+
/**
|
|
1648
|
+
* 选中指定节点(将指定节点设置成当前选中状态)
|
|
1649
|
+
* @param config 指定节点配置或者ID
|
|
1650
|
+
* @returns 当前选中的节点配置
|
|
1651
|
+
*/
|
|
1652
|
+
async select(config) {
|
|
1653
|
+
const { node, page, parent } = this.selectedConfigExceptionHandler(config);
|
|
1654
|
+
this.set("nodes", node ? [node] : []);
|
|
1655
|
+
this.set("page", page);
|
|
1656
|
+
this.set("parent", parent);
|
|
1657
|
+
if (page) {
|
|
1658
|
+
historyService.changePage(toRaw(page));
|
|
1659
|
+
} else {
|
|
1660
|
+
historyService.resetState();
|
|
1661
|
+
}
|
|
1662
|
+
if (node?.id) {
|
|
1663
|
+
this.get("stage")?.renderer.runtime?.getApp?.()?.page?.emit(
|
|
1664
|
+
"editor:select",
|
|
1665
|
+
{
|
|
1666
|
+
node,
|
|
1667
|
+
page,
|
|
1668
|
+
parent
|
|
1669
|
+
},
|
|
1670
|
+
getNodePath(node.id, this.get("root")?.items)
|
|
1671
|
+
);
|
|
1672
|
+
}
|
|
1673
|
+
this.emit("select", node);
|
|
1674
|
+
return node;
|
|
2103
1675
|
}
|
|
2104
|
-
|
|
2105
|
-
const
|
|
2106
|
-
if (!
|
|
2107
|
-
return
|
|
2108
|
-
const
|
|
2109
|
-
|
|
2110
|
-
|
|
1676
|
+
async selectNextNode() {
|
|
1677
|
+
const node = toRaw(this.get("node"));
|
|
1678
|
+
if (!node || isPage(node) || node.type === NodeType.ROOT)
|
|
1679
|
+
return node;
|
|
1680
|
+
const parent = toRaw(this.getParentById(node.id));
|
|
1681
|
+
if (!parent)
|
|
1682
|
+
return node;
|
|
1683
|
+
const index = getNodeIndex(node.id, parent);
|
|
1684
|
+
const nextNode = parent.items[index + 1] || parent.items[0];
|
|
1685
|
+
await this.select(nextNode);
|
|
1686
|
+
this.get("stage")?.select(nextNode.id);
|
|
1687
|
+
return nextNode;
|
|
2111
1688
|
}
|
|
2112
|
-
|
|
2113
|
-
const
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
1689
|
+
async selectNextPage() {
|
|
1690
|
+
const root = toRaw(this.get("root"));
|
|
1691
|
+
const page = toRaw(this.get("page"));
|
|
1692
|
+
if (!page)
|
|
1693
|
+
throw new Error("page不能为空");
|
|
1694
|
+
if (!root)
|
|
1695
|
+
throw new Error("root不能为空");
|
|
1696
|
+
const index = getNodeIndex(page.id, root);
|
|
1697
|
+
const nextPage = root.items[index + 1] || root.items[0];
|
|
1698
|
+
await this.select(nextPage);
|
|
1699
|
+
this.get("stage")?.select(nextPage.id);
|
|
1700
|
+
return nextPage;
|
|
2119
1701
|
}
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
1702
|
+
/**
|
|
1703
|
+
* 高亮指定节点
|
|
1704
|
+
* @param config 指定节点配置或者ID
|
|
1705
|
+
* @returns 当前高亮的节点配置
|
|
1706
|
+
*/
|
|
1707
|
+
highlight(config) {
|
|
1708
|
+
const { node } = this.selectedConfigExceptionHandler(config);
|
|
1709
|
+
const currentHighlightNode = this.get("highlightNode");
|
|
1710
|
+
if (currentHighlightNode === node)
|
|
1711
|
+
return;
|
|
1712
|
+
this.set("highlightNode", node);
|
|
2124
1713
|
}
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
1714
|
+
/**
|
|
1715
|
+
* 多选
|
|
1716
|
+
* @param ids 指定节点ID
|
|
1717
|
+
* @returns 加入多选的节点配置
|
|
1718
|
+
*/
|
|
1719
|
+
multiSelect(ids) {
|
|
1720
|
+
const nodes = [];
|
|
1721
|
+
const idsUnique = uniq(ids);
|
|
1722
|
+
idsUnique.forEach((id) => {
|
|
1723
|
+
const { node } = this.getNodeInfo(id);
|
|
1724
|
+
if (!node)
|
|
1725
|
+
return;
|
|
1726
|
+
nodes.push(node);
|
|
1727
|
+
});
|
|
1728
|
+
this.set("nodes", nodes);
|
|
2129
1729
|
}
|
|
2130
|
-
|
|
2131
|
-
const
|
|
2132
|
-
|
|
2133
|
-
|
|
1730
|
+
selectRoot() {
|
|
1731
|
+
const root = this.get("root");
|
|
1732
|
+
if (!root)
|
|
1733
|
+
return;
|
|
1734
|
+
this.set("nodes", [root]);
|
|
1735
|
+
this.set("parent", null);
|
|
1736
|
+
this.set("page", null);
|
|
1737
|
+
this.set("stage", null);
|
|
1738
|
+
this.set("highlightNode", null);
|
|
2134
1739
|
}
|
|
2135
|
-
|
|
2136
|
-
const
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
}
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
}
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
1740
|
+
async doAdd(node, parent) {
|
|
1741
|
+
const root = this.get("root");
|
|
1742
|
+
if (!root)
|
|
1743
|
+
throw new Error("root为空");
|
|
1744
|
+
const curNode = this.get("node");
|
|
1745
|
+
const stage = this.get("stage");
|
|
1746
|
+
if (!curNode)
|
|
1747
|
+
throw new Error("当前选中节点为空");
|
|
1748
|
+
if ((parent.type === NodeType.ROOT || curNode?.type === NodeType.ROOT) && !(isPage(node) || isPageFragment(node))) {
|
|
1749
|
+
throw new Error("app下不能添加组件");
|
|
1750
|
+
}
|
|
1751
|
+
if (parent.id !== curNode.id && !(isPage(node) || isPageFragment(node))) {
|
|
1752
|
+
const index = parent.items.indexOf(curNode);
|
|
1753
|
+
parent.items?.splice(index + 1, 0, node);
|
|
1754
|
+
} else {
|
|
1755
|
+
parent.items?.push(node);
|
|
1756
|
+
}
|
|
1757
|
+
const layout = await this.getLayout(toRaw(parent), node);
|
|
1758
|
+
node.style = getInitPositionStyle(node.style, layout);
|
|
1759
|
+
await stage?.add({
|
|
1760
|
+
config: cloneDeep(node),
|
|
1761
|
+
parent: cloneDeep(parent),
|
|
1762
|
+
parentId: parent.id,
|
|
1763
|
+
root: cloneDeep(root)
|
|
1764
|
+
});
|
|
1765
|
+
const newStyle = fixNodePosition(node, parent, stage);
|
|
1766
|
+
if (newStyle && (newStyle.top !== node.style.top || newStyle.left !== node.style.left)) {
|
|
1767
|
+
node.style = newStyle;
|
|
1768
|
+
await stage?.update({ config: cloneDeep(node), parentId: parent.id, root: cloneDeep(root) });
|
|
1769
|
+
}
|
|
1770
|
+
this.addModifiedNodeId(node.id);
|
|
1771
|
+
return node;
|
|
2155
1772
|
}
|
|
2156
1773
|
/**
|
|
2157
|
-
*
|
|
2158
|
-
*
|
|
2159
|
-
*
|
|
2160
|
-
*
|
|
2161
|
-
* async afterGetStorage(): Promise<Storage> {
|
|
2162
|
-
* return window.sessionStorage;
|
|
2163
|
-
* },
|
|
2164
|
-
* });
|
|
1774
|
+
* 向指点容器添加组件节点
|
|
1775
|
+
* @param addConfig 将要添加的组件节点配置
|
|
1776
|
+
* @param parent 要添加到的容器组件节点配置,如果不设置,默认为当前选中的组件的父节点
|
|
1777
|
+
* @returns 添加后的节点
|
|
2165
1778
|
*/
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
1779
|
+
async add(addNode, parent) {
|
|
1780
|
+
const stage = this.get("stage");
|
|
1781
|
+
const addNodes = [];
|
|
1782
|
+
if (!Array.isArray(addNode)) {
|
|
1783
|
+
const { type, inputEvent, ...config } = addNode;
|
|
1784
|
+
if (!type)
|
|
1785
|
+
throw new Error("组件类型不能为空");
|
|
1786
|
+
addNodes.push({ ...toRaw(await propsService.getPropsValue(type, config)) });
|
|
1787
|
+
} else {
|
|
1788
|
+
addNodes.push(...addNode);
|
|
1789
|
+
}
|
|
1790
|
+
const newNodes = await Promise.all(
|
|
1791
|
+
addNodes.map((node) => {
|
|
1792
|
+
const root = this.get("root");
|
|
1793
|
+
if ((isPage(node) || isPageFragment(node)) && root) {
|
|
1794
|
+
return this.doAdd(node, root);
|
|
1795
|
+
}
|
|
1796
|
+
const parentNode = parent && typeof parent !== "function" ? parent : getAddParent(node);
|
|
1797
|
+
if (!parentNode)
|
|
1798
|
+
throw new Error("未找到父元素");
|
|
1799
|
+
return this.doAdd(node, parentNode);
|
|
1800
|
+
})
|
|
1801
|
+
);
|
|
1802
|
+
if (newNodes.length > 1) {
|
|
1803
|
+
const newNodeIds = newNodes.map((node) => node.id);
|
|
1804
|
+
stage?.multiSelect(newNodeIds);
|
|
1805
|
+
await this.multiSelect(newNodeIds);
|
|
1806
|
+
} else {
|
|
1807
|
+
await this.select(newNodes[0]);
|
|
1808
|
+
if (isPage(newNodes[0])) {
|
|
1809
|
+
this.state.pageLength += 1;
|
|
1810
|
+
} else if (isPageFragment(newNodes[0])) {
|
|
1811
|
+
this.state.pageFragmentLength += 1;
|
|
1812
|
+
} else {
|
|
1813
|
+
stage?.select(newNodes[0].id);
|
|
1814
|
+
}
|
|
1815
|
+
}
|
|
1816
|
+
if (!(isPage(newNodes[0]) || isPageFragment(newNodes[0]))) {
|
|
1817
|
+
this.pushHistoryState();
|
|
1818
|
+
}
|
|
1819
|
+
this.emit("add", newNodes);
|
|
1820
|
+
return Array.isArray(addNode) ? newNodes : newNodes[0];
|
|
2171
1821
|
}
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
const
|
|
2177
|
-
|
|
1822
|
+
async doRemove(node) {
|
|
1823
|
+
const root = this.get("root");
|
|
1824
|
+
if (!root)
|
|
1825
|
+
throw new Error("root不能为空");
|
|
1826
|
+
const { parent, node: curNode } = this.getNodeInfo(node.id, false);
|
|
1827
|
+
if (!parent || !curNode)
|
|
1828
|
+
throw new Error("找不要删除的节点");
|
|
1829
|
+
const index = getNodeIndex(curNode.id, parent);
|
|
1830
|
+
if (typeof index !== "number" || index === -1)
|
|
1831
|
+
throw new Error("找不要删除的节点");
|
|
1832
|
+
parent.items?.splice(index, 1);
|
|
1833
|
+
const stage = this.get("stage");
|
|
1834
|
+
stage?.remove({ id: node.id, parentId: parent.id, root: cloneDeep(root) });
|
|
1835
|
+
const selectDefault = async (pages) => {
|
|
1836
|
+
if (pages[0]) {
|
|
1837
|
+
await this.select(pages[0]);
|
|
1838
|
+
stage?.select(pages[0].id);
|
|
1839
|
+
} else {
|
|
1840
|
+
this.selectRoot();
|
|
1841
|
+
historyService.resetPage();
|
|
1842
|
+
}
|
|
1843
|
+
};
|
|
1844
|
+
const rootItems = root.items || [];
|
|
1845
|
+
if (isPage(node)) {
|
|
1846
|
+
this.state.pageLength -= 1;
|
|
1847
|
+
await selectDefault(getPageList(root));
|
|
1848
|
+
} else if (isPageFragment(node)) {
|
|
1849
|
+
this.state.pageFragmentLength -= 1;
|
|
1850
|
+
await selectDefault(getPageFragmentList(root));
|
|
1851
|
+
} else {
|
|
1852
|
+
await this.select(parent);
|
|
1853
|
+
stage?.select(parent.id);
|
|
1854
|
+
this.addModifiedNodeId(parent.id);
|
|
1855
|
+
}
|
|
1856
|
+
if (!rootItems.length) {
|
|
1857
|
+
this.resetModifiedNodeId();
|
|
1858
|
+
historyService.reset();
|
|
1859
|
+
}
|
|
2178
1860
|
}
|
|
2179
1861
|
/**
|
|
2180
|
-
*
|
|
1862
|
+
* 删除组件
|
|
1863
|
+
* @param {Object} node
|
|
2181
1864
|
*/
|
|
2182
|
-
|
|
2183
|
-
const
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
);
|
|
2188
|
-
if (item === null)
|
|
2189
|
-
return null;
|
|
2190
|
-
switch (protocol) {
|
|
2191
|
-
case "object" /* OBJECT */:
|
|
2192
|
-
return getConfig("parseDSL")(`(${item})`);
|
|
2193
|
-
case "json" /* JSON */:
|
|
2194
|
-
return JSON.parse(item);
|
|
2195
|
-
case "number" /* NUMBER */:
|
|
2196
|
-
return Number(item);
|
|
2197
|
-
case "boolean" /* BOOLEAN */:
|
|
2198
|
-
return Boolean(item);
|
|
2199
|
-
default:
|
|
2200
|
-
return item;
|
|
1865
|
+
async remove(nodeOrNodeList) {
|
|
1866
|
+
const nodes = Array.isArray(nodeOrNodeList) ? nodeOrNodeList : [nodeOrNodeList];
|
|
1867
|
+
await Promise.all(nodes.map((node) => this.doRemove(node)));
|
|
1868
|
+
if (!(isPage(nodes[0]) || isPageFragment(nodes[0]))) {
|
|
1869
|
+
this.pushHistoryState();
|
|
2201
1870
|
}
|
|
1871
|
+
this.emit("remove", nodes);
|
|
2202
1872
|
}
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
1873
|
+
async doUpdate(config) {
|
|
1874
|
+
const root = this.get("root");
|
|
1875
|
+
if (!root)
|
|
1876
|
+
throw new Error("root为空");
|
|
1877
|
+
if (!config?.id)
|
|
1878
|
+
throw new Error("没有配置或者配置缺少id值");
|
|
1879
|
+
const info = this.getNodeInfo(config.id, false);
|
|
1880
|
+
if (!info.node)
|
|
1881
|
+
throw new Error(`获取不到id为${config.id}的节点`);
|
|
1882
|
+
const node = cloneDeep(toRaw(info.node));
|
|
1883
|
+
let newConfig = await this.toggleFixedPosition(toRaw(config), node, root);
|
|
1884
|
+
newConfig = mergeWith(cloneDeep(node), newConfig, (objValue, srcValue, key) => {
|
|
1885
|
+
if (typeof srcValue === "undefined" && Object.hasOwn(newConfig, key)) {
|
|
1886
|
+
return "";
|
|
1887
|
+
}
|
|
1888
|
+
if (isObject(srcValue) && Array.isArray(objValue)) {
|
|
1889
|
+
return srcValue;
|
|
1890
|
+
}
|
|
1891
|
+
if (Array.isArray(srcValue)) {
|
|
1892
|
+
return srcValue;
|
|
1893
|
+
}
|
|
1894
|
+
});
|
|
1895
|
+
if (!newConfig.type)
|
|
1896
|
+
throw new Error("配置缺少type值");
|
|
1897
|
+
if (newConfig.type === NodeType.ROOT) {
|
|
1898
|
+
this.set("root", newConfig);
|
|
1899
|
+
return newConfig;
|
|
1900
|
+
}
|
|
1901
|
+
const { parent } = info;
|
|
1902
|
+
if (!parent)
|
|
1903
|
+
throw new Error("获取不到父级节点");
|
|
1904
|
+
const parentNodeItems = parent.items;
|
|
1905
|
+
const index = getNodeIndex(newConfig.id, parent);
|
|
1906
|
+
if (!parentNodeItems || typeof index === "undefined" || index === -1)
|
|
1907
|
+
throw new Error("更新的节点未找到");
|
|
1908
|
+
const newLayout = await this.getLayout(newConfig);
|
|
1909
|
+
const layout = await this.getLayout(node);
|
|
1910
|
+
if (Array.isArray(newConfig.items) && newLayout !== layout) {
|
|
1911
|
+
newConfig = setChildrenLayout(newConfig, newLayout);
|
|
1912
|
+
}
|
|
1913
|
+
parentNodeItems[index] = newConfig;
|
|
1914
|
+
const nodes = this.get("nodes");
|
|
1915
|
+
const targetIndex = nodes.findIndex((nodeItem) => `${nodeItem.id}` === `${newConfig.id}`);
|
|
1916
|
+
nodes.splice(targetIndex, 1, newConfig);
|
|
1917
|
+
this.set("nodes", [...nodes]);
|
|
1918
|
+
this.get("stage")?.update({
|
|
1919
|
+
config: cloneDeep(newConfig),
|
|
1920
|
+
parentId: parent.id,
|
|
1921
|
+
root: cloneDeep(root)
|
|
1922
|
+
});
|
|
1923
|
+
if (isPage(newConfig) || isPageFragment(newConfig)) {
|
|
1924
|
+
this.set("page", newConfig);
|
|
1925
|
+
}
|
|
1926
|
+
this.addModifiedNodeId(newConfig.id);
|
|
1927
|
+
return newConfig;
|
|
2209
1928
|
}
|
|
2210
1929
|
/**
|
|
2211
|
-
*
|
|
1930
|
+
* 更新节点
|
|
1931
|
+
* @param config 新的节点配置,配置中需要有id信息
|
|
1932
|
+
* @returns 更新后的节点配置
|
|
2212
1933
|
*/
|
|
2213
|
-
|
|
2214
|
-
const
|
|
2215
|
-
const
|
|
2216
|
-
|
|
1934
|
+
async update(config) {
|
|
1935
|
+
const nodes = Array.isArray(config) ? config : [config];
|
|
1936
|
+
const newNodes = await Promise.all(nodes.map((node) => this.doUpdate(node)));
|
|
1937
|
+
if (newNodes[0]?.type !== NodeType.ROOT) {
|
|
1938
|
+
this.pushHistoryState();
|
|
1939
|
+
}
|
|
1940
|
+
this.emit("update", newNodes);
|
|
1941
|
+
return Array.isArray(config) ? newNodes : newNodes[0];
|
|
2217
1942
|
}
|
|
2218
1943
|
/**
|
|
2219
|
-
*
|
|
1944
|
+
* 将id为id1的组件移动到id为id2的组件位置上,例如:[1,2,3,4] -> sort(1,3) -> [2,1,3,4]
|
|
1945
|
+
* @param id1 组件ID
|
|
1946
|
+
* @param id2 组件ID
|
|
1947
|
+
* @returns void
|
|
2220
1948
|
*/
|
|
2221
|
-
|
|
2222
|
-
const
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
const
|
|
2226
|
-
if (
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
protocol
|
|
2246
|
-
};
|
|
2247
|
-
}
|
|
2248
|
-
const item = value.replace(new RegExp(`^(${Object.values(Protocol).join("|")})(:)(.+)`), (_$0, $1, _$2, $3) => {
|
|
2249
|
-
protocol = $1;
|
|
2250
|
-
return $3;
|
|
2251
|
-
});
|
|
2252
|
-
return {
|
|
2253
|
-
protocol,
|
|
2254
|
-
item
|
|
2255
|
-
};
|
|
2256
|
-
}
|
|
2257
|
-
}
|
|
2258
|
-
const storageService = new WebStorage();
|
|
2259
|
-
|
|
2260
|
-
const canUsePluginMethods$3 = {
|
|
2261
|
-
async: [
|
|
2262
|
-
"getLayout",
|
|
2263
|
-
"highlight",
|
|
2264
|
-
"select",
|
|
2265
|
-
"multiSelect",
|
|
2266
|
-
"doAdd",
|
|
2267
|
-
"add",
|
|
2268
|
-
"doRemove",
|
|
2269
|
-
"remove",
|
|
2270
|
-
"doUpdate",
|
|
2271
|
-
"update",
|
|
2272
|
-
"sort",
|
|
2273
|
-
"copy",
|
|
2274
|
-
"paste",
|
|
2275
|
-
"doPaste",
|
|
2276
|
-
"doAlignCenter",
|
|
2277
|
-
"alignCenter",
|
|
2278
|
-
"moveLayer",
|
|
2279
|
-
"moveToContainer",
|
|
2280
|
-
"dragTo",
|
|
2281
|
-
"undo",
|
|
2282
|
-
"redo",
|
|
2283
|
-
"move"
|
|
2284
|
-
],
|
|
2285
|
-
sync: []
|
|
2286
|
-
};
|
|
2287
|
-
class Editor extends BaseService {
|
|
2288
|
-
state = reactive({
|
|
2289
|
-
root: null,
|
|
2290
|
-
page: null,
|
|
2291
|
-
parent: null,
|
|
2292
|
-
node: null,
|
|
2293
|
-
nodes: [],
|
|
2294
|
-
stage: null,
|
|
2295
|
-
stageLoading: true,
|
|
2296
|
-
highlightNode: null,
|
|
2297
|
-
modifiedNodeIds: /* @__PURE__ */ new Map(),
|
|
2298
|
-
pageLength: 0,
|
|
2299
|
-
pageFragmentLength: 0,
|
|
2300
|
-
disabledMultiSelect: false
|
|
2301
|
-
});
|
|
2302
|
-
isHistoryStateChange = false;
|
|
2303
|
-
constructor() {
|
|
2304
|
-
super(
|
|
2305
|
-
canUsePluginMethods$3.async.map((methodName) => ({ name: methodName, isAsync: true })),
|
|
2306
|
-
// 需要注意循环依赖问题,如果函数间有相互调用的话,不能设置为串行调用
|
|
2307
|
-
["select", "update", "moveLayer"]
|
|
2308
|
-
);
|
|
1949
|
+
async sort(id1, id2) {
|
|
1950
|
+
const root = this.get("root");
|
|
1951
|
+
if (!root)
|
|
1952
|
+
throw new Error("root为空");
|
|
1953
|
+
const node = this.get("node");
|
|
1954
|
+
if (!node)
|
|
1955
|
+
throw new Error("当前节点为空");
|
|
1956
|
+
const parent = cloneDeep(toRaw(this.get("parent")));
|
|
1957
|
+
if (!parent)
|
|
1958
|
+
throw new Error("父节点为空");
|
|
1959
|
+
const index2 = parent.items.findIndex((node2) => `${node2.id}` === `${id2}`);
|
|
1960
|
+
if (index2 < 0)
|
|
1961
|
+
return;
|
|
1962
|
+
const index1 = parent.items.findIndex((node2) => `${node2.id}` === `${id1}`);
|
|
1963
|
+
parent.items.splice(index2, 0, ...parent.items.splice(index1, 1));
|
|
1964
|
+
await this.update(parent);
|
|
1965
|
+
await this.select(node);
|
|
1966
|
+
this.get("stage")?.update({
|
|
1967
|
+
config: cloneDeep(node),
|
|
1968
|
+
parentId: parent.id,
|
|
1969
|
+
root: cloneDeep(root)
|
|
1970
|
+
});
|
|
1971
|
+
this.addModifiedNodeId(parent.id);
|
|
1972
|
+
this.pushHistoryState();
|
|
2309
1973
|
}
|
|
2310
1974
|
/**
|
|
2311
|
-
*
|
|
2312
|
-
* @param
|
|
2313
|
-
* @
|
|
1975
|
+
* 将组件节点配置存储到localStorage中
|
|
1976
|
+
* @param config 组件节点配置
|
|
1977
|
+
* @returns
|
|
2314
1978
|
*/
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
this.set("node", value[0]);
|
|
2320
|
-
}
|
|
2321
|
-
if (name === "root") {
|
|
2322
|
-
if (Array.isArray(value)) {
|
|
2323
|
-
throw new Error("root 不能为数组");
|
|
2324
|
-
}
|
|
2325
|
-
if (value && isObject(value)) {
|
|
2326
|
-
const app = value;
|
|
2327
|
-
this.state.pageLength = getPageList(app).length || 0;
|
|
2328
|
-
this.state.pageFragmentLength = getPageFragmentList(app).length || 0;
|
|
2329
|
-
this.state.stageLoading = this.state.pageLength !== 0;
|
|
2330
|
-
} else {
|
|
2331
|
-
this.state.pageLength = 0;
|
|
2332
|
-
this.state.pageFragmentLength = 0;
|
|
2333
|
-
this.state.stageLoading = false;
|
|
2334
|
-
}
|
|
2335
|
-
this.emit("root-change", value, preValue);
|
|
2336
|
-
}
|
|
1979
|
+
copy(config) {
|
|
1980
|
+
storageService.setItem(COPY_STORAGE_KEY, Array.isArray(config) ? config : [config], {
|
|
1981
|
+
protocol: Protocol.OBJECT
|
|
1982
|
+
});
|
|
2337
1983
|
}
|
|
2338
1984
|
/**
|
|
2339
|
-
*
|
|
2340
|
-
* @param
|
|
2341
|
-
* @returns
|
|
1985
|
+
* 复制时会带上组件关联的依赖
|
|
1986
|
+
* @param config 组件节点配置
|
|
1987
|
+
* @returns
|
|
2342
1988
|
*/
|
|
2343
|
-
|
|
2344
|
-
|
|
1989
|
+
copyWithRelated(config) {
|
|
1990
|
+
const copyNodes = Array.isArray(config) ? config : [config];
|
|
1991
|
+
depService.clearByType(DepTargetType.RELATED_COMP_WHEN_COPY);
|
|
1992
|
+
depService.collect(copyNodes, true, DepTargetType.RELATED_COMP_WHEN_COPY);
|
|
1993
|
+
const customTarget = depService.getTarget(
|
|
1994
|
+
DepTargetType.RELATED_COMP_WHEN_COPY,
|
|
1995
|
+
DepTargetType.RELATED_COMP_WHEN_COPY
|
|
1996
|
+
);
|
|
1997
|
+
if (customTarget) {
|
|
1998
|
+
Object.keys(customTarget.deps).forEach((nodeId) => {
|
|
1999
|
+
const node = this.getNodeById(nodeId);
|
|
2000
|
+
if (!node)
|
|
2001
|
+
return;
|
|
2002
|
+
customTarget.deps[nodeId].keys.forEach((key) => {
|
|
2003
|
+
const relateNodeId = get(node, key);
|
|
2004
|
+
const isExist = copyNodes.find((node2) => node2.id === relateNodeId);
|
|
2005
|
+
if (!isExist) {
|
|
2006
|
+
const relateNode = this.getNodeById(relateNodeId);
|
|
2007
|
+
if (relateNode) {
|
|
2008
|
+
copyNodes.push(relateNode);
|
|
2009
|
+
}
|
|
2010
|
+
}
|
|
2011
|
+
});
|
|
2012
|
+
});
|
|
2013
|
+
}
|
|
2014
|
+
storageService.setItem(COPY_STORAGE_KEY, copyNodes, {
|
|
2015
|
+
protocol: Protocol.OBJECT
|
|
2016
|
+
});
|
|
2345
2017
|
}
|
|
2346
2018
|
/**
|
|
2347
|
-
*
|
|
2348
|
-
* @param
|
|
2349
|
-
* @
|
|
2350
|
-
* @returns {EditorNodeInfo}
|
|
2019
|
+
* 从localStorage中获取节点,然后添加到当前容器中
|
|
2020
|
+
* @param position 粘贴的坐标
|
|
2021
|
+
* @returns 添加后的组件节点配置
|
|
2351
2022
|
*/
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
if (
|
|
2355
|
-
|
|
2023
|
+
async paste(position = {}) {
|
|
2024
|
+
const config = storageService.getItem(COPY_STORAGE_KEY);
|
|
2025
|
+
if (!Array.isArray(config))
|
|
2026
|
+
return;
|
|
2027
|
+
const node = this.get("node");
|
|
2028
|
+
let parent = null;
|
|
2029
|
+
if (config.length === 1 && config[0].id === node?.id) {
|
|
2030
|
+
parent = this.get("parent");
|
|
2031
|
+
if (parent?.type === NodeType.ROOT) {
|
|
2032
|
+
parent = this.get("page");
|
|
2033
|
+
}
|
|
2356
2034
|
}
|
|
2357
|
-
const
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2035
|
+
const pasteConfigs = await this.doPaste(config, position);
|
|
2036
|
+
propsService.replaceRelateId(config, pasteConfigs);
|
|
2037
|
+
return this.add(pasteConfigs, parent);
|
|
2038
|
+
}
|
|
2039
|
+
async doPaste(config, position = {}) {
|
|
2040
|
+
propsService.clearRelateId();
|
|
2041
|
+
const pasteConfigs = beforePaste(position, cloneDeep(config));
|
|
2042
|
+
return pasteConfigs;
|
|
2043
|
+
}
|
|
2044
|
+
async doAlignCenter(config) {
|
|
2045
|
+
const parent = this.getParentById(config.id);
|
|
2046
|
+
if (!parent)
|
|
2047
|
+
throw new Error("找不到父节点");
|
|
2048
|
+
const node = cloneDeep(toRaw(config));
|
|
2049
|
+
const layout = await this.getLayout(parent, node);
|
|
2050
|
+
if (layout === Layout.RELATIVE) {
|
|
2051
|
+
return config;
|
|
2367
2052
|
}
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
if (
|
|
2376
|
-
|
|
2377
|
-
|
|
2053
|
+
if (!node.style)
|
|
2054
|
+
return config;
|
|
2055
|
+
const stage = this.get("stage");
|
|
2056
|
+
const doc = stage?.renderer.contentWindow?.document;
|
|
2057
|
+
if (doc) {
|
|
2058
|
+
const el = doc.getElementById(`${node.id}`);
|
|
2059
|
+
const parentEl = layout === Layout.FIXED ? doc.body : el?.offsetParent;
|
|
2060
|
+
if (parentEl && el) {
|
|
2061
|
+
node.style.left = calcValueByFontsize(doc, (parentEl.clientWidth - el.clientWidth) / 2);
|
|
2062
|
+
node.style.right = "";
|
|
2378
2063
|
}
|
|
2379
|
-
})
|
|
2380
|
-
|
|
2064
|
+
} else if (parent.style && isNumber(parent.style?.width) && isNumber(node.style?.width)) {
|
|
2065
|
+
node.style.left = (parent.style.width - node.style.width) / 2;
|
|
2066
|
+
node.style.right = "";
|
|
2067
|
+
}
|
|
2068
|
+
return node;
|
|
2381
2069
|
}
|
|
2382
2070
|
/**
|
|
2383
|
-
*
|
|
2384
|
-
* @param
|
|
2385
|
-
* @
|
|
2386
|
-
* @returns 组件节点配置
|
|
2071
|
+
* 将指点节点设置居中
|
|
2072
|
+
* @param config 组件节点配置
|
|
2073
|
+
* @returns 当前组件节点配置
|
|
2387
2074
|
*/
|
|
2388
|
-
|
|
2389
|
-
const
|
|
2390
|
-
|
|
2075
|
+
async alignCenter(config) {
|
|
2076
|
+
const nodes = Array.isArray(config) ? config : [config];
|
|
2077
|
+
const stage = this.get("stage");
|
|
2078
|
+
const newNodes = await Promise.all(nodes.map((node) => this.doAlignCenter(node)));
|
|
2079
|
+
const newNode = await this.update(newNodes);
|
|
2080
|
+
if (newNodes.length > 1) {
|
|
2081
|
+
await stage?.multiSelect(newNodes.map((node) => node.id));
|
|
2082
|
+
} else {
|
|
2083
|
+
await stage?.select(newNodes[0].id);
|
|
2084
|
+
}
|
|
2085
|
+
return newNode;
|
|
2391
2086
|
}
|
|
2392
2087
|
/**
|
|
2393
|
-
*
|
|
2394
|
-
* @param
|
|
2395
|
-
* @param {boolean} raw 是否使用toRaw
|
|
2396
|
-
* @returns 指点组件的父节点配置
|
|
2088
|
+
* 移动当前选中节点位置
|
|
2089
|
+
* @param offset 偏移量
|
|
2397
2090
|
*/
|
|
2398
|
-
|
|
2399
|
-
const
|
|
2400
|
-
|
|
2091
|
+
async moveLayer(offset) {
|
|
2092
|
+
const root = this.get("root");
|
|
2093
|
+
if (!root)
|
|
2094
|
+
throw new Error("root为空");
|
|
2095
|
+
const parent = this.get("parent");
|
|
2096
|
+
if (!parent)
|
|
2097
|
+
throw new Error("父节点为空");
|
|
2098
|
+
const node = this.get("node");
|
|
2099
|
+
if (!node)
|
|
2100
|
+
throw new Error("当前节点为空");
|
|
2101
|
+
const brothers = parent.items || [];
|
|
2102
|
+
const index = brothers.findIndex((item) => `${item.id}` === `${node?.id}`);
|
|
2103
|
+
const layout = await this.getLayout(parent, node);
|
|
2104
|
+
const isRelative = layout === Layout.RELATIVE;
|
|
2105
|
+
let offsetIndex;
|
|
2106
|
+
if (offset === LayerOffset.TOP) {
|
|
2107
|
+
offsetIndex = isRelative ? 0 : brothers.length;
|
|
2108
|
+
} else if (offset === LayerOffset.BOTTOM) {
|
|
2109
|
+
offsetIndex = isRelative ? brothers.length : 0;
|
|
2110
|
+
} else {
|
|
2111
|
+
offsetIndex = index + (isRelative ? -offset : offset);
|
|
2112
|
+
}
|
|
2113
|
+
if (offsetIndex > 0 && offsetIndex > brothers.length || offsetIndex < 0) {
|
|
2114
|
+
return;
|
|
2115
|
+
}
|
|
2116
|
+
brothers.splice(index, 1);
|
|
2117
|
+
brothers.splice(offsetIndex, 0, node);
|
|
2118
|
+
const grandparent = this.getParentById(parent.id);
|
|
2119
|
+
this.get("stage")?.update({
|
|
2120
|
+
config: cloneDeep(toRaw(parent)),
|
|
2121
|
+
parentId: grandparent?.id,
|
|
2122
|
+
root: cloneDeep(root)
|
|
2123
|
+
});
|
|
2124
|
+
this.addModifiedNodeId(parent.id);
|
|
2125
|
+
this.pushHistoryState();
|
|
2126
|
+
this.emit("move-layer", offset);
|
|
2401
2127
|
}
|
|
2402
2128
|
/**
|
|
2403
|
-
*
|
|
2129
|
+
* 移动到指定容器中
|
|
2130
|
+
* @param config 需要移动的节点
|
|
2131
|
+
* @param targetId 容器ID
|
|
2404
2132
|
*/
|
|
2405
|
-
async
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2133
|
+
async moveToContainer(config, targetId) {
|
|
2134
|
+
const root = this.get("root");
|
|
2135
|
+
const { node, parent } = this.getNodeInfo(config.id, false);
|
|
2136
|
+
const target = this.getNodeById(targetId, false);
|
|
2137
|
+
const stage = this.get("stage");
|
|
2138
|
+
if (root && node && parent && stage) {
|
|
2139
|
+
const index = getNodeIndex(node.id, parent);
|
|
2140
|
+
parent.items?.splice(index, 1);
|
|
2141
|
+
await stage.remove({ id: node.id, parentId: parent.id, root: cloneDeep(root) });
|
|
2142
|
+
const layout = await this.getLayout(target);
|
|
2143
|
+
const newConfig = mergeWith(cloneDeep(node), config, (objValue, srcValue) => {
|
|
2144
|
+
if (Array.isArray(srcValue)) {
|
|
2145
|
+
return srcValue;
|
|
2146
|
+
}
|
|
2147
|
+
});
|
|
2148
|
+
newConfig.style = getInitPositionStyle(newConfig.style, layout);
|
|
2149
|
+
target.items.push(newConfig);
|
|
2150
|
+
await stage.select(targetId);
|
|
2151
|
+
const targetParent = this.getParentById(target.id);
|
|
2152
|
+
await stage.update({ config: cloneDeep(target), parentId: targetParent?.id, root: cloneDeep(root) });
|
|
2153
|
+
await this.select(newConfig);
|
|
2154
|
+
stage.select(newConfig.id);
|
|
2155
|
+
this.addModifiedNodeId(target.id);
|
|
2156
|
+
this.addModifiedNodeId(parent.id);
|
|
2157
|
+
this.pushHistoryState();
|
|
2158
|
+
return newConfig;
|
|
2413
2159
|
}
|
|
2414
|
-
return Layout.ABSOLUTE;
|
|
2415
2160
|
}
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
const
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2161
|
+
async dragTo(config, targetParent, targetIndex) {
|
|
2162
|
+
if (!targetParent || !Array.isArray(targetParent.items))
|
|
2163
|
+
return;
|
|
2164
|
+
const { parent, node: curNode } = this.getNodeInfo(config.id, false);
|
|
2165
|
+
if (!parent || !curNode)
|
|
2166
|
+
throw new Error("找不要删除的节点");
|
|
2167
|
+
const index = getNodeIndex(curNode.id, parent);
|
|
2168
|
+
if (typeof index !== "number" || index === -1)
|
|
2169
|
+
throw new Error("找不要删除的节点");
|
|
2170
|
+
if (parent.id === targetParent.id) {
|
|
2171
|
+
if (index === targetIndex)
|
|
2172
|
+
return;
|
|
2173
|
+
if (index < targetIndex) {
|
|
2174
|
+
targetIndex -= 1;
|
|
2175
|
+
}
|
|
2430
2176
|
}
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
node,
|
|
2436
|
-
page,
|
|
2437
|
-
parent
|
|
2438
|
-
},
|
|
2439
|
-
getNodePath(node.id, this.get("root")?.items)
|
|
2440
|
-
);
|
|
2177
|
+
const layout = await this.getLayout(parent);
|
|
2178
|
+
const newLayout = await this.getLayout(targetParent);
|
|
2179
|
+
if (newLayout !== layout) {
|
|
2180
|
+
setLayout(config, newLayout);
|
|
2441
2181
|
}
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
const
|
|
2447
|
-
if (
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
this.
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
async selectNextPage() {
|
|
2459
|
-
const root = toRaw(this.get("root"));
|
|
2460
|
-
const page = toRaw(this.get("page"));
|
|
2461
|
-
if (!page)
|
|
2462
|
-
throw new Error("page不能为空");
|
|
2463
|
-
if (!root)
|
|
2464
|
-
throw new Error("root不能为空");
|
|
2465
|
-
const index = getNodeIndex(page.id, root);
|
|
2466
|
-
const nextPage = root.items[index + 1] || root.items[0];
|
|
2467
|
-
await this.select(nextPage);
|
|
2468
|
-
this.get("stage")?.select(nextPage.id);
|
|
2469
|
-
return nextPage;
|
|
2182
|
+
parent.items?.splice(index, 1);
|
|
2183
|
+
targetParent.items?.splice(targetIndex, 0, config);
|
|
2184
|
+
const page = this.get("page");
|
|
2185
|
+
const root = this.get("root");
|
|
2186
|
+
const stage = this.get("stage");
|
|
2187
|
+
if (stage && page && root) {
|
|
2188
|
+
stage.update({
|
|
2189
|
+
config: cloneDeep(page),
|
|
2190
|
+
parentId: root.id,
|
|
2191
|
+
root: cloneDeep(root)
|
|
2192
|
+
});
|
|
2193
|
+
}
|
|
2194
|
+
this.addModifiedNodeId(config.id);
|
|
2195
|
+
this.addModifiedNodeId(parent.id);
|
|
2196
|
+
this.pushHistoryState();
|
|
2197
|
+
this.emit("drag-to", { index, targetIndex, config, parent, targetParent });
|
|
2470
2198
|
}
|
|
2471
2199
|
/**
|
|
2472
|
-
*
|
|
2473
|
-
* @
|
|
2474
|
-
* @returns 当前高亮的节点配置
|
|
2200
|
+
* 撤销当前操作
|
|
2201
|
+
* @returns 上一次数据
|
|
2475
2202
|
*/
|
|
2476
|
-
|
|
2477
|
-
const
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
return;
|
|
2481
|
-
this.set("highlightNode", node);
|
|
2203
|
+
async undo() {
|
|
2204
|
+
const value = historyService.undo();
|
|
2205
|
+
await this.changeHistoryState(value);
|
|
2206
|
+
return value;
|
|
2482
2207
|
}
|
|
2483
2208
|
/**
|
|
2484
|
-
*
|
|
2485
|
-
* @
|
|
2486
|
-
* @returns 加入多选的节点配置
|
|
2209
|
+
* 恢复到下一步
|
|
2210
|
+
* @returns 下一步数据
|
|
2487
2211
|
*/
|
|
2488
|
-
|
|
2489
|
-
const
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
const { node } = this.getNodeInfo(id);
|
|
2493
|
-
if (!node)
|
|
2494
|
-
return;
|
|
2495
|
-
nodes.push(node);
|
|
2496
|
-
});
|
|
2497
|
-
this.set("nodes", nodes);
|
|
2212
|
+
async redo() {
|
|
2213
|
+
const value = historyService.redo();
|
|
2214
|
+
await this.changeHistoryState(value);
|
|
2215
|
+
return value;
|
|
2498
2216
|
}
|
|
2499
|
-
|
|
2500
|
-
const
|
|
2501
|
-
if (!
|
|
2217
|
+
async move(left, top) {
|
|
2218
|
+
const node = toRaw(this.get("node"));
|
|
2219
|
+
if (!node || isPage(node))
|
|
2502
2220
|
return;
|
|
2503
|
-
|
|
2504
|
-
|
|
2221
|
+
const { style, id, type } = node;
|
|
2222
|
+
if (!style || !["absolute", "fixed"].includes(style.position))
|
|
2223
|
+
return;
|
|
2224
|
+
const update = (style2) => this.update({
|
|
2225
|
+
id,
|
|
2226
|
+
type,
|
|
2227
|
+
style: style2
|
|
2228
|
+
});
|
|
2229
|
+
if (top) {
|
|
2230
|
+
if (isNumber(style.top)) {
|
|
2231
|
+
update({
|
|
2232
|
+
...style,
|
|
2233
|
+
top: Number(style.top) + Number(top),
|
|
2234
|
+
bottom: ""
|
|
2235
|
+
});
|
|
2236
|
+
} else if (isNumber(style.bottom)) {
|
|
2237
|
+
update({
|
|
2238
|
+
...style,
|
|
2239
|
+
bottom: Number(style.bottom) - Number(top),
|
|
2240
|
+
top: ""
|
|
2241
|
+
});
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
if (left) {
|
|
2245
|
+
if (isNumber(style.left)) {
|
|
2246
|
+
update({
|
|
2247
|
+
...style,
|
|
2248
|
+
left: Number(style.left) + Number(left),
|
|
2249
|
+
right: ""
|
|
2250
|
+
});
|
|
2251
|
+
} else if (isNumber(style.right)) {
|
|
2252
|
+
update({
|
|
2253
|
+
...style,
|
|
2254
|
+
right: Number(style.right) - Number(left),
|
|
2255
|
+
left: ""
|
|
2256
|
+
});
|
|
2257
|
+
}
|
|
2258
|
+
}
|
|
2259
|
+
}
|
|
2260
|
+
resetState() {
|
|
2261
|
+
this.set("root", null);
|
|
2262
|
+
this.set("node", null);
|
|
2263
|
+
this.set("nodes", []);
|
|
2505
2264
|
this.set("page", null);
|
|
2265
|
+
this.set("parent", null);
|
|
2506
2266
|
this.set("stage", null);
|
|
2507
2267
|
this.set("highlightNode", null);
|
|
2268
|
+
this.set("modifiedNodeIds", /* @__PURE__ */ new Map());
|
|
2269
|
+
this.set("pageLength", 0);
|
|
2508
2270
|
}
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2271
|
+
destroy() {
|
|
2272
|
+
this.removeAllListeners();
|
|
2273
|
+
this.resetState();
|
|
2274
|
+
this.removeAllPlugins();
|
|
2275
|
+
}
|
|
2276
|
+
resetModifiedNodeId() {
|
|
2277
|
+
this.get("modifiedNodeIds").clear();
|
|
2278
|
+
}
|
|
2279
|
+
usePlugin(options) {
|
|
2280
|
+
super.usePlugin(options);
|
|
2281
|
+
}
|
|
2282
|
+
addModifiedNodeId(id) {
|
|
2283
|
+
if (!this.isHistoryStateChange) {
|
|
2284
|
+
this.get("modifiedNodeIds").set(id, id);
|
|
2519
2285
|
}
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2286
|
+
}
|
|
2287
|
+
pushHistoryState() {
|
|
2288
|
+
const curNode = cloneDeep(toRaw(this.get("node")));
|
|
2289
|
+
const page = this.get("page");
|
|
2290
|
+
if (!this.isHistoryStateChange && curNode && page) {
|
|
2291
|
+
historyService.push({
|
|
2292
|
+
data: cloneDeep(toRaw(page)),
|
|
2293
|
+
modifiedNodeIds: this.get("modifiedNodeIds"),
|
|
2294
|
+
nodeId: curNode.id
|
|
2295
|
+
});
|
|
2525
2296
|
}
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
await
|
|
2297
|
+
this.isHistoryStateChange = false;
|
|
2298
|
+
}
|
|
2299
|
+
async changeHistoryState(value) {
|
|
2300
|
+
if (!value)
|
|
2301
|
+
return;
|
|
2302
|
+
this.isHistoryStateChange = true;
|
|
2303
|
+
await this.update(value.data);
|
|
2304
|
+
this.set("modifiedNodeIds", value.modifiedNodeIds);
|
|
2305
|
+
setTimeout(async () => {
|
|
2306
|
+
if (!value.nodeId)
|
|
2307
|
+
return;
|
|
2308
|
+
await this.select(value.nodeId);
|
|
2309
|
+
this.get("stage")?.select(value.nodeId);
|
|
2310
|
+
}, 0);
|
|
2311
|
+
this.emit("history-change", value.data);
|
|
2312
|
+
}
|
|
2313
|
+
async toggleFixedPosition(dist, src, root) {
|
|
2314
|
+
const newConfig = cloneDeep(dist);
|
|
2315
|
+
if (!isPop(src) && newConfig.style?.position) {
|
|
2316
|
+
if (isFixed(newConfig) && !isFixed(src)) {
|
|
2317
|
+
newConfig.style = change2Fixed(newConfig, root);
|
|
2318
|
+
} else if (!isFixed(newConfig) && isFixed(src)) {
|
|
2319
|
+
newConfig.style = await Fixed2Other(newConfig, root, this.getLayout);
|
|
2320
|
+
}
|
|
2538
2321
|
}
|
|
2539
|
-
|
|
2540
|
-
return node;
|
|
2322
|
+
return newConfig;
|
|
2541
2323
|
}
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
* @returns 添加后的节点
|
|
2547
|
-
*/
|
|
2548
|
-
async add(addNode, parent) {
|
|
2549
|
-
const stage = this.get("stage");
|
|
2550
|
-
const addNodes = [];
|
|
2551
|
-
if (!Array.isArray(addNode)) {
|
|
2552
|
-
const { type, inputEvent, ...config } = addNode;
|
|
2553
|
-
if (!type)
|
|
2554
|
-
throw new Error("组件类型不能为空");
|
|
2555
|
-
addNodes.push({ ...toRaw(await propsService.getPropsValue(type, config)) });
|
|
2324
|
+
selectedConfigExceptionHandler(config) {
|
|
2325
|
+
let id;
|
|
2326
|
+
if (typeof config === "string" || typeof config === "number") {
|
|
2327
|
+
id = config;
|
|
2556
2328
|
} else {
|
|
2557
|
-
|
|
2329
|
+
id = config.id;
|
|
2558
2330
|
}
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
const root = this.get("root");
|
|
2562
|
-
if ((isPage(node) || isPageFragment(node)) && root) {
|
|
2563
|
-
return this.doAdd(node, root);
|
|
2564
|
-
}
|
|
2565
|
-
const parentNode = parent && typeof parent !== "function" ? parent : getAddParent(node);
|
|
2566
|
-
if (!parentNode)
|
|
2567
|
-
throw new Error("未找到父元素");
|
|
2568
|
-
return this.doAdd(node, parentNode);
|
|
2569
|
-
})
|
|
2570
|
-
);
|
|
2571
|
-
if (newNodes.length > 1) {
|
|
2572
|
-
const newNodeIds = newNodes.map((node) => node.id);
|
|
2573
|
-
stage?.multiSelect(newNodeIds);
|
|
2574
|
-
await this.multiSelect(newNodeIds);
|
|
2575
|
-
} else {
|
|
2576
|
-
await this.select(newNodes[0]);
|
|
2577
|
-
if (isPage(newNodes[0])) {
|
|
2578
|
-
this.state.pageLength += 1;
|
|
2579
|
-
} else if (isPageFragment(newNodes[0])) {
|
|
2580
|
-
this.state.pageFragmentLength += 1;
|
|
2581
|
-
} else {
|
|
2582
|
-
stage?.select(newNodes[0].id);
|
|
2583
|
-
}
|
|
2331
|
+
if (!id) {
|
|
2332
|
+
throw new Error("没有ID,无法选中");
|
|
2584
2333
|
}
|
|
2585
|
-
|
|
2586
|
-
|
|
2334
|
+
const { node, parent, page } = this.getNodeInfo(id);
|
|
2335
|
+
if (!node)
|
|
2336
|
+
throw new Error("获取不到组件信息");
|
|
2337
|
+
if (node.id === this.state.root?.id) {
|
|
2338
|
+
throw new Error("不能选根节点");
|
|
2587
2339
|
}
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
const root = this.get("root");
|
|
2593
|
-
if (!root)
|
|
2594
|
-
throw new Error("root不能为空");
|
|
2595
|
-
const { parent, node: curNode } = this.getNodeInfo(node.id, false);
|
|
2596
|
-
if (!parent || !curNode)
|
|
2597
|
-
throw new Error("找不要删除的节点");
|
|
2598
|
-
const index = getNodeIndex(curNode.id, parent);
|
|
2599
|
-
if (typeof index !== "number" || index === -1)
|
|
2600
|
-
throw new Error("找不要删除的节点");
|
|
2601
|
-
parent.items?.splice(index, 1);
|
|
2602
|
-
const stage = this.get("stage");
|
|
2603
|
-
stage?.remove({ id: node.id, parentId: parent.id, root: cloneDeep(root) });
|
|
2604
|
-
const selectDefault = async (pages) => {
|
|
2605
|
-
if (pages[0]) {
|
|
2606
|
-
await this.select(pages[0]);
|
|
2607
|
-
stage?.select(pages[0].id);
|
|
2608
|
-
} else {
|
|
2609
|
-
this.selectRoot();
|
|
2610
|
-
historyService.resetPage();
|
|
2611
|
-
}
|
|
2340
|
+
return {
|
|
2341
|
+
node,
|
|
2342
|
+
parent,
|
|
2343
|
+
page
|
|
2612
2344
|
};
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2345
|
+
}
|
|
2346
|
+
}
|
|
2347
|
+
const editorService = new Editor();
|
|
2348
|
+
|
|
2349
|
+
function BaseFormConfig() {
|
|
2350
|
+
return [
|
|
2351
|
+
{
|
|
2352
|
+
name: "id",
|
|
2353
|
+
type: "hidden"
|
|
2354
|
+
},
|
|
2355
|
+
{
|
|
2356
|
+
name: "type",
|
|
2357
|
+
text: "类型",
|
|
2358
|
+
type: "hidden",
|
|
2359
|
+
defaultValue: "base"
|
|
2360
|
+
},
|
|
2361
|
+
{
|
|
2362
|
+
name: "title",
|
|
2363
|
+
text: "名称",
|
|
2364
|
+
rules: [
|
|
2365
|
+
{
|
|
2366
|
+
required: true,
|
|
2367
|
+
message: "请输入名称"
|
|
2368
|
+
}
|
|
2369
|
+
]
|
|
2370
|
+
},
|
|
2371
|
+
{
|
|
2372
|
+
name: "description",
|
|
2373
|
+
text: "描述"
|
|
2628
2374
|
}
|
|
2375
|
+
];
|
|
2376
|
+
}
|
|
2377
|
+
|
|
2378
|
+
const HttpFormConfig = [
|
|
2379
|
+
{
|
|
2380
|
+
name: "autoFetch",
|
|
2381
|
+
text: "自动请求",
|
|
2382
|
+
type: "switch",
|
|
2383
|
+
defaultValue: true
|
|
2384
|
+
},
|
|
2385
|
+
{
|
|
2386
|
+
name: "responseOptions",
|
|
2387
|
+
items: [
|
|
2388
|
+
{
|
|
2389
|
+
name: "dataPath",
|
|
2390
|
+
text: "数据路径"
|
|
2391
|
+
}
|
|
2392
|
+
]
|
|
2393
|
+
},
|
|
2394
|
+
{
|
|
2395
|
+
type: "fieldset",
|
|
2396
|
+
name: "options",
|
|
2397
|
+
legend: "HTTP 配置",
|
|
2398
|
+
items: [
|
|
2399
|
+
{
|
|
2400
|
+
name: "url",
|
|
2401
|
+
text: "URL"
|
|
2402
|
+
},
|
|
2403
|
+
{
|
|
2404
|
+
name: "method",
|
|
2405
|
+
text: "Method",
|
|
2406
|
+
type: "select",
|
|
2407
|
+
options: [
|
|
2408
|
+
{ text: "GET", value: "GET" },
|
|
2409
|
+
{ text: "POST", value: "POST" },
|
|
2410
|
+
{ text: "PUT", value: "PUT" },
|
|
2411
|
+
{ text: "DELETE", value: "DELETE" }
|
|
2412
|
+
]
|
|
2413
|
+
},
|
|
2414
|
+
{
|
|
2415
|
+
name: "params",
|
|
2416
|
+
type: "key-value",
|
|
2417
|
+
defaultValue: {},
|
|
2418
|
+
text: "参数"
|
|
2419
|
+
},
|
|
2420
|
+
{
|
|
2421
|
+
name: "data",
|
|
2422
|
+
type: "key-value",
|
|
2423
|
+
defaultValue: {},
|
|
2424
|
+
advanced: true,
|
|
2425
|
+
text: "请求体"
|
|
2426
|
+
},
|
|
2427
|
+
{
|
|
2428
|
+
name: "headers",
|
|
2429
|
+
type: "key-value",
|
|
2430
|
+
defaultValue: {},
|
|
2431
|
+
text: "请求头"
|
|
2432
|
+
}
|
|
2433
|
+
]
|
|
2434
|
+
}
|
|
2435
|
+
];
|
|
2436
|
+
|
|
2437
|
+
const fillConfig$1 = (config) => [
|
|
2438
|
+
...BaseFormConfig(),
|
|
2439
|
+
...config,
|
|
2440
|
+
{
|
|
2441
|
+
type: "tab",
|
|
2442
|
+
items: [
|
|
2443
|
+
{
|
|
2444
|
+
title: "数据定义",
|
|
2445
|
+
items: [
|
|
2446
|
+
{
|
|
2447
|
+
name: "fields",
|
|
2448
|
+
type: "data-source-fields",
|
|
2449
|
+
defaultValue: () => []
|
|
2450
|
+
}
|
|
2451
|
+
]
|
|
2452
|
+
},
|
|
2453
|
+
{
|
|
2454
|
+
title: "方法定义",
|
|
2455
|
+
items: [
|
|
2456
|
+
{
|
|
2457
|
+
name: "methods",
|
|
2458
|
+
type: "data-source-methods",
|
|
2459
|
+
defaultValue: () => []
|
|
2460
|
+
}
|
|
2461
|
+
]
|
|
2462
|
+
},
|
|
2463
|
+
{
|
|
2464
|
+
title: "事件配置",
|
|
2465
|
+
items: [
|
|
2466
|
+
{
|
|
2467
|
+
name: "events",
|
|
2468
|
+
src: "datasource",
|
|
2469
|
+
type: "event-select"
|
|
2470
|
+
}
|
|
2471
|
+
]
|
|
2472
|
+
},
|
|
2473
|
+
{
|
|
2474
|
+
title: "mock数据",
|
|
2475
|
+
items: [
|
|
2476
|
+
{
|
|
2477
|
+
name: "mocks",
|
|
2478
|
+
type: "data-source-mocks",
|
|
2479
|
+
defaultValue: () => []
|
|
2480
|
+
}
|
|
2481
|
+
]
|
|
2482
|
+
},
|
|
2483
|
+
{
|
|
2484
|
+
title: "请求参数裁剪",
|
|
2485
|
+
display: (formState, { model }) => model.type === "http",
|
|
2486
|
+
items: [
|
|
2487
|
+
{
|
|
2488
|
+
name: "beforeRequest",
|
|
2489
|
+
type: "vs-code",
|
|
2490
|
+
parse: true,
|
|
2491
|
+
height: "600px"
|
|
2492
|
+
}
|
|
2493
|
+
]
|
|
2494
|
+
},
|
|
2495
|
+
{
|
|
2496
|
+
title: "响应数据裁剪",
|
|
2497
|
+
display: (formState, { model }) => model.type === "http",
|
|
2498
|
+
items: [
|
|
2499
|
+
{
|
|
2500
|
+
name: "afterResponse",
|
|
2501
|
+
type: "vs-code",
|
|
2502
|
+
parse: true,
|
|
2503
|
+
height: "600px"
|
|
2504
|
+
}
|
|
2505
|
+
]
|
|
2506
|
+
}
|
|
2507
|
+
]
|
|
2508
|
+
}
|
|
2509
|
+
];
|
|
2510
|
+
const getFormConfig = (type, configs) => {
|
|
2511
|
+
switch (type) {
|
|
2512
|
+
case "base":
|
|
2513
|
+
return fillConfig$1([]);
|
|
2514
|
+
case "http":
|
|
2515
|
+
return fillConfig$1(HttpFormConfig);
|
|
2516
|
+
default:
|
|
2517
|
+
return fillConfig$1(configs[type] || []);
|
|
2518
|
+
}
|
|
2519
|
+
};
|
|
2520
|
+
const getFormValue = (type, values) => {
|
|
2521
|
+
if (type !== "http") {
|
|
2522
|
+
return values;
|
|
2629
2523
|
}
|
|
2524
|
+
return {
|
|
2525
|
+
beforeRequest: `(options, context) => {
|
|
2630
2526
|
/**
|
|
2631
|
-
*
|
|
2632
|
-
*
|
|
2527
|
+
* 用户可以直接编写函数,在原始接口调用之前,会运行该函数,将这个函数的返回值作为该数据源接口的入参
|
|
2528
|
+
*
|
|
2529
|
+
* options: HttpOptions
|
|
2530
|
+
*
|
|
2531
|
+
* interface HttpOptions {
|
|
2532
|
+
* // 请求链接
|
|
2533
|
+
* url: string;
|
|
2534
|
+
* // query参数
|
|
2535
|
+
* params?: Record<string, string>;
|
|
2536
|
+
* // body数据
|
|
2537
|
+
* data?: Record<string, any>;
|
|
2538
|
+
* // 请求头
|
|
2539
|
+
* headers?: Record<string, string>;
|
|
2540
|
+
* // 请求方法 GET/POST
|
|
2541
|
+
* method?: Method;
|
|
2542
|
+
* }
|
|
2543
|
+
*
|
|
2544
|
+
* context:上下文对象
|
|
2545
|
+
*
|
|
2546
|
+
* interface Content {
|
|
2547
|
+
* app: AppCore;
|
|
2548
|
+
* dataSource: HttpDataSource;
|
|
2549
|
+
* }
|
|
2550
|
+
*
|
|
2551
|
+
* return: HttpOptions
|
|
2633
2552
|
*/
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2553
|
+
|
|
2554
|
+
// 此处的返回值会作为这个接口的入参
|
|
2555
|
+
return options;
|
|
2556
|
+
}`,
|
|
2557
|
+
afterResponse: `(response, context) => {
|
|
2558
|
+
/**
|
|
2559
|
+
* 用户可以直接编写函数,在原始接口返回之后,会运行该函数,将这个函数的返回值作为该数据源接口的返回
|
|
2560
|
+
|
|
2561
|
+
* context:上下文对象
|
|
2562
|
+
*
|
|
2563
|
+
* interface Content {
|
|
2564
|
+
* app: AppCore;
|
|
2565
|
+
* dataSource: HttpDataSource;
|
|
2566
|
+
* }
|
|
2567
|
+
*
|
|
2568
|
+
*/
|
|
2569
|
+
|
|
2570
|
+
// 此处的返回值会作为这个接口的返回值
|
|
2571
|
+
return response;
|
|
2572
|
+
}`,
|
|
2573
|
+
...values
|
|
2574
|
+
};
|
|
2575
|
+
};
|
|
2576
|
+
const getDisplayField = (dataSources, key) => {
|
|
2577
|
+
const displayState = [];
|
|
2578
|
+
const matches = key.matchAll(/\$\{([\s\S]+?)\}/g);
|
|
2579
|
+
let index = 0;
|
|
2580
|
+
for (const match of matches) {
|
|
2581
|
+
if (typeof match.index === "undefined")
|
|
2582
|
+
break;
|
|
2583
|
+
displayState.push({
|
|
2584
|
+
type: "text",
|
|
2585
|
+
value: key.substring(index, match.index)
|
|
2586
|
+
});
|
|
2587
|
+
let dsText = "";
|
|
2588
|
+
let ds;
|
|
2589
|
+
let fields;
|
|
2590
|
+
match[1].split(".").forEach((item, index2) => {
|
|
2591
|
+
if (index2 === 0) {
|
|
2592
|
+
ds = dataSources.find((ds2) => ds2.id === item);
|
|
2593
|
+
dsText += ds?.title || item;
|
|
2594
|
+
fields = ds?.fields;
|
|
2595
|
+
return;
|
|
2662
2596
|
}
|
|
2597
|
+
const field = fields?.find((field2) => field2.name === item);
|
|
2598
|
+
fields = field?.fields;
|
|
2599
|
+
dsText += `.${field?.title || item}`;
|
|
2663
2600
|
});
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2601
|
+
displayState.push({
|
|
2602
|
+
type: "var",
|
|
2603
|
+
value: dsText
|
|
2604
|
+
});
|
|
2605
|
+
index = match.index + match[0].length;
|
|
2606
|
+
}
|
|
2607
|
+
if (index < key.length) {
|
|
2608
|
+
displayState.push({
|
|
2609
|
+
type: "text",
|
|
2610
|
+
value: key.substring(index)
|
|
2611
|
+
});
|
|
2612
|
+
}
|
|
2613
|
+
return displayState;
|
|
2614
|
+
};
|
|
2615
|
+
const getCascaderOptionsFromFields = (fields = [], dataSourceFieldType = ["any"]) => {
|
|
2616
|
+
const child = [];
|
|
2617
|
+
fields.forEach((field) => {
|
|
2618
|
+
if (!dataSourceFieldType.length) {
|
|
2619
|
+
dataSourceFieldType.push("any");
|
|
2620
|
+
}
|
|
2621
|
+
const children = getCascaderOptionsFromFields(field.fields, dataSourceFieldType);
|
|
2622
|
+
const item = {
|
|
2623
|
+
label: field.title || field.name,
|
|
2624
|
+
value: field.name,
|
|
2625
|
+
children
|
|
2626
|
+
};
|
|
2627
|
+
const fieldType = field.type || "any";
|
|
2628
|
+
if (dataSourceFieldType.includes("any") || dataSourceFieldType.includes(fieldType)) {
|
|
2629
|
+
child.push(item);
|
|
2630
|
+
return;
|
|
2669
2631
|
}
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
throw new Error("获取不到父级节点");
|
|
2673
|
-
const parentNodeItems = parent.items;
|
|
2674
|
-
const index = getNodeIndex(newConfig.id, parent);
|
|
2675
|
-
if (!parentNodeItems || typeof index === "undefined" || index === -1)
|
|
2676
|
-
throw new Error("更新的节点未找到");
|
|
2677
|
-
const newLayout = await this.getLayout(newConfig);
|
|
2678
|
-
const layout = await this.getLayout(node);
|
|
2679
|
-
if (Array.isArray(newConfig.items) && newLayout !== layout) {
|
|
2680
|
-
newConfig = setChildrenLayout(newConfig, newLayout);
|
|
2632
|
+
if (!dataSourceFieldType.includes(fieldType) && !["array", "object", "any"].includes(fieldType)) {
|
|
2633
|
+
return;
|
|
2681
2634
|
}
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
const targetIndex = nodes.findIndex((nodeItem) => `${nodeItem.id}` === `${newConfig.id}`);
|
|
2685
|
-
nodes.splice(targetIndex, 1, newConfig);
|
|
2686
|
-
this.set("nodes", [...nodes]);
|
|
2687
|
-
this.get("stage")?.update({
|
|
2688
|
-
config: cloneDeep(newConfig),
|
|
2689
|
-
parentId: parent.id,
|
|
2690
|
-
root: cloneDeep(root)
|
|
2691
|
-
});
|
|
2692
|
-
if (isPage(newConfig) || isPageFragment(newConfig)) {
|
|
2693
|
-
this.set("page", newConfig);
|
|
2635
|
+
if (!children.length && ["object", "array", "any"].includes(field.type || "")) {
|
|
2636
|
+
return;
|
|
2694
2637
|
}
|
|
2695
|
-
|
|
2638
|
+
child.push(item);
|
|
2639
|
+
});
|
|
2640
|
+
return child;
|
|
2641
|
+
};
|
|
2642
|
+
|
|
2643
|
+
const canUsePluginMethods$3 = {
|
|
2644
|
+
async: [],
|
|
2645
|
+
sync: [
|
|
2646
|
+
"getFormConfig",
|
|
2647
|
+
"setFormConfig",
|
|
2648
|
+
"getFormValue",
|
|
2649
|
+
"setFormValue",
|
|
2650
|
+
"getFormEvent",
|
|
2651
|
+
"setFormEvent",
|
|
2652
|
+
"getFormMethod",
|
|
2653
|
+
"setFormMethod",
|
|
2654
|
+
"add",
|
|
2655
|
+
"update",
|
|
2656
|
+
"remove",
|
|
2657
|
+
"createId"
|
|
2658
|
+
]
|
|
2659
|
+
};
|
|
2660
|
+
class DataSource extends BaseService {
|
|
2661
|
+
state = reactive({
|
|
2662
|
+
datasourceTypeList: [],
|
|
2663
|
+
dataSources: [],
|
|
2664
|
+
editable: true,
|
|
2665
|
+
configs: {},
|
|
2666
|
+
values: {},
|
|
2667
|
+
events: {},
|
|
2668
|
+
methods: {}
|
|
2669
|
+
});
|
|
2670
|
+
constructor() {
|
|
2671
|
+
super(canUsePluginMethods$3.sync.map((methodName) => ({ name: methodName, isAsync: false })));
|
|
2672
|
+
}
|
|
2673
|
+
set(name, value) {
|
|
2674
|
+
this.state[name] = value;
|
|
2675
|
+
}
|
|
2676
|
+
get(name) {
|
|
2677
|
+
return this.state[name];
|
|
2678
|
+
}
|
|
2679
|
+
getFormConfig(type = "base") {
|
|
2680
|
+
return getFormConfig(toLine(type), this.get("configs"));
|
|
2681
|
+
}
|
|
2682
|
+
setFormConfig(type, config) {
|
|
2683
|
+
this.get("configs")[toLine(type)] = config;
|
|
2684
|
+
}
|
|
2685
|
+
getFormValue(type = "base") {
|
|
2686
|
+
return getFormValue(toLine(type), this.get("values")[type]);
|
|
2687
|
+
}
|
|
2688
|
+
setFormValue(type, value) {
|
|
2689
|
+
this.get("values")[toLine(type)] = value;
|
|
2690
|
+
}
|
|
2691
|
+
getFormEvent(type = "base") {
|
|
2692
|
+
return this.get("events")[toLine(type)] || [];
|
|
2693
|
+
}
|
|
2694
|
+
setFormEvent(type, value = []) {
|
|
2695
|
+
this.get("events")[toLine(type)] = value;
|
|
2696
|
+
}
|
|
2697
|
+
getFormMethod(type = "base") {
|
|
2698
|
+
return this.get("methods")[toLine(type)] || [];
|
|
2699
|
+
}
|
|
2700
|
+
setFormMethod(type, value = []) {
|
|
2701
|
+
this.get("methods")[toLine(type)] = value;
|
|
2702
|
+
}
|
|
2703
|
+
add(config) {
|
|
2704
|
+
const newConfig = {
|
|
2705
|
+
...config,
|
|
2706
|
+
id: config.id && !this.getDataSourceById(config.id) ? config.id : this.createId()
|
|
2707
|
+
};
|
|
2708
|
+
this.get("dataSources").push(newConfig);
|
|
2709
|
+
this.emit("add", newConfig);
|
|
2696
2710
|
return newConfig;
|
|
2697
2711
|
}
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
this.emit("
|
|
2710
|
-
|
|
2712
|
+
update(config) {
|
|
2713
|
+
const dataSources = this.get("dataSources");
|
|
2714
|
+
const index = dataSources.findIndex((ds) => ds.id === config.id);
|
|
2715
|
+
dataSources[index] = cloneDeep(config);
|
|
2716
|
+
this.emit("update", config);
|
|
2717
|
+
return config;
|
|
2718
|
+
}
|
|
2719
|
+
remove(id) {
|
|
2720
|
+
const dataSources = this.get("dataSources");
|
|
2721
|
+
const index = dataSources.findIndex((ds) => ds.id === id);
|
|
2722
|
+
dataSources.splice(index, 1);
|
|
2723
|
+
this.emit("remove", id);
|
|
2724
|
+
}
|
|
2725
|
+
createId() {
|
|
2726
|
+
return `ds_${guid()}`;
|
|
2727
|
+
}
|
|
2728
|
+
getDataSourceById(id) {
|
|
2729
|
+
return this.get("dataSources").find((ds) => ds.id === id);
|
|
2711
2730
|
}
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
* @param id1 组件ID
|
|
2715
|
-
* @param id2 组件ID
|
|
2716
|
-
* @returns void
|
|
2717
|
-
*/
|
|
2718
|
-
async sort(id1, id2) {
|
|
2719
|
-
const root = this.get("root");
|
|
2720
|
-
if (!root)
|
|
2721
|
-
throw new Error("root为空");
|
|
2722
|
-
const node = this.get("node");
|
|
2723
|
-
if (!node)
|
|
2724
|
-
throw new Error("当前节点为空");
|
|
2725
|
-
const parent = cloneDeep(toRaw(this.get("parent")));
|
|
2726
|
-
if (!parent)
|
|
2727
|
-
throw new Error("父节点为空");
|
|
2728
|
-
const index2 = parent.items.findIndex((node2) => `${node2.id}` === `${id2}`);
|
|
2729
|
-
if (index2 < 0)
|
|
2730
|
-
return;
|
|
2731
|
-
const index1 = parent.items.findIndex((node2) => `${node2.id}` === `${id1}`);
|
|
2732
|
-
parent.items.splice(index2, 0, ...parent.items.splice(index1, 1));
|
|
2733
|
-
await this.update(parent);
|
|
2734
|
-
await this.select(node);
|
|
2735
|
-
this.get("stage")?.update({
|
|
2736
|
-
config: cloneDeep(node),
|
|
2737
|
-
parentId: parent.id,
|
|
2738
|
-
root: cloneDeep(root)
|
|
2739
|
-
});
|
|
2740
|
-
this.addModifiedNodeId(parent.id);
|
|
2741
|
-
this.pushHistoryState();
|
|
2731
|
+
resetState() {
|
|
2732
|
+
this.set("dataSources", []);
|
|
2742
2733
|
}
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
protocol: Protocol.OBJECT
|
|
2751
|
-
});
|
|
2734
|
+
destroy() {
|
|
2735
|
+
this.removeAllListeners();
|
|
2736
|
+
this.resetState();
|
|
2737
|
+
this.removeAllPlugins();
|
|
2738
|
+
}
|
|
2739
|
+
usePlugin(options) {
|
|
2740
|
+
super.usePlugin(options);
|
|
2752
2741
|
}
|
|
2753
2742
|
/**
|
|
2754
|
-
*
|
|
2743
|
+
* 复制时会带上组件关联的数据源
|
|
2755
2744
|
* @param config 组件节点配置
|
|
2756
2745
|
* @returns
|
|
2757
2746
|
*/
|
|
2758
2747
|
copyWithRelated(config) {
|
|
2759
2748
|
const copyNodes = Array.isArray(config) ? config : [config];
|
|
2760
|
-
depService.clearByType(DepTargetType.
|
|
2761
|
-
depService.collect(copyNodes, true, DepTargetType.
|
|
2762
|
-
const customTarget = depService.getTarget(
|
|
2763
|
-
|
|
2764
|
-
DepTargetType.RELATED_COMP_WHEN_COPY
|
|
2765
|
-
);
|
|
2749
|
+
depService.clearByType(DepTargetType.RELATED_DS_WHEN_COPY);
|
|
2750
|
+
depService.collect(copyNodes, true, DepTargetType.RELATED_DS_WHEN_COPY);
|
|
2751
|
+
const customTarget = depService.getTarget(DepTargetType.RELATED_DS_WHEN_COPY, DepTargetType.RELATED_DS_WHEN_COPY);
|
|
2752
|
+
const copyData = [];
|
|
2766
2753
|
if (customTarget) {
|
|
2767
2754
|
Object.keys(customTarget.deps).forEach((nodeId) => {
|
|
2768
|
-
const node =
|
|
2755
|
+
const node = editorService.getNodeById(nodeId);
|
|
2769
2756
|
if (!node)
|
|
2770
2757
|
return;
|
|
2771
2758
|
customTarget.deps[nodeId].keys.forEach((key) => {
|
|
2772
|
-
const
|
|
2773
|
-
const isExist =
|
|
2759
|
+
const [relateDsId] = get(node, key);
|
|
2760
|
+
const isExist = copyData.find((dsItem) => dsItem.id === relateDsId);
|
|
2774
2761
|
if (!isExist) {
|
|
2775
|
-
const
|
|
2776
|
-
if (
|
|
2777
|
-
|
|
2762
|
+
const relateDs = this.getDataSourceById(relateDsId);
|
|
2763
|
+
if (relateDs) {
|
|
2764
|
+
copyData.push(relateDs);
|
|
2765
|
+
}
|
|
2766
|
+
}
|
|
2767
|
+
});
|
|
2768
|
+
});
|
|
2769
|
+
}
|
|
2770
|
+
storageService.setItem(COPY_DS_STORAGE_KEY, copyData, {
|
|
2771
|
+
protocol: Protocol.OBJECT
|
|
2772
|
+
});
|
|
2773
|
+
}
|
|
2774
|
+
/**
|
|
2775
|
+
* 粘贴数据源
|
|
2776
|
+
* @returns
|
|
2777
|
+
*/
|
|
2778
|
+
paste() {
|
|
2779
|
+
const dataSource = storageService.getItem(COPY_DS_STORAGE_KEY);
|
|
2780
|
+
dataSource.forEach((item) => {
|
|
2781
|
+
if (!this.getDataSourceById(item.id)) {
|
|
2782
|
+
this.add(item);
|
|
2783
|
+
}
|
|
2784
|
+
});
|
|
2785
|
+
}
|
|
2786
|
+
}
|
|
2787
|
+
const dataSourceService = new DataSource();
|
|
2788
|
+
|
|
2789
|
+
const arrayOptions = [
|
|
2790
|
+
{ text: "包含", value: "include" },
|
|
2791
|
+
{ text: "不包含", value: "not_include" }
|
|
2792
|
+
];
|
|
2793
|
+
const eqOptions = [
|
|
2794
|
+
{ text: "等于", value: "=" },
|
|
2795
|
+
{ text: "不等于", value: "!=" }
|
|
2796
|
+
];
|
|
2797
|
+
const numberOptions = [
|
|
2798
|
+
{ text: "大于", value: ">" },
|
|
2799
|
+
{ text: "大于等于", value: ">=" },
|
|
2800
|
+
{ text: "小于", value: "<" },
|
|
2801
|
+
{ text: "小于等于", value: "<=" },
|
|
2802
|
+
{ text: "在范围内", value: "between" },
|
|
2803
|
+
{ text: "不在范围内", value: "not_between" }
|
|
2804
|
+
];
|
|
2805
|
+
const styleTabConfig = {
|
|
2806
|
+
title: "样式",
|
|
2807
|
+
items: [
|
|
2808
|
+
{
|
|
2809
|
+
name: "style",
|
|
2810
|
+
items: [
|
|
2811
|
+
{
|
|
2812
|
+
type: "fieldset",
|
|
2813
|
+
legend: "位置",
|
|
2814
|
+
items: [
|
|
2815
|
+
{
|
|
2816
|
+
type: "data-source-field-select",
|
|
2817
|
+
name: "position",
|
|
2818
|
+
text: "固定定位",
|
|
2819
|
+
checkStrictly: false,
|
|
2820
|
+
dataSourceFieldType: ["string"],
|
|
2821
|
+
fieldConfig: {
|
|
2822
|
+
type: "checkbox",
|
|
2823
|
+
activeValue: "fixed",
|
|
2824
|
+
inactiveValue: "absolute",
|
|
2825
|
+
defaultValue: "absolute"
|
|
2826
|
+
}
|
|
2827
|
+
},
|
|
2828
|
+
{
|
|
2829
|
+
type: "data-source-field-select",
|
|
2830
|
+
name: "left",
|
|
2831
|
+
text: "left",
|
|
2832
|
+
checkStrictly: false,
|
|
2833
|
+
dataSourceFieldType: ["string", "number"],
|
|
2834
|
+
fieldConfig: {
|
|
2835
|
+
type: "text"
|
|
2836
|
+
}
|
|
2837
|
+
},
|
|
2838
|
+
{
|
|
2839
|
+
type: "data-source-field-select",
|
|
2840
|
+
name: "top",
|
|
2841
|
+
text: "top",
|
|
2842
|
+
checkStrictly: false,
|
|
2843
|
+
dataSourceFieldType: ["string", "number"],
|
|
2844
|
+
fieldConfig: {
|
|
2845
|
+
type: "text"
|
|
2846
|
+
},
|
|
2847
|
+
disabled: (vm, { model }) => model.position === "fixed" && model._magic_position === "fixedBottom"
|
|
2848
|
+
},
|
|
2849
|
+
{
|
|
2850
|
+
type: "data-source-field-select",
|
|
2851
|
+
name: "right",
|
|
2852
|
+
text: "right",
|
|
2853
|
+
checkStrictly: false,
|
|
2854
|
+
dataSourceFieldType: ["string", "number"],
|
|
2855
|
+
fieldConfig: {
|
|
2856
|
+
type: "text"
|
|
2857
|
+
}
|
|
2858
|
+
},
|
|
2859
|
+
{
|
|
2860
|
+
type: "data-source-field-select",
|
|
2861
|
+
name: "bottom",
|
|
2862
|
+
text: "bottom",
|
|
2863
|
+
checkStrictly: false,
|
|
2864
|
+
dataSourceFieldType: ["string", "number"],
|
|
2865
|
+
fieldConfig: {
|
|
2866
|
+
type: "text"
|
|
2867
|
+
},
|
|
2868
|
+
disabled: (vm, { model }) => model.position === "fixed" && model._magic_position === "fixedTop"
|
|
2869
|
+
}
|
|
2870
|
+
]
|
|
2871
|
+
},
|
|
2872
|
+
{
|
|
2873
|
+
type: "fieldset",
|
|
2874
|
+
legend: "盒子",
|
|
2875
|
+
items: [
|
|
2876
|
+
{
|
|
2877
|
+
type: "data-source-field-select",
|
|
2878
|
+
name: "width",
|
|
2879
|
+
text: "宽度",
|
|
2880
|
+
checkStrictly: false,
|
|
2881
|
+
dataSourceFieldType: ["string", "number"],
|
|
2882
|
+
fieldConfig: {
|
|
2883
|
+
type: "text"
|
|
2884
|
+
}
|
|
2885
|
+
},
|
|
2886
|
+
{
|
|
2887
|
+
type: "data-source-field-select",
|
|
2888
|
+
name: "height",
|
|
2889
|
+
text: "高度",
|
|
2890
|
+
checkStrictly: false,
|
|
2891
|
+
dataSourceFieldType: ["string", "number"],
|
|
2892
|
+
fieldConfig: {
|
|
2893
|
+
type: "text"
|
|
2894
|
+
}
|
|
2895
|
+
},
|
|
2896
|
+
{
|
|
2897
|
+
type: "data-source-field-select",
|
|
2898
|
+
text: "overflow",
|
|
2899
|
+
name: "overflow",
|
|
2900
|
+
checkStrictly: false,
|
|
2901
|
+
dataSourceFieldType: ["string"],
|
|
2902
|
+
fieldConfig: {
|
|
2903
|
+
type: "select",
|
|
2904
|
+
options: [
|
|
2905
|
+
{ text: "visible", value: "visible" },
|
|
2906
|
+
{ text: "hidden", value: "hidden" },
|
|
2907
|
+
{ text: "clip", value: "clip" },
|
|
2908
|
+
{ text: "scroll", value: "scroll" },
|
|
2909
|
+
{ text: "auto", value: "auto" },
|
|
2910
|
+
{ text: "overlay", value: "overlay" }
|
|
2911
|
+
]
|
|
2912
|
+
}
|
|
2913
|
+
}
|
|
2914
|
+
]
|
|
2915
|
+
},
|
|
2916
|
+
{
|
|
2917
|
+
type: "fieldset",
|
|
2918
|
+
legend: "边框",
|
|
2919
|
+
items: [
|
|
2920
|
+
{
|
|
2921
|
+
type: "data-source-field-select",
|
|
2922
|
+
name: "borderWidth",
|
|
2923
|
+
text: "宽度",
|
|
2924
|
+
defaultValue: "0",
|
|
2925
|
+
checkStrictly: false,
|
|
2926
|
+
dataSourceFieldType: ["string", "number"],
|
|
2927
|
+
fieldConfig: {
|
|
2928
|
+
type: "text"
|
|
2929
|
+
}
|
|
2930
|
+
},
|
|
2931
|
+
{
|
|
2932
|
+
type: "data-source-field-select",
|
|
2933
|
+
name: "borderColor",
|
|
2934
|
+
text: "颜色",
|
|
2935
|
+
checkStrictly: false,
|
|
2936
|
+
dataSourceFieldType: ["string"],
|
|
2937
|
+
fieldConfig: {
|
|
2938
|
+
type: "text"
|
|
2939
|
+
}
|
|
2940
|
+
},
|
|
2941
|
+
{
|
|
2942
|
+
type: "data-source-field-select",
|
|
2943
|
+
name: "borderStyle",
|
|
2944
|
+
text: "样式",
|
|
2945
|
+
defaultValue: "none",
|
|
2946
|
+
checkStrictly: false,
|
|
2947
|
+
dataSourceFieldType: ["string"],
|
|
2948
|
+
fieldConfig: {
|
|
2949
|
+
type: "select",
|
|
2950
|
+
options: [
|
|
2951
|
+
{ text: "none", value: "none" },
|
|
2952
|
+
{ text: "hidden", value: "hidden" },
|
|
2953
|
+
{ text: "dotted", value: "dotted" },
|
|
2954
|
+
{ text: "dashed", value: "dashed" },
|
|
2955
|
+
{ text: "solid", value: "solid" },
|
|
2956
|
+
{ text: "double", value: "double" },
|
|
2957
|
+
{ text: "groove", value: "groove" },
|
|
2958
|
+
{ text: "ridge", value: "ridge" },
|
|
2959
|
+
{ text: "inset", value: "inset" },
|
|
2960
|
+
{ text: "outset", value: "outset" }
|
|
2961
|
+
]
|
|
2962
|
+
}
|
|
2778
2963
|
}
|
|
2779
|
-
|
|
2780
|
-
}
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
* 移动到指定容器中
|
|
2899
|
-
* @param config 需要移动的节点
|
|
2900
|
-
* @param targetId 容器ID
|
|
2901
|
-
*/
|
|
2902
|
-
async moveToContainer(config, targetId) {
|
|
2903
|
-
const root = this.get("root");
|
|
2904
|
-
const { node, parent } = this.getNodeInfo(config.id, false);
|
|
2905
|
-
const target = this.getNodeById(targetId, false);
|
|
2906
|
-
const stage = this.get("stage");
|
|
2907
|
-
if (root && node && parent && stage) {
|
|
2908
|
-
const index = getNodeIndex(node.id, parent);
|
|
2909
|
-
parent.items?.splice(index, 1);
|
|
2910
|
-
await stage.remove({ id: node.id, parentId: parent.id, root: cloneDeep(root) });
|
|
2911
|
-
const layout = await this.getLayout(target);
|
|
2912
|
-
const newConfig = mergeWith(cloneDeep(node), config, (objValue, srcValue) => {
|
|
2913
|
-
if (Array.isArray(srcValue)) {
|
|
2914
|
-
return srcValue;
|
|
2964
|
+
]
|
|
2965
|
+
},
|
|
2966
|
+
{
|
|
2967
|
+
type: "fieldset",
|
|
2968
|
+
legend: "背景",
|
|
2969
|
+
items: [
|
|
2970
|
+
{
|
|
2971
|
+
type: "data-source-field-select",
|
|
2972
|
+
name: "backgroundImage",
|
|
2973
|
+
text: "背景图",
|
|
2974
|
+
checkStrictly: false,
|
|
2975
|
+
dataSourceFieldType: ["string"],
|
|
2976
|
+
fieldConfig: {
|
|
2977
|
+
type: "text"
|
|
2978
|
+
}
|
|
2979
|
+
},
|
|
2980
|
+
{
|
|
2981
|
+
type: "data-source-field-select",
|
|
2982
|
+
name: "backgroundColor",
|
|
2983
|
+
text: "背景颜色",
|
|
2984
|
+
checkStrictly: false,
|
|
2985
|
+
dataSourceFieldType: ["string"],
|
|
2986
|
+
fieldConfig: {
|
|
2987
|
+
type: "colorPicker"
|
|
2988
|
+
}
|
|
2989
|
+
},
|
|
2990
|
+
{
|
|
2991
|
+
type: "data-source-field-select",
|
|
2992
|
+
name: "backgroundRepeat",
|
|
2993
|
+
text: "背景图重复",
|
|
2994
|
+
defaultValue: "no-repeat",
|
|
2995
|
+
checkStrictly: false,
|
|
2996
|
+
dataSourceFieldType: ["string"],
|
|
2997
|
+
fieldConfig: {
|
|
2998
|
+
type: "select",
|
|
2999
|
+
options: [
|
|
3000
|
+
{ text: "repeat", value: "repeat" },
|
|
3001
|
+
{ text: "repeat-x", value: "repeat-x" },
|
|
3002
|
+
{ text: "repeat-y", value: "repeat-y" },
|
|
3003
|
+
{ text: "no-repeat", value: "no-repeat" },
|
|
3004
|
+
{ text: "inherit", value: "inherit" }
|
|
3005
|
+
]
|
|
3006
|
+
}
|
|
3007
|
+
},
|
|
3008
|
+
{
|
|
3009
|
+
type: "data-source-field-select",
|
|
3010
|
+
name: "backgroundSize",
|
|
3011
|
+
text: "背景图大小",
|
|
3012
|
+
defaultValue: "100% 100%",
|
|
3013
|
+
checkStrictly: false,
|
|
3014
|
+
dataSourceFieldType: ["string"],
|
|
3015
|
+
fieldConfig: {
|
|
3016
|
+
type: "text"
|
|
3017
|
+
}
|
|
3018
|
+
}
|
|
3019
|
+
]
|
|
3020
|
+
},
|
|
3021
|
+
{
|
|
3022
|
+
type: "fieldset",
|
|
3023
|
+
legend: "字体",
|
|
3024
|
+
items: [
|
|
3025
|
+
{
|
|
3026
|
+
type: "data-source-field-select",
|
|
3027
|
+
name: "color",
|
|
3028
|
+
text: "颜色",
|
|
3029
|
+
checkStrictly: false,
|
|
3030
|
+
dataSourceFieldType: ["string"],
|
|
3031
|
+
fieldConfig: {
|
|
3032
|
+
type: "colorPicker"
|
|
3033
|
+
}
|
|
3034
|
+
},
|
|
3035
|
+
{
|
|
3036
|
+
type: "data-source-field-select",
|
|
3037
|
+
name: "fontSize",
|
|
3038
|
+
text: "大小",
|
|
3039
|
+
checkStrictly: false,
|
|
3040
|
+
dataSourceFieldType: ["string", "number"],
|
|
3041
|
+
fieldConfig: {
|
|
3042
|
+
type: "text"
|
|
3043
|
+
}
|
|
3044
|
+
},
|
|
3045
|
+
{
|
|
3046
|
+
type: "data-source-field-select",
|
|
3047
|
+
name: "fontWeight",
|
|
3048
|
+
text: "粗细",
|
|
3049
|
+
checkStrictly: false,
|
|
3050
|
+
dataSourceFieldType: ["string", "number"],
|
|
3051
|
+
fieldConfig: {
|
|
3052
|
+
type: "text"
|
|
3053
|
+
}
|
|
3054
|
+
}
|
|
3055
|
+
]
|
|
3056
|
+
},
|
|
3057
|
+
{
|
|
3058
|
+
type: "fieldset",
|
|
3059
|
+
legend: "变形",
|
|
3060
|
+
name: "transform",
|
|
3061
|
+
items: [
|
|
3062
|
+
{
|
|
3063
|
+
type: "data-source-field-select",
|
|
3064
|
+
name: "rotate",
|
|
3065
|
+
text: "旋转角度",
|
|
3066
|
+
checkStrictly: false,
|
|
3067
|
+
dataSourceFieldType: ["string"],
|
|
3068
|
+
fieldConfig: {
|
|
3069
|
+
type: "text"
|
|
3070
|
+
}
|
|
3071
|
+
},
|
|
3072
|
+
{
|
|
3073
|
+
type: "data-source-field-select",
|
|
3074
|
+
name: "scale",
|
|
3075
|
+
text: "缩放",
|
|
3076
|
+
checkStrictly: false,
|
|
3077
|
+
dataSourceFieldType: ["number", "string"],
|
|
3078
|
+
fieldConfig: {
|
|
3079
|
+
type: "text"
|
|
3080
|
+
}
|
|
3081
|
+
}
|
|
3082
|
+
]
|
|
2915
3083
|
}
|
|
2916
|
-
|
|
2917
|
-
newConfig.style = getInitPositionStyle(newConfig.style, layout);
|
|
2918
|
-
target.items.push(newConfig);
|
|
2919
|
-
await stage.select(targetId);
|
|
2920
|
-
const targetParent = this.getParentById(target.id);
|
|
2921
|
-
await stage.update({ config: cloneDeep(target), parentId: targetParent?.id, root: cloneDeep(root) });
|
|
2922
|
-
await this.select(newConfig);
|
|
2923
|
-
stage.select(newConfig.id);
|
|
2924
|
-
this.addModifiedNodeId(target.id);
|
|
2925
|
-
this.addModifiedNodeId(parent.id);
|
|
2926
|
-
this.pushHistoryState();
|
|
2927
|
-
return newConfig;
|
|
2928
|
-
}
|
|
2929
|
-
}
|
|
2930
|
-
async dragTo(config, targetParent, targetIndex) {
|
|
2931
|
-
if (!targetParent || !Array.isArray(targetParent.items))
|
|
2932
|
-
return;
|
|
2933
|
-
const { parent, node: curNode } = this.getNodeInfo(config.id, false);
|
|
2934
|
-
if (!parent || !curNode)
|
|
2935
|
-
throw new Error("找不要删除的节点");
|
|
2936
|
-
const index = getNodeIndex(curNode.id, parent);
|
|
2937
|
-
if (typeof index !== "number" || index === -1)
|
|
2938
|
-
throw new Error("找不要删除的节点");
|
|
2939
|
-
if (parent.id === targetParent.id) {
|
|
2940
|
-
if (index === targetIndex)
|
|
2941
|
-
return;
|
|
2942
|
-
if (index < targetIndex) {
|
|
2943
|
-
targetIndex -= 1;
|
|
2944
|
-
}
|
|
2945
|
-
}
|
|
2946
|
-
const layout = await this.getLayout(parent);
|
|
2947
|
-
const newLayout = await this.getLayout(targetParent);
|
|
2948
|
-
if (newLayout !== layout) {
|
|
2949
|
-
setLayout(config, newLayout);
|
|
2950
|
-
}
|
|
2951
|
-
parent.items?.splice(index, 1);
|
|
2952
|
-
targetParent.items?.splice(targetIndex, 0, config);
|
|
2953
|
-
const page = this.get("page");
|
|
2954
|
-
const root = this.get("root");
|
|
2955
|
-
const stage = this.get("stage");
|
|
2956
|
-
if (stage && page && root) {
|
|
2957
|
-
stage.update({
|
|
2958
|
-
config: cloneDeep(page),
|
|
2959
|
-
parentId: root.id,
|
|
2960
|
-
root: cloneDeep(root)
|
|
2961
|
-
});
|
|
2962
|
-
}
|
|
2963
|
-
this.addModifiedNodeId(config.id);
|
|
2964
|
-
this.addModifiedNodeId(parent.id);
|
|
2965
|
-
this.pushHistoryState();
|
|
2966
|
-
this.emit("drag-to", { index, targetIndex, config, parent, targetParent });
|
|
2967
|
-
}
|
|
2968
|
-
/**
|
|
2969
|
-
* 撤销当前操作
|
|
2970
|
-
* @returns 上一次数据
|
|
2971
|
-
*/
|
|
2972
|
-
async undo() {
|
|
2973
|
-
const value = historyService.undo();
|
|
2974
|
-
await this.changeHistoryState(value);
|
|
2975
|
-
return value;
|
|
2976
|
-
}
|
|
2977
|
-
/**
|
|
2978
|
-
* 恢复到下一步
|
|
2979
|
-
* @returns 下一步数据
|
|
2980
|
-
*/
|
|
2981
|
-
async redo() {
|
|
2982
|
-
const value = historyService.redo();
|
|
2983
|
-
await this.changeHistoryState(value);
|
|
2984
|
-
return value;
|
|
2985
|
-
}
|
|
2986
|
-
async move(left, top) {
|
|
2987
|
-
const node = toRaw(this.get("node"));
|
|
2988
|
-
if (!node || isPage(node))
|
|
2989
|
-
return;
|
|
2990
|
-
const { style, id, type } = node;
|
|
2991
|
-
if (!style || !["absolute", "fixed"].includes(style.position))
|
|
2992
|
-
return;
|
|
2993
|
-
const update = (style2) => this.update({
|
|
2994
|
-
id,
|
|
2995
|
-
type,
|
|
2996
|
-
style: style2
|
|
2997
|
-
});
|
|
2998
|
-
if (top) {
|
|
2999
|
-
if (isNumber(style.top)) {
|
|
3000
|
-
update({
|
|
3001
|
-
...style,
|
|
3002
|
-
top: Number(style.top) + Number(top),
|
|
3003
|
-
bottom: ""
|
|
3004
|
-
});
|
|
3005
|
-
} else if (isNumber(style.bottom)) {
|
|
3006
|
-
update({
|
|
3007
|
-
...style,
|
|
3008
|
-
bottom: Number(style.bottom) - Number(top),
|
|
3009
|
-
top: ""
|
|
3010
|
-
});
|
|
3011
|
-
}
|
|
3084
|
+
]
|
|
3012
3085
|
}
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
right: Number(style.right) - Number(left),
|
|
3024
|
-
left: ""
|
|
3025
|
-
});
|
|
3026
|
-
}
|
|
3086
|
+
]
|
|
3087
|
+
};
|
|
3088
|
+
const eventTabConfig = {
|
|
3089
|
+
title: "事件",
|
|
3090
|
+
items: [
|
|
3091
|
+
{
|
|
3092
|
+
name: "events",
|
|
3093
|
+
src: "component",
|
|
3094
|
+
labelWidth: "100px",
|
|
3095
|
+
type: "event-select"
|
|
3027
3096
|
}
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
this.removeAllPlugins();
|
|
3044
|
-
}
|
|
3045
|
-
resetModifiedNodeId() {
|
|
3046
|
-
this.get("modifiedNodeIds").clear();
|
|
3047
|
-
}
|
|
3048
|
-
usePlugin(options) {
|
|
3049
|
-
super.usePlugin(options);
|
|
3050
|
-
}
|
|
3051
|
-
addModifiedNodeId(id) {
|
|
3052
|
-
if (!this.isHistoryStateChange) {
|
|
3053
|
-
this.get("modifiedNodeIds").set(id, id);
|
|
3097
|
+
]
|
|
3098
|
+
};
|
|
3099
|
+
const advancedTabConfig = {
|
|
3100
|
+
title: "高级",
|
|
3101
|
+
lazy: true,
|
|
3102
|
+
items: [
|
|
3103
|
+
{
|
|
3104
|
+
name: "created",
|
|
3105
|
+
text: "created",
|
|
3106
|
+
type: "code-select"
|
|
3107
|
+
},
|
|
3108
|
+
{
|
|
3109
|
+
name: "mounted",
|
|
3110
|
+
text: "mounted",
|
|
3111
|
+
type: "code-select"
|
|
3054
3112
|
}
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3113
|
+
]
|
|
3114
|
+
};
|
|
3115
|
+
const displayTabConfig = {
|
|
3116
|
+
title: "显示条件",
|
|
3117
|
+
display: (vm, { model }) => model.type !== "page",
|
|
3118
|
+
items: [
|
|
3119
|
+
{
|
|
3120
|
+
type: "groupList",
|
|
3121
|
+
name: "displayConds",
|
|
3122
|
+
titlePrefix: "条件组",
|
|
3123
|
+
expandAll: true,
|
|
3124
|
+
items: [
|
|
3125
|
+
{
|
|
3126
|
+
type: "table",
|
|
3127
|
+
name: "cond",
|
|
3128
|
+
items: [
|
|
3129
|
+
{
|
|
3130
|
+
type: "data-source-field-select",
|
|
3131
|
+
name: "field",
|
|
3132
|
+
value: "key",
|
|
3133
|
+
label: "字段",
|
|
3134
|
+
checkStrictly: false,
|
|
3135
|
+
dataSourceFieldType: ["string", "number", "boolean", "any"]
|
|
3136
|
+
},
|
|
3137
|
+
{
|
|
3138
|
+
type: "select",
|
|
3139
|
+
options: (mForm, { model }) => {
|
|
3140
|
+
const [id, ...fieldNames] = model.field;
|
|
3141
|
+
const ds = dataSourceService.getDataSourceById(id);
|
|
3142
|
+
let fields = ds?.fields || [];
|
|
3143
|
+
let type = "";
|
|
3144
|
+
(fieldNames || []).forEach((fieldName) => {
|
|
3145
|
+
const field = fields.find((f) => f.name === fieldName);
|
|
3146
|
+
fields = field?.fields || [];
|
|
3147
|
+
type = field?.type || "";
|
|
3148
|
+
});
|
|
3149
|
+
if (type === "array") {
|
|
3150
|
+
return arrayOptions;
|
|
3151
|
+
}
|
|
3152
|
+
if (type === "boolean") {
|
|
3153
|
+
return [
|
|
3154
|
+
{ text: "是", value: "is" },
|
|
3155
|
+
{ text: "不是", value: "not" }
|
|
3156
|
+
];
|
|
3157
|
+
}
|
|
3158
|
+
if (type === "number") {
|
|
3159
|
+
return [...eqOptions, ...numberOptions];
|
|
3160
|
+
}
|
|
3161
|
+
if (type === "string") {
|
|
3162
|
+
return [...arrayOptions, ...eqOptions];
|
|
3163
|
+
}
|
|
3164
|
+
return [...arrayOptions, ...eqOptions, ...numberOptions];
|
|
3165
|
+
},
|
|
3166
|
+
label: "条件",
|
|
3167
|
+
name: "op"
|
|
3168
|
+
},
|
|
3169
|
+
{
|
|
3170
|
+
label: "值",
|
|
3171
|
+
items: [
|
|
3172
|
+
{
|
|
3173
|
+
name: "value",
|
|
3174
|
+
type: (mForm, { model }) => {
|
|
3175
|
+
const [id, ...fieldNames] = model.field;
|
|
3176
|
+
const ds = dataSourceService.getDataSourceById(id);
|
|
3177
|
+
let fields = ds?.fields || [];
|
|
3178
|
+
let type = "";
|
|
3179
|
+
(fieldNames || []).forEach((fieldName) => {
|
|
3180
|
+
const field = fields.find((f) => f.name === fieldName);
|
|
3181
|
+
fields = field?.fields || [];
|
|
3182
|
+
type = field?.type || "";
|
|
3183
|
+
});
|
|
3184
|
+
if (type === "number") {
|
|
3185
|
+
return "number";
|
|
3186
|
+
}
|
|
3187
|
+
if (type === "boolean") {
|
|
3188
|
+
return "select";
|
|
3189
|
+
}
|
|
3190
|
+
return "text";
|
|
3191
|
+
},
|
|
3192
|
+
options: [
|
|
3193
|
+
{ text: "true", value: true },
|
|
3194
|
+
{ text: "false", value: false }
|
|
3195
|
+
],
|
|
3196
|
+
display: (vm, { model }) => !["between", "not_between"].includes(model.op)
|
|
3197
|
+
},
|
|
3198
|
+
{
|
|
3199
|
+
name: "range",
|
|
3200
|
+
type: "number-range",
|
|
3201
|
+
display: (vm, { model }) => ["between", "not_between"].includes(model.op)
|
|
3202
|
+
}
|
|
3203
|
+
]
|
|
3204
|
+
}
|
|
3205
|
+
]
|
|
3206
|
+
}
|
|
3207
|
+
]
|
|
3065
3208
|
}
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3209
|
+
]
|
|
3210
|
+
};
|
|
3211
|
+
const fillConfig = (config = [], labelWidth = "80px") => [
|
|
3212
|
+
{
|
|
3213
|
+
type: "tab",
|
|
3214
|
+
labelWidth,
|
|
3215
|
+
items: [
|
|
3216
|
+
{
|
|
3217
|
+
title: "属性",
|
|
3218
|
+
items: [
|
|
3219
|
+
// 组件类型,必须要有
|
|
3220
|
+
{
|
|
3221
|
+
text: "type",
|
|
3222
|
+
name: "type",
|
|
3223
|
+
type: "hidden"
|
|
3224
|
+
},
|
|
3225
|
+
// 组件id,必须要有
|
|
3226
|
+
{
|
|
3227
|
+
name: "id",
|
|
3228
|
+
type: "display",
|
|
3229
|
+
text: "id"
|
|
3230
|
+
},
|
|
3231
|
+
{
|
|
3232
|
+
name: "name",
|
|
3233
|
+
text: "组件名称"
|
|
3234
|
+
},
|
|
3235
|
+
...config
|
|
3236
|
+
]
|
|
3237
|
+
},
|
|
3238
|
+
{ ...styleTabConfig },
|
|
3239
|
+
{ ...eventTabConfig },
|
|
3240
|
+
{ ...advancedTabConfig },
|
|
3241
|
+
{ ...displayTabConfig }
|
|
3242
|
+
]
|
|
3081
3243
|
}
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
} else if (!isFixed(newConfig) && isFixed(src)) {
|
|
3088
|
-
newConfig.style = await Fixed2Other(newConfig, root, this.getLayout);
|
|
3089
|
-
}
|
|
3090
|
-
}
|
|
3091
|
-
return newConfig;
|
|
3244
|
+
];
|
|
3245
|
+
|
|
3246
|
+
const log = (...args) => {
|
|
3247
|
+
if (process.env.NODE_ENV === "development") {
|
|
3248
|
+
console.log("magic editor: ", ...args);
|
|
3092
3249
|
}
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
} else {
|
|
3098
|
-
id = config.id;
|
|
3099
|
-
}
|
|
3100
|
-
if (!id) {
|
|
3101
|
-
throw new Error("没有ID,无法选中");
|
|
3102
|
-
}
|
|
3103
|
-
const { node, parent, page } = this.getNodeInfo(id);
|
|
3104
|
-
if (!node)
|
|
3105
|
-
throw new Error("获取不到组件信息");
|
|
3106
|
-
if (node.id === this.state.root?.id) {
|
|
3107
|
-
throw new Error("不能选根节点");
|
|
3108
|
-
}
|
|
3109
|
-
return {
|
|
3110
|
-
node,
|
|
3111
|
-
parent,
|
|
3112
|
-
page
|
|
3113
|
-
};
|
|
3250
|
+
};
|
|
3251
|
+
const info = (...args) => {
|
|
3252
|
+
if (process.env.NODE_ENV === "development") {
|
|
3253
|
+
console.info("magic editor: ", ...args);
|
|
3114
3254
|
}
|
|
3115
|
-
}
|
|
3116
|
-
const editorService = new Editor();
|
|
3117
|
-
|
|
3118
|
-
const beforePaste = (position, config) => {
|
|
3119
|
-
if (!config[0]?.style)
|
|
3120
|
-
return config;
|
|
3121
|
-
const curNode = editorService.get("node");
|
|
3122
|
-
const { left: referenceLeft, top: referenceTop } = config[0].style;
|
|
3123
|
-
const pasteConfigs = config.map((configItem) => {
|
|
3124
|
-
const { offsetX = 0, offsetY = 0, ...positionClone } = position;
|
|
3125
|
-
let pastePosition = positionClone;
|
|
3126
|
-
if (!isEmpty(pastePosition) && curNode?.items) {
|
|
3127
|
-
pastePosition = getPositionInContainer(pastePosition, curNode.id);
|
|
3128
|
-
}
|
|
3129
|
-
if (pastePosition.left && configItem.style?.left) {
|
|
3130
|
-
pastePosition.left = configItem.style.left - referenceLeft + pastePosition.left;
|
|
3131
|
-
}
|
|
3132
|
-
if (pastePosition.top && configItem.style?.top) {
|
|
3133
|
-
pastePosition.top = configItem.style?.top - referenceTop + pastePosition.top;
|
|
3134
|
-
}
|
|
3135
|
-
const pasteConfig = propsService.setNewItemId(configItem, false);
|
|
3136
|
-
if (pasteConfig.style) {
|
|
3137
|
-
const { left, top } = pasteConfig.style;
|
|
3138
|
-
if (typeof left === "number" || !!left && !isNaN(Number(left))) {
|
|
3139
|
-
pasteConfig.style.left = Number(left) + offsetX;
|
|
3140
|
-
}
|
|
3141
|
-
if (typeof top === "number" || !!top && !isNaN(Number(top))) {
|
|
3142
|
-
pasteConfig.style.top = Number(top) + offsetY;
|
|
3143
|
-
}
|
|
3144
|
-
pasteConfig.style = {
|
|
3145
|
-
...pasteConfig.style,
|
|
3146
|
-
...pastePosition
|
|
3147
|
-
};
|
|
3148
|
-
}
|
|
3149
|
-
const root = editorService.get("root");
|
|
3150
|
-
if ((isPage(pasteConfig) || isPageFragment(pasteConfig)) && root) {
|
|
3151
|
-
pasteConfig.name = generatePageNameByApp(root, isPage(pasteConfig) ? NodeType.PAGE : NodeType.PAGE_FRAGMENT);
|
|
3152
|
-
}
|
|
3153
|
-
return pasteConfig;
|
|
3154
|
-
});
|
|
3155
|
-
return pasteConfigs;
|
|
3156
3255
|
};
|
|
3157
|
-
const
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
left = left - (parentElRect?.left || 0);
|
|
3162
|
-
top = top - (parentElRect?.top || 0);
|
|
3163
|
-
return {
|
|
3164
|
-
left,
|
|
3165
|
-
top
|
|
3166
|
-
};
|
|
3256
|
+
const warn = (...args) => {
|
|
3257
|
+
if (process.env.NODE_ENV === "development") {
|
|
3258
|
+
console.warn("magic editor: ", ...args);
|
|
3259
|
+
}
|
|
3167
3260
|
};
|
|
3168
|
-
const
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
if (isPage(node)) {
|
|
3172
|
-
parentNode = editorService.get("root");
|
|
3173
|
-
} else if (curNode?.items) {
|
|
3174
|
-
parentNode = curNode;
|
|
3175
|
-
} else if (curNode?.id) {
|
|
3176
|
-
parentNode = editorService.getParentById(curNode.id, false);
|
|
3261
|
+
const debug = (...args) => {
|
|
3262
|
+
if (process.env.NODE_ENV === "development") {
|
|
3263
|
+
console.debug("magic editor: ", ...args);
|
|
3177
3264
|
}
|
|
3178
|
-
return parentNode;
|
|
3179
3265
|
};
|
|
3180
|
-
const
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
newNode.style = getInitPositionStyle(newNode.style, layout);
|
|
3185
|
-
return newNode;
|
|
3266
|
+
const error = (...args) => {
|
|
3267
|
+
if (process.env.NODE_ENV === "development") {
|
|
3268
|
+
console.error("magic editor: ", ...args);
|
|
3269
|
+
}
|
|
3186
3270
|
};
|
|
3187
3271
|
|
|
3188
3272
|
const _sfc_main$P = /* @__PURE__ */ defineComponent({
|
|
@@ -3572,7 +3656,6 @@ const useCodeBlockEdit = (codeBlockService) => {
|
|
|
3572
3656
|
if (!codeId.value)
|
|
3573
3657
|
return;
|
|
3574
3658
|
await codeBlockService?.setCodeDslById(codeId.value, values);
|
|
3575
|
-
tMagicMessage.success("代码块保存成功");
|
|
3576
3659
|
codeBlockEditor.value?.hide();
|
|
3577
3660
|
};
|
|
3578
3661
|
return {
|
|
@@ -3774,7 +3857,7 @@ const useStage = (stageOptions) => {
|
|
|
3774
3857
|
const stage = new StageCore({
|
|
3775
3858
|
render: stageOptions.render,
|
|
3776
3859
|
runtimeUrl: stageOptions.runtimeUrl,
|
|
3777
|
-
zoom: zoom.value,
|
|
3860
|
+
zoom: stageOptions.zoom ?? zoom.value,
|
|
3778
3861
|
autoScrollIntoView: stageOptions.autoScrollIntoView,
|
|
3779
3862
|
isContainer: stageOptions.isContainer,
|
|
3780
3863
|
containerHighlightClassName: stageOptions.containerHighlightClassName,
|
|
@@ -4355,33 +4438,6 @@ const _sfc_main$L = /* @__PURE__ */ defineComponent({
|
|
|
4355
4438
|
return value[0].replace(DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX, "");
|
|
4356
4439
|
});
|
|
4357
4440
|
const dataSources = computed(() => services?.dataSourceService.get("dataSources"));
|
|
4358
|
-
const getOptionChildren = (fields = [], dataSourceFieldType = ["any"]) => {
|
|
4359
|
-
const child = [];
|
|
4360
|
-
fields.forEach((field) => {
|
|
4361
|
-
if (!dataSourceFieldType.length) {
|
|
4362
|
-
dataSourceFieldType.push("any");
|
|
4363
|
-
}
|
|
4364
|
-
const children = getOptionChildren(field.fields, dataSourceFieldType);
|
|
4365
|
-
const item = {
|
|
4366
|
-
label: field.title || field.name,
|
|
4367
|
-
value: field.name,
|
|
4368
|
-
children
|
|
4369
|
-
};
|
|
4370
|
-
const fieldType = field.type || "any";
|
|
4371
|
-
if (dataSourceFieldType.includes("any") || dataSourceFieldType.includes(fieldType)) {
|
|
4372
|
-
child.push(item);
|
|
4373
|
-
return;
|
|
4374
|
-
}
|
|
4375
|
-
if (!dataSourceFieldType.includes(fieldType) && !["array", "object", "any"].includes(fieldType)) {
|
|
4376
|
-
return;
|
|
4377
|
-
}
|
|
4378
|
-
if (!children.length && ["object", "array", "any"].includes(field.type || "")) {
|
|
4379
|
-
return;
|
|
4380
|
-
}
|
|
4381
|
-
child.push(item);
|
|
4382
|
-
});
|
|
4383
|
-
return child;
|
|
4384
|
-
};
|
|
4385
4441
|
const cascaderConfig = computed(() => {
|
|
4386
4442
|
const valueIsKey = props.config.value === "key";
|
|
4387
4443
|
return {
|
|
@@ -4392,7 +4448,7 @@ const _sfc_main$L = /* @__PURE__ */ defineComponent({
|
|
|
4392
4448
|
const options = dataSources.value?.map((ds) => ({
|
|
4393
4449
|
label: ds.title || ds.id,
|
|
4394
4450
|
value: valueIsKey ? ds.id : `${DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX}${ds.id}`,
|
|
4395
|
-
children:
|
|
4451
|
+
children: getCascaderOptionsFromFields(ds.fields, props.config.dataSourceFieldType)
|
|
4396
4452
|
})) || [];
|
|
4397
4453
|
return options.filter((option) => option.children.length);
|
|
4398
4454
|
}
|
|
@@ -4444,7 +4500,6 @@ const _sfc_main$L = /* @__PURE__ */ defineComponent({
|
|
|
4444
4500
|
return (_ctx, _cache) => {
|
|
4445
4501
|
return openBlock(), createElementBlock("div", _hoisted_1$q, [
|
|
4446
4502
|
(openBlock(), createBlock(resolveDynamicComponent(tagName.value), {
|
|
4447
|
-
style: { "width": "100%" },
|
|
4448
4503
|
config: showDataSourceFieldSelect.value || !_ctx.config.fieldConfig ? cascaderConfig.value : _ctx.config.fieldConfig,
|
|
4449
4504
|
model: _ctx.model,
|
|
4450
4505
|
name: _ctx.name,
|
|
@@ -5631,24 +5686,41 @@ const _sfc_main$E = /* @__PURE__ */ defineComponent({
|
|
|
5631
5686
|
const eventsService = services?.eventsService;
|
|
5632
5687
|
const codeBlockService = services?.codeBlockService;
|
|
5633
5688
|
const eventNameConfig = computed(() => {
|
|
5689
|
+
const fieldType = props.config.src === "component" ? "select" : "cascader";
|
|
5634
5690
|
const defaultEventNameConfig = {
|
|
5635
5691
|
name: "name",
|
|
5636
5692
|
text: "事件",
|
|
5637
|
-
type:
|
|
5693
|
+
type: fieldType,
|
|
5638
5694
|
labelWidth: "40px",
|
|
5695
|
+
checkStrictly: true,
|
|
5696
|
+
valueSeparator: ".",
|
|
5639
5697
|
options: (mForm, { formValue }) => {
|
|
5640
5698
|
let events = [];
|
|
5641
5699
|
if (!eventsService || !dataSourceService)
|
|
5642
5700
|
return events;
|
|
5643
5701
|
if (props.config.src === "component") {
|
|
5644
5702
|
events = eventsService.getEvent(formValue.type);
|
|
5645
|
-
|
|
5703
|
+
return events.map((option) => ({
|
|
5704
|
+
text: option.label,
|
|
5705
|
+
value: option.value
|
|
5706
|
+
}));
|
|
5707
|
+
}
|
|
5708
|
+
if (props.config.src === "datasource") {
|
|
5646
5709
|
events = dataSourceService.getFormEvent(formValue.type);
|
|
5710
|
+
const dataSource = dataSourceService.getDataSourceById(formValue.id);
|
|
5711
|
+
const fields = dataSource?.fields || [];
|
|
5712
|
+
if (fields.length > 0) {
|
|
5713
|
+
return [
|
|
5714
|
+
...events,
|
|
5715
|
+
{
|
|
5716
|
+
label: "数据变化",
|
|
5717
|
+
value: DATA_SOURCE_FIELDS_CHANGE_EVENT_PREFIX,
|
|
5718
|
+
children: getCascaderOptionsFromFields(fields)
|
|
5719
|
+
}
|
|
5720
|
+
];
|
|
5721
|
+
}
|
|
5722
|
+
return events;
|
|
5647
5723
|
}
|
|
5648
|
-
return events.map((option) => ({
|
|
5649
|
-
text: option.label,
|
|
5650
|
-
value: option.value
|
|
5651
|
-
}));
|
|
5652
5724
|
}
|
|
5653
5725
|
};
|
|
5654
5726
|
return { ...defaultEventNameConfig, ...props.config.eventNameConfig };
|
|
@@ -8614,8 +8686,8 @@ const usePasteMenu = (menu) => ({
|
|
|
8614
8686
|
const stage = services?.editorService?.get("stage");
|
|
8615
8687
|
const rect = menu.value.$el.getBoundingClientRect();
|
|
8616
8688
|
const parentRect = stage?.container?.getBoundingClientRect();
|
|
8617
|
-
const initialLeft = (rect.left || 0) - (parentRect?.left || 0);
|
|
8618
|
-
const initialTop = (rect.top || 0) - (parentRect?.top || 0);
|
|
8689
|
+
const initialLeft = calcValueByFontsize(stage?.renderer.getDocument(), (rect.left || 0) - (parentRect?.left || 0)) / services.uiService.get("zoom");
|
|
8690
|
+
const initialTop = calcValueByFontsize(stage?.renderer.getDocument(), (rect.top || 0) - (parentRect?.top || 0)) / services.uiService.get("zoom");
|
|
8619
8691
|
services?.editorService?.paste({ left: initialLeft, top: initialTop });
|
|
8620
8692
|
} else {
|
|
8621
8693
|
services?.editorService?.paste();
|
|
@@ -9612,7 +9684,10 @@ const _sfc_main$a = /* @__PURE__ */ defineComponent({
|
|
|
9612
9684
|
class: "m-editor-sidebar-content",
|
|
9613
9685
|
key: config.$key ?? index
|
|
9614
9686
|
}, [
|
|
9615
|
-
config && !unref(floatBoxStates)[config.$key]?.status ? (openBlock(), createBlock(resolveDynamicComponent(config.component), mergeProps({
|
|
9687
|
+
config && !unref(floatBoxStates)[config.$key]?.status ? (openBlock(), createBlock(resolveDynamicComponent(config.component), mergeProps({
|
|
9688
|
+
key: 0,
|
|
9689
|
+
ref_for: true
|
|
9690
|
+
}, config.props || {}, toHandlers(config?.listeners || {})), createSlots({ _: 2 }, [
|
|
9616
9691
|
config.$key === "component-list" || config.slots?.componentListPanelHeader ? {
|
|
9617
9692
|
name: "component-list-panel-header",
|
|
9618
9693
|
fn: withCtx(() => [
|
|
@@ -9745,7 +9820,10 @@ const _sfc_main$a = /* @__PURE__ */ defineComponent({
|
|
|
9745
9820
|
}, {
|
|
9746
9821
|
body: withCtx(() => [
|
|
9747
9822
|
createElementVNode("div", _hoisted_5$1, [
|
|
9748
|
-
config && unref(floatBoxStates)[config.$key].status ? (openBlock(), createBlock(resolveDynamicComponent(config.component), mergeProps({
|
|
9823
|
+
config && unref(floatBoxStates)[config.$key].status ? (openBlock(), createBlock(resolveDynamicComponent(config.component), mergeProps({
|
|
9824
|
+
key: 0,
|
|
9825
|
+
ref_for: true
|
|
9826
|
+
}, config.props || {}, toHandlers(config?.listeners || {})), null, 16)) : createCommentVNode("", true)
|
|
9749
9827
|
])
|
|
9750
9828
|
]),
|
|
9751
9829
|
_: 2
|
|
@@ -10566,17 +10644,17 @@ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
|
10566
10644
|
position = "absolute";
|
|
10567
10645
|
top = e.clientY - containerRect.top + scrollTop;
|
|
10568
10646
|
left = e.clientX - containerRect.left + scrollLeft;
|
|
10569
|
-
if (parentEl
|
|
10647
|
+
if (parentEl) {
|
|
10570
10648
|
const { left: parentLeft, top: parentTop } = getOffset(parentEl);
|
|
10571
|
-
left = left -
|
|
10572
|
-
top = top -
|
|
10649
|
+
left = left - parentLeft * zoom.value;
|
|
10650
|
+
top = top - parentTop * zoom.value;
|
|
10573
10651
|
}
|
|
10574
10652
|
}
|
|
10575
10653
|
config.data.style = {
|
|
10576
10654
|
...style,
|
|
10577
10655
|
position,
|
|
10578
|
-
top: top / zoom.value,
|
|
10579
|
-
left: left / zoom.value
|
|
10656
|
+
top: calcValueByFontsize(doc, top / zoom.value),
|
|
10657
|
+
left: calcValueByFontsize(doc, left / zoom.value)
|
|
10580
10658
|
};
|
|
10581
10659
|
config.data.inputEvent = e;
|
|
10582
10660
|
services?.editorService.add(config.data, parent);
|
|
@@ -10707,7 +10785,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
|
10707
10785
|
|
|
10708
10786
|
const canUsePluginMethods$1 = {
|
|
10709
10787
|
async: ["setCodeDslById", "setEditStatus", "setCombineIds", "setUndeleteableList", "deleteCodeDslByIds"],
|
|
10710
|
-
sync: []
|
|
10788
|
+
sync: ["setCodeDslByIdSync"]
|
|
10711
10789
|
};
|
|
10712
10790
|
class CodeBlock extends BaseService {
|
|
10713
10791
|
state = reactive({
|
|
@@ -10718,7 +10796,10 @@ class CodeBlock extends BaseService {
|
|
|
10718
10796
|
paramsColConfig: void 0
|
|
10719
10797
|
});
|
|
10720
10798
|
constructor() {
|
|
10721
|
-
super(
|
|
10799
|
+
super([
|
|
10800
|
+
...canUsePluginMethods$1.async.map((methodName) => ({ name: methodName, isAsync: true })),
|
|
10801
|
+
...canUsePluginMethods$1.sync.map((methodName) => ({ name: methodName, isAsync: false }))
|
|
10802
|
+
]);
|
|
10722
10803
|
}
|
|
10723
10804
|
/**
|
|
10724
10805
|
* 设置活动的代码块dsl数据源
|
|
@@ -10758,17 +10839,29 @@ class CodeBlock extends BaseService {
|
|
|
10758
10839
|
* @returns {void}
|
|
10759
10840
|
*/
|
|
10760
10841
|
async setCodeDslById(id, codeConfig) {
|
|
10842
|
+
this.setCodeDslByIdSync(id, codeConfig, true);
|
|
10843
|
+
}
|
|
10844
|
+
/**
|
|
10845
|
+
* 为了兼容历史原因
|
|
10846
|
+
* 设置代码块ID和代码内容到源dsl
|
|
10847
|
+
* @param {Id} id 代码块id
|
|
10848
|
+
* @param {CodeBlockContent} codeConfig 代码块内容配置信息
|
|
10849
|
+
* @param {boolean} force 是否强制写入,默认true
|
|
10850
|
+
* @returns {void}
|
|
10851
|
+
*/
|
|
10852
|
+
setCodeDslByIdSync(id, codeConfig, force = true) {
|
|
10761
10853
|
const codeDsl = this.getCodeDsl();
|
|
10762
10854
|
if (!codeDsl) {
|
|
10763
10855
|
throw new Error("dsl中没有codeBlocks");
|
|
10764
10856
|
}
|
|
10765
|
-
|
|
10766
|
-
|
|
10857
|
+
if (codeDsl[id] && !force)
|
|
10858
|
+
return;
|
|
10859
|
+
const codeConfigProcessed = cloneDeep(codeConfig);
|
|
10860
|
+
if (codeConfigProcessed.content) {
|
|
10767
10861
|
const parseDSL = getConfig("parseDSL");
|
|
10768
|
-
if (typeof
|
|
10769
|
-
|
|
10862
|
+
if (typeof codeConfigProcessed.content === "string") {
|
|
10863
|
+
codeConfigProcessed.content = parseDSL(codeConfigProcessed.content);
|
|
10770
10864
|
}
|
|
10771
|
-
codeConfigProcessed.content = codeConfig.content;
|
|
10772
10865
|
}
|
|
10773
10866
|
const existContent = codeDsl[id] || {};
|
|
10774
10867
|
codeDsl[id] = {
|
|
@@ -10880,6 +10973,51 @@ class CodeBlock extends BaseService {
|
|
|
10880
10973
|
return newId;
|
|
10881
10974
|
return await this.getUniqueId();
|
|
10882
10975
|
}
|
|
10976
|
+
/**
|
|
10977
|
+
* 复制时会带上组件关联的代码块
|
|
10978
|
+
* @param config 组件节点配置
|
|
10979
|
+
* @returns
|
|
10980
|
+
*/
|
|
10981
|
+
copyWithRelated(config) {
|
|
10982
|
+
const copyNodes = Array.isArray(config) ? config : [config];
|
|
10983
|
+
depService.clearByType(DepTargetType.RELATED_CODE_WHEN_COPY);
|
|
10984
|
+
depService.collect(copyNodes, true, DepTargetType.RELATED_CODE_WHEN_COPY);
|
|
10985
|
+
const customTarget = depService.getTarget(
|
|
10986
|
+
DepTargetType.RELATED_CODE_WHEN_COPY,
|
|
10987
|
+
DepTargetType.RELATED_CODE_WHEN_COPY
|
|
10988
|
+
);
|
|
10989
|
+
const copyData = {};
|
|
10990
|
+
if (customTarget) {
|
|
10991
|
+
Object.keys(customTarget.deps).forEach((nodeId) => {
|
|
10992
|
+
const node = editorService.getNodeById(nodeId);
|
|
10993
|
+
if (!node)
|
|
10994
|
+
return;
|
|
10995
|
+
customTarget.deps[nodeId].keys.forEach((key) => {
|
|
10996
|
+
const relateCodeId = get(node, key);
|
|
10997
|
+
const isExist = Object.keys(copyData).find((codeId) => codeId === relateCodeId);
|
|
10998
|
+
if (!isExist) {
|
|
10999
|
+
const relateCode = this.getCodeContentById(relateCodeId);
|
|
11000
|
+
if (relateCode) {
|
|
11001
|
+
copyData[relateCodeId] = relateCode;
|
|
11002
|
+
}
|
|
11003
|
+
}
|
|
11004
|
+
});
|
|
11005
|
+
});
|
|
11006
|
+
}
|
|
11007
|
+
storageService.setItem(COPY_CODE_STORAGE_KEY, copyData, {
|
|
11008
|
+
protocol: Protocol.OBJECT
|
|
11009
|
+
});
|
|
11010
|
+
}
|
|
11011
|
+
/**
|
|
11012
|
+
* 粘贴代码块
|
|
11013
|
+
* @returns
|
|
11014
|
+
*/
|
|
11015
|
+
paste() {
|
|
11016
|
+
const codeDsl = storageService.getItem(COPY_CODE_STORAGE_KEY);
|
|
11017
|
+
Object.keys(codeDsl).forEach((codeId) => {
|
|
11018
|
+
this.setCodeDslByIdSync(codeId, codeDsl[codeId], false);
|
|
11019
|
+
});
|
|
11020
|
+
}
|
|
10883
11021
|
resetState() {
|
|
10884
11022
|
this.state.codeDsl = null;
|
|
10885
11023
|
this.state.editable = true;
|
|
@@ -11221,6 +11359,7 @@ class StageOverlay extends BaseService {
|
|
|
11221
11359
|
createStage(stageOptions = {}) {
|
|
11222
11360
|
return useStage({
|
|
11223
11361
|
...stageOptions,
|
|
11362
|
+
zoom: 1,
|
|
11224
11363
|
runtimeUrl: "",
|
|
11225
11364
|
autoScrollIntoView: false,
|
|
11226
11365
|
render: async (stage) => {
|
|
@@ -11650,7 +11789,17 @@ const initServiceEvents = (props, emit, { editorService, codeBlockService, dataS
|
|
|
11650
11789
|
dataSourceService.on("update", dataSourceUpdateHandler);
|
|
11651
11790
|
dataSourceService.on("remove", dataSourceRemoveHandler);
|
|
11652
11791
|
if (props.collectorOptions && !depService.hasTarget(DepTargetType.RELATED_COMP_WHEN_COPY)) {
|
|
11653
|
-
depService.addTarget(
|
|
11792
|
+
depService.addTarget(createRelatedTargetForCopy(props.collectorOptions, DepTargetType.RELATED_COMP_WHEN_COPY));
|
|
11793
|
+
}
|
|
11794
|
+
if (props.collectorOptionsForCode && !depService.hasTarget(DepTargetType.RELATED_CODE_WHEN_COPY)) {
|
|
11795
|
+
depService.addTarget(
|
|
11796
|
+
createRelatedTargetForCopy(props.collectorOptionsForCode, DepTargetType.RELATED_CODE_WHEN_COPY)
|
|
11797
|
+
);
|
|
11798
|
+
}
|
|
11799
|
+
if (props.collectorOptionsForDataSource && !depService.hasTarget(DepTargetType.RELATED_DS_WHEN_COPY)) {
|
|
11800
|
+
depService.addTarget(
|
|
11801
|
+
createRelatedTargetForCopy(props.collectorOptionsForDataSource, DepTargetType.RELATED_DS_WHEN_COPY)
|
|
11802
|
+
);
|
|
11654
11803
|
}
|
|
11655
11804
|
onBeforeUnmount(() => {
|
|
11656
11805
|
depService.off("add-target", targetAddHandler);
|
|
@@ -11701,6 +11850,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
11701
11850
|
codeOptions: {},
|
|
11702
11851
|
disabledDragStart: { type: Boolean },
|
|
11703
11852
|
collectorOptions: {},
|
|
11853
|
+
collectorOptionsForCode: {},
|
|
11854
|
+
collectorOptionsForDataSource: {},
|
|
11704
11855
|
guidesOptions: {},
|
|
11705
11856
|
disabledMultiSelect: { type: Boolean },
|
|
11706
11857
|
disabledPageFragment: { type: Boolean },
|
|
@@ -11906,4 +12057,4 @@ const index = {
|
|
|
11906
12057
|
}
|
|
11907
12058
|
};
|
|
11908
12059
|
|
|
11909
|
-
export { CODE_DRAFT_STORAGE_KEY, COPY_STORAGE_KEY, _sfc_main$J as CodeBlockEditor, _sfc_main$l as CodeBlockList, _sfc_main$k as CodeBlockListPanel, CodeDeleteErrorType, _sfc_main$Q as CodeSelect, _sfc_main$O as CodeSelectCol, ColumnLayout, _sfc_main$b as ComponentListPanel, _sfc_main$g as ContentMenu, _sfc_main$j as DataSourceConfigPanel, _sfc_main$L as DataSourceFieldSelect, _sfc_main$M as DataSourceFields, _sfc_main$K as DataSourceInput, _sfc_main$H as DataSourceMethodSelect, _sfc_main$I as DataSourceMethods, _sfc_main$G as DataSourceMocks, _sfc_main$F as DataSourceSelect, DragType, _sfc_main$E as EventSelect, Fixed2Other, H_GUIDE_LINE_STORAGE_KEY, _sfc_main$U as Icon, KeyBindingCommand, _sfc_main$C as KeyValue, Keys, LayerOffset, _sfc_main$c as LayerPanel, Layout, _sfc_main$y as LayoutContainer, _sfc_main$B as PageFragmentSelect, _sfc_main$p as PropsPanel, _sfc_main$z as Resizer, SideItemKey, _sfc_main$y as SplitView, _sfc_main$T as TMagicCodeEditor, _sfc_main as TMagicEditor, _sfc_main$x as ToolButton, UI_SELECT_MODE_EVENT_NAME, V_GUIDE_LINE_STORAGE_KEY, advancedTabConfig, beforePaste, change2Fixed, codeBlockService, dataSourceService, debug, index as default, depService, displayTabConfig, editorService, error, eventTabConfig, eventsService, fillConfig, fixNodeLeft, fixNodePosition, generatePageName, generatePageNameByApp, getAddParent, getConfig, getDefaultConfig, getDisplayField, getFormConfig, getFormValue, getGuideLineFromCache, getInitPositionStyle, getNodeIndex, getPageFragmentList, getPageList, getPageNameList, getPositionInContainer, getRelativeStyle, historyService, info, isFixed, log, propsService, serializeConfig, setChildrenLayout, setConfig, setLayout, stageOverlayService, storageService, styleTabConfig, traverseNode, uiService, useCodeBlockEdit, useDataSourceMethod, useEditorContentHeight, useFloatBox, useStage, useWindowRect, warn };
|
|
12060
|
+
export { CODE_DRAFT_STORAGE_KEY, COPY_CODE_STORAGE_KEY, COPY_DS_STORAGE_KEY, COPY_STORAGE_KEY, _sfc_main$J as CodeBlockEditor, _sfc_main$l as CodeBlockList, _sfc_main$k as CodeBlockListPanel, CodeDeleteErrorType, _sfc_main$Q as CodeSelect, _sfc_main$O as CodeSelectCol, ColumnLayout, _sfc_main$b as ComponentListPanel, _sfc_main$g as ContentMenu, _sfc_main$j as DataSourceConfigPanel, _sfc_main$L as DataSourceFieldSelect, _sfc_main$M as DataSourceFields, _sfc_main$K as DataSourceInput, _sfc_main$H as DataSourceMethodSelect, _sfc_main$I as DataSourceMethods, _sfc_main$G as DataSourceMocks, _sfc_main$F as DataSourceSelect, DragType, _sfc_main$E as EventSelect, Fixed2Other, _sfc_main$N as FloatingBox, H_GUIDE_LINE_STORAGE_KEY, _sfc_main$U as Icon, KeyBindingCommand, _sfc_main$C as KeyValue, Keys, LayerOffset, _sfc_main$c as LayerPanel, Layout, _sfc_main$y as LayoutContainer, _sfc_main$B as PageFragmentSelect, _sfc_main$p as PropsPanel, _sfc_main$z as Resizer, SideItemKey, _sfc_main$y as SplitView, _sfc_main$T as TMagicCodeEditor, _sfc_main as TMagicEditor, _sfc_main$x as ToolButton, UI_SELECT_MODE_EVENT_NAME, V_GUIDE_LINE_STORAGE_KEY, advancedTabConfig, beforePaste, change2Fixed, codeBlockService, dataSourceService, debug, index as default, depService, displayTabConfig, editorService, error, eventTabConfig, eventsService, fillConfig, fixNodeLeft, fixNodePosition, generatePageName, generatePageNameByApp, getAddParent, getCascaderOptionsFromFields, getConfig, getDefaultConfig, getDisplayField, getFormConfig, getFormValue, getGuideLineFromCache, getInitPositionStyle, getNodeIndex, getPageFragmentList, getPageList, getPageNameList, getPositionInContainer, getRelativeStyle, historyService, info, isFixed, log, propsService, serializeConfig, setChildrenLayout, setConfig, setLayout, stageOverlayService, storageService, styleTabConfig, traverseNode, uiService, useCodeBlockEdit, useDataSourceMethod, useEditorContentHeight, useFloatBox, useStage, useWindowRect, warn };
|