@tmagic/editor 1.3.0-alpha.9 → 1.3.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/dist/style.css +106 -219
  2. package/dist/tmagic-editor.js +6253 -5042
  3. package/dist/tmagic-editor.js.map +1 -1
  4. package/dist/tmagic-editor.umd.cjs +6280 -5055
  5. package/dist/tmagic-editor.umd.cjs.map +1 -1
  6. package/package.json +15 -15
  7. package/src/Editor.vue +4 -5
  8. package/src/components/CodeBlockEditor.vue +266 -0
  9. package/src/components/CodeParams.vue +60 -0
  10. package/src/components/ContentMenu.vue +97 -43
  11. package/src/components/Resizer.vue +8 -30
  12. package/src/components/SplitView.vue +3 -2
  13. package/src/editorProps.ts +30 -5
  14. package/src/fields/Code.vue +23 -19
  15. package/src/fields/CodeLink.vue +6 -7
  16. package/src/fields/CodeSelect.vue +12 -9
  17. package/src/fields/CodeSelectCol.vue +70 -81
  18. package/src/fields/DataSourceFieldSelect.vue +47 -0
  19. package/src/fields/DataSourceFields.vue +38 -22
  20. package/src/fields/DataSourceInput.vue +21 -58
  21. package/src/fields/DataSourceMethodSelect.vue +136 -0
  22. package/src/fields/DataSourceMethods.vue +104 -0
  23. package/src/fields/DataSourceSelect.vue +5 -12
  24. package/src/fields/EventSelect.vue +53 -19
  25. package/src/fields/KeyValue.vue +9 -11
  26. package/src/fields/UISelect.vue +54 -14
  27. package/src/hooks/index.ts +21 -0
  28. package/src/hooks/use-code-block-edit.ts +84 -0
  29. package/src/hooks/use-data-source-method.ts +100 -0
  30. package/src/hooks/use-getso.ts +35 -0
  31. package/src/{utils/stage.ts → hooks/use-stage.ts} +4 -7
  32. package/src/icons/CenterIcon.vue +13 -0
  33. package/src/icons/CodeIcon.vue +0 -2
  34. package/src/icons/FolderMinusIcon.vue +22 -0
  35. package/src/icons/PinIcon.vue +25 -0
  36. package/src/icons/PinnedIcon.vue +25 -0
  37. package/src/index.ts +14 -0
  38. package/src/initService.ts +69 -16
  39. package/src/layouts/CodeEditor.vue +35 -3
  40. package/src/layouts/Framework.vue +7 -3
  41. package/src/layouts/PropsPanel.vue +8 -3
  42. package/src/layouts/sidebar/ComponentListPanel.vue +4 -6
  43. package/src/layouts/sidebar/LayerMenu.vue +20 -21
  44. package/src/layouts/sidebar/LayerPanel.vue +12 -2
  45. package/src/layouts/sidebar/Sidebar.vue +22 -36
  46. package/src/layouts/sidebar/code-block/CodeBlockList.vue +81 -119
  47. package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +64 -0
  48. package/src/layouts/sidebar/data-source/DataSourceConfigPanel.vue +27 -47
  49. package/src/layouts/sidebar/data-source/DataSourceList.vue +145 -0
  50. package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +58 -85
  51. package/src/layouts/workspace/Workspace.vue +1 -1
  52. package/src/layouts/workspace/viewer/NodeListMenu.vue +159 -0
  53. package/src/layouts/workspace/viewer/NodeListMenuTitle.vue +68 -0
  54. package/src/layouts/workspace/{Stage.vue → viewer/Stage.vue} +5 -2
  55. package/src/layouts/workspace/{ViewerMenu.vue → viewer/ViewerMenu.vue} +10 -35
  56. package/src/services/codeBlock.ts +18 -71
  57. package/src/services/dataSource.ts +16 -1
  58. package/src/services/dep.ts +22 -20
  59. package/src/services/editor.ts +46 -18
  60. package/src/services/props.ts +2 -2
  61. package/src/theme/code-block.scss +5 -117
  62. package/src/theme/code-editor.scss +27 -2
  63. package/src/theme/content-menu.scss +26 -2
  64. package/src/theme/data-source-methods.scss +13 -0
  65. package/src/theme/data-source.scss +11 -0
  66. package/src/theme/event.scss +15 -12
  67. package/src/theme/framework.scss +0 -3
  68. package/src/theme/index.scss +8 -0
  69. package/src/theme/layout.scss +4 -0
  70. package/src/theme/sidebar.scss +18 -60
  71. package/src/theme/theme.scss +1 -0
  72. package/src/type.ts +49 -7
  73. package/src/utils/content-menu.ts +92 -0
  74. package/src/utils/data-source/formConfigs/base.ts +28 -30
  75. package/src/utils/data-source/formConfigs/http.ts +9 -0
  76. package/src/utils/data-source/index.ts +65 -2
  77. package/src/utils/dep.ts +33 -7
  78. package/src/utils/index.ts +1 -1
  79. package/src/utils/props.ts +308 -189
  80. package/src/utils/undo-redo.ts +1 -1
  81. package/types/Editor.vue.d.ts +30 -6
  82. package/types/components/CodeBlockEditor.vue.d.ts +25 -0
  83. package/types/components/CodeParams.vue.d.ts +26 -0
  84. package/types/components/ContentMenu.vue.d.ts +27 -8
  85. package/types/components/Resizer.vue.d.ts +1 -3
  86. package/types/components/ToolButton.vue.d.ts +3 -3
  87. package/types/editorProps.d.ts +19 -5
  88. package/types/fields/Code.vue.d.ts +24 -19
  89. package/types/fields/CodeLink.vue.d.ts +12 -21
  90. package/types/fields/CodeSelect.vue.d.ts +6 -17
  91. package/types/fields/CodeSelectCol.vue.d.ts +10 -14
  92. package/types/fields/DataSourceFieldSelect.vue.d.ts +29 -0
  93. package/types/fields/DataSourceFields.vue.d.ts +7 -18
  94. package/types/fields/DataSourceInput.vue.d.ts +10 -30
  95. package/types/fields/DataSourceMethodSelect.vue.d.ts +29 -0
  96. package/types/fields/DataSourceMethods.vue.d.ts +32 -0
  97. package/types/fields/DataSourceSelect.vue.d.ts +13 -29
  98. package/types/fields/EventSelect.vue.d.ts +2 -13
  99. package/types/fields/KeyValue.vue.d.ts +9 -24
  100. package/types/fields/UISelect.vue.d.ts +2 -11
  101. package/types/hooks/index.d.ts +3 -0
  102. package/types/{components/FunctionEditor.vue.d.ts → hooks/use-code-block-edit.d.ts} +36 -119
  103. package/types/hooks/use-data-source-method.d.ts +130 -0
  104. package/types/hooks/use-getso.d.ts +5 -0
  105. package/types/icons/CenterIcon.vue.d.ts +2 -0
  106. package/types/icons/FolderMinusIcon.vue.d.ts +2 -0
  107. package/types/icons/PinIcon.vue.d.ts +2 -0
  108. package/types/icons/PinnedIcon.vue.d.ts +2 -0
  109. package/types/index.d.ts +7 -0
  110. package/types/initService.d.ts +2 -2
  111. package/types/layouts/CodeEditor.vue.d.ts +7 -4
  112. package/types/layouts/PropsPanel.vue.d.ts +274 -2
  113. package/types/layouts/sidebar/Sidebar.vue.d.ts +0 -3
  114. package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +4 -9
  115. package/types/layouts/sidebar/code-block/{CodeBlockEditor.vue.d.ts → CodeBlockListPanel.vue.d.ts} +9 -5
  116. package/types/layouts/sidebar/data-source/DataSourceConfigPanel.vue.d.ts +3 -1
  117. package/types/layouts/sidebar/data-source/DataSourceList.vue.d.ts +14 -0
  118. package/types/layouts/sidebar/data-source/DataSourceListPanel.vue.d.ts +1 -11
  119. package/types/layouts/workspace/viewer/NodeListMenu.vue.d.ts +15 -0
  120. package/types/layouts/workspace/viewer/NodeListMenuTitle.vue.d.ts +15 -0
  121. package/types/layouts/workspace/{Stage.vue.d.ts → viewer/Stage.vue.d.ts} +1 -1
  122. package/types/layouts/workspace/{ViewerMenu.vue.d.ts → viewer/ViewerMenu.vue.d.ts} +1 -1
  123. package/types/services/codeBlock.d.ts +6 -37
  124. package/types/services/dataSource.d.ts +7 -1
  125. package/types/services/dep.d.ts +12 -21
  126. package/types/services/editor.d.ts +1 -1
  127. package/types/services/props.d.ts +10 -115
  128. package/types/type.d.ts +44 -7
  129. package/types/utils/content-menu.d.ts +7 -0
  130. package/types/utils/data-source/formConfigs/base.d.ts +1 -2
  131. package/types/utils/data-source/index.d.ts +5 -0
  132. package/types/utils/dep.d.ts +4 -2
  133. package/types/utils/index.d.ts +1 -1
  134. package/types/utils/props.d.ts +13 -102
  135. package/src/components/CodeDraftEditor.vue +0 -148
  136. package/src/components/FunctionEditor.vue +0 -197
  137. package/src/layouts/sidebar/code-block/CodeBlockEditor.vue +0 -100
  138. package/types/components/CodeDraftEditor.vue.d.ts +0 -61
  139. /package/types/{utils/stage.d.ts → hooks/use-stage.d.ts} +0 -0
@@ -7,120 +7,15 @@ declare class Props extends BaseService {
7
7
  setPropsConfigs(configs: Record<string, FormConfig>): void;
8
8
  fillConfig(config: FormConfig): Promise<{
9
9
  type: string;
10
- items: ({
10
+ items: {
11
+ [x: string]: any;
12
+ status?: string | undefined;
11
13
  title: string;
12
- labelWidth: string;
13
- items: import("@tmagic/form").ChildConfig[];
14
- lazy?: undefined;
15
- } | {
16
- title: string;
17
- labelWidth: string;
18
- items: {
19
- name: string;
20
- items: ({
21
- type: string;
22
- legend: string;
23
- items: ({
24
- name: string;
25
- type: string;
26
- activeValue: string; /**
27
- * 为指定类型组件设置组件属性表单配置
28
- * @param type 组件类型
29
- * @param config 组件属性表单配置
30
- */
31
- inactiveValue: string;
32
- defaultValue: string;
33
- text: string;
34
- disabled?: undefined;
35
- } | {
36
- name: string;
37
- text: string;
38
- type?: undefined;
39
- activeValue?: undefined; /**
40
- * 为指定类型组件设置组件属性表单配置
41
- * @param type 组件类型
42
- * @param config 组件属性表单配置
43
- */
44
- inactiveValue?: undefined;
45
- defaultValue?: undefined;
46
- disabled?: undefined;
47
- } | {
48
- name: string;
49
- text: string;
50
- disabled: (vm: import("@tmagic/form").FormState, { model }: any) => boolean;
51
- type?: undefined;
52
- activeValue?: undefined; /**
53
- * 为指定类型组件设置组件属性表单配置
54
- * @param type 组件类型
55
- * @param config 组件属性表单配置
56
- */
57
- inactiveValue?: undefined;
58
- defaultValue?: undefined;
59
- })[];
60
- name?: undefined;
61
- } | {
62
- type: string;
63
- legend: string;
64
- items: ({
65
- name: string;
66
- text: string;
67
- type?: undefined;
68
- defaultValue?: undefined;
69
- options?: undefined;
70
- } | {
71
- name: string;
72
- text: string;
73
- type: string;
74
- defaultValue?: undefined;
75
- options?: undefined;
76
- } | {
77
- name: string;
78
- text: string;
79
- type: string;
80
- defaultValue: string;
81
- options: {
82
- text: string;
83
- value: string;
84
- }[];
85
- } | {
86
- name: string;
87
- text: string;
88
- defaultValue: string;
89
- type?: undefined;
90
- options?: undefined;
91
- })[];
92
- name?: undefined;
93
- } | {
94
- type: string;
95
- legend: string;
96
- name: string;
97
- items: {
98
- name: string;
99
- text: string;
100
- }[];
101
- })[];
102
- }[];
103
- lazy?: undefined;
104
- } | {
105
- title: string;
106
- items: {
107
- name: string;
108
- type: string;
109
- labelWidth: number;
110
- }[];
111
- labelWidth?: undefined;
112
- lazy?: undefined;
113
- } | {
114
- title: string;
115
- lazy: boolean;
116
- items: {
117
- name: string;
118
- text: string;
119
- labelWidth: string;
120
- type: string;
121
- }[];
122
- labelWidth?: undefined;
123
- })[];
14
+ lazy?: boolean | undefined;
15
+ labelWidth?: string | undefined;
16
+ items: FormConfig;
17
+ onTabClick?: ((mForm: import("@tmagic/form").FormState | undefined, tab: any, data: any) => void) | undefined;
18
+ }[];
124
19
  }[]>;
125
20
  /**
126
21
  * 为指定类型组件设置组件属性表单配置
@@ -134,13 +29,13 @@ declare class Props extends BaseService {
134
29
  * @returns 组件属性表单配置
135
30
  */
136
31
  getPropsConfig(type: string): Promise<FormConfig>;
137
- setPropsValues(values: Record<string, MNode>): void;
32
+ setPropsValues(values: Record<string, Partial<MNode>>): void;
138
33
  /**
139
34
  * 为指点类型组件设置组件初始值
140
35
  * @param type 组件类型
141
36
  * @param value 组件初始值
142
37
  */
143
- setPropsValue(type: string, value: MNode): Promise<void>;
38
+ setPropsValue(type: string, value: Partial<MNode>): Promise<void>;
144
39
  /**
145
40
  * 获取指定类型的组件初始值
146
41
  * @param type 组件类型
package/types/type.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { Component } from 'vue';
2
- import type { FormConfig, FormItem } from '@tmagic/form';
2
+ import type { ColumnConfig, FilterFunction, FormConfig, FormItem } from '@tmagic/form';
3
3
  import type { CodeBlockContent, CodeBlockDSL, Id, MApp, MContainer, MNode, MPage } from '@tmagic/schema';
4
4
  import type StageCore from '@tmagic/stage';
5
5
  import type { ContainerHighlightType, CustomizeMoveableOptionsCallbackConfig, MoveableOptions, UpdateDragEl } from '@tmagic/stage';
@@ -18,7 +18,7 @@ import type { UndoRedo } from './utils/undo-redo';
18
18
  export type BeforeAdd = (config: MNode, parent: MContainer) => Promise<MNode> | MNode;
19
19
  export type GetConfig = (config: FormConfig) => Promise<FormConfig> | FormConfig;
20
20
  export interface InstallOptions {
21
- parseDSL: (dsl: string) => MApp;
21
+ parseDSL: <T = any>(dsl: string) => T;
22
22
  [key: string]: any;
23
23
  }
24
24
  export interface Services {
@@ -61,7 +61,7 @@ export interface StoreState {
61
61
  export type StoreStateKey = keyof StoreState;
62
62
  export interface PropsState {
63
63
  propsConfigMap: Record<string, FormConfig>;
64
- propsValueMap: Record<string, MNode>;
64
+ propsValueMap: Record<string, Partial<MNode>>;
65
65
  }
66
66
  export interface ComponentGroupState {
67
67
  list: ComponentGroup[];
@@ -159,6 +159,8 @@ export interface MenuButton {
159
159
  className?: string;
160
160
  /** type为dropdown时,下拉的菜单列表, 或者有子菜单时 */
161
161
  items?: MenuButton[];
162
+ /** 唯一标识,用于高亮 */
163
+ id?: string | number;
162
164
  }
163
165
  export interface MenuComponent {
164
166
  type: 'component';
@@ -263,18 +265,15 @@ export interface ScrollViewerEvent {
263
265
  scrollWidth: number;
264
266
  }
265
267
  export type CodeState = {
266
- /** 是否展示代码块编辑区 */
267
- isShowCodeEditor: boolean;
268
268
  /** 代码块DSL数据源 */
269
269
  codeDsl: CodeBlockDSL | null;
270
- /** 当前选中的代码块id */
271
- id: Id;
272
270
  /** 代码块是否可编辑 */
273
271
  editable: boolean;
274
272
  /** list模式下左侧展示的代码列表 */
275
273
  combineIds: string[];
276
274
  /** 为业务逻辑预留的不可删除的代码块列表,由业务逻辑维护(如代码块上线后不可删除) */
277
275
  undeletableList: Id[];
276
+ paramsColConfig?: ColumnConfig;
278
277
  };
279
278
  export type HookData = {
280
279
  /** 代码块id */
@@ -346,6 +345,8 @@ export interface EventSelectConfig {
346
345
  compActionConfig?: FormItem;
347
346
  /** 联动代码配置 */
348
347
  codeActionConfig?: FormItem;
348
+ /** 联动数据源配置 */
349
+ dataSourceActionConfig?: FormItem;
349
350
  }
350
351
  export declare enum KeyBindingCommand {
351
352
  /** 复制 */
@@ -399,3 +400,39 @@ export interface KeyBindingCacheItem {
399
400
  eventType: 'keyup' | 'keydown';
400
401
  binded: boolean;
401
402
  }
403
+ export interface CodeSelectColConfig {
404
+ type: 'code-select-col';
405
+ name: string;
406
+ labelWidth?: number | string;
407
+ disabled?: boolean | FilterFunction;
408
+ display?: boolean | FilterFunction;
409
+ }
410
+ export interface DataSourceMethodSelectConfig {
411
+ type: 'data-source-method-select';
412
+ name: string;
413
+ labelWidth?: number | string;
414
+ disabled?: boolean | FilterFunction;
415
+ display?: boolean | FilterFunction;
416
+ }
417
+ export interface DataSourceFieldSelectConfig {
418
+ type: 'data-source-field-select';
419
+ name: string;
420
+ labelWidth?: number | string;
421
+ disabled?: boolean | FilterFunction;
422
+ display?: boolean | FilterFunction;
423
+ }
424
+ export declare enum DepTargetType {
425
+ DEFAULT = "default",
426
+ /** 代码块 */
427
+ CODE_BLOCK = "code-block",
428
+ /** 数据源 */
429
+ DATA_SOURCE = "data-source",
430
+ /** 数据源方法 */
431
+ DATA_SOURCE_METHOD = "data-source-method",
432
+ /** 数据源条件 */
433
+ DATA_SOURCE_COND = "data-source-cond"
434
+ }
435
+ export interface DatasourceTypeOption {
436
+ type: string;
437
+ text: string;
438
+ }
@@ -0,0 +1,7 @@
1
+ import { Ref } from 'vue';
2
+ import ContentMenu from '../components/ContentMenu.vue';
3
+ import type { MenuButton, Services } from '../type';
4
+ export declare const useDeleteMenu: () => MenuButton;
5
+ export declare const useCopyMenu: () => MenuButton;
6
+ export declare const usePasteMenu: (menu?: Ref<InstanceType<typeof ContentMenu> | undefined>) => MenuButton;
7
+ export declare const useMoveToMenu: (services?: Services) => MenuButton;
@@ -1,3 +1,2 @@
1
1
  import type { FormConfig } from '@tmagic/form';
2
- declare const _default: FormConfig;
3
- export default _default;
2
+ export default function (): FormConfig;
@@ -1,2 +1,7 @@
1
1
  import { FormConfig } from '@tmagic/form';
2
+ import { DataSourceSchema } from '@tmagic/schema';
2
3
  export declare const getFormConfig: (type: string, configs: Record<string, FormConfig>) => FormConfig;
4
+ export declare const getDisplayField: (dataSources: DataSourceSchema[], key: string) => {
5
+ value: string;
6
+ type: 'var' | 'text';
7
+ }[];
@@ -1,4 +1,6 @@
1
- import { CodeBlockContent, DataSourceSchema, Id } from '@tmagic/schema';
1
+ import { CodeBlockContent, Id } from '@tmagic/schema';
2
2
  import { Target } from '../services/dep';
3
3
  export declare const createCodeBlockTarget: (id: Id, codeBlock: CodeBlockContent) => Target;
4
- export declare const createDataSourceTarget: (id: Id, ds: DataSourceSchema) => Target;
4
+ export declare const createDataSourceTarget: (id: Id) => Target;
5
+ export declare const createDataSourceCondTarget: (id: string) => Target;
6
+ export declare const createDataSourceMethodTarget: (id: string) => Target;
@@ -2,5 +2,5 @@ export * from './config';
2
2
  export * from './props';
3
3
  export * from './logger';
4
4
  export * from './editor';
5
- export * from './stage';
6
5
  export * from './operator';
6
+ export * from './data-source';
@@ -1,4 +1,8 @@
1
- import { FormConfig, FormState } from '@tmagic/form';
1
+ import type { FormConfig, FormState, TabPaneConfig } from '@tmagic/form';
2
+ export declare const styleTabConfig: TabPaneConfig;
3
+ export declare const eventTabConfig: TabPaneConfig;
4
+ export declare const advancedTabConfig: TabPaneConfig;
5
+ export declare const displayTabConfig: TabPaneConfig;
2
6
  /**
3
7
  * 统一为组件属性表单加上事件、高级、样式配置
4
8
  * @param config 组件属性配置
@@ -6,106 +10,13 @@ import { FormConfig, FormState } from '@tmagic/form';
6
10
  */
7
11
  export declare const fillConfig: (config?: FormConfig) => {
8
12
  type: string;
9
- items: ({
13
+ items: {
14
+ [x: string]: any;
15
+ status?: string | undefined;
10
16
  title: string;
11
- labelWidth: string;
12
- items: import("@tmagic/form").ChildConfig[];
13
- lazy?: undefined;
14
- } | {
15
- title: string;
16
- labelWidth: string;
17
- items: {
18
- name: string;
19
- items: ({
20
- type: string;
21
- legend: string;
22
- items: ({
23
- name: string;
24
- type: string;
25
- activeValue: string;
26
- inactiveValue: string;
27
- defaultValue: string;
28
- text: string;
29
- disabled?: undefined;
30
- } | {
31
- name: string;
32
- text: string;
33
- type?: undefined;
34
- activeValue?: undefined;
35
- inactiveValue?: undefined;
36
- defaultValue?: undefined;
37
- disabled?: undefined;
38
- } | {
39
- name: string;
40
- text: string;
41
- disabled: (vm: FormState, { model }: any) => boolean;
42
- type?: undefined;
43
- activeValue?: undefined;
44
- inactiveValue?: undefined;
45
- defaultValue?: undefined;
46
- })[];
47
- name?: undefined;
48
- } | {
49
- type: string;
50
- legend: string;
51
- items: ({
52
- name: string;
53
- text: string;
54
- type?: undefined;
55
- defaultValue?: undefined;
56
- options?: undefined;
57
- } | {
58
- name: string;
59
- text: string;
60
- type: string;
61
- defaultValue?: undefined;
62
- options?: undefined;
63
- } | {
64
- name: string;
65
- text: string;
66
- type: string;
67
- defaultValue: string;
68
- options: {
69
- text: string;
70
- value: string;
71
- }[];
72
- } | {
73
- name: string;
74
- text: string;
75
- defaultValue: string;
76
- type?: undefined;
77
- options?: undefined;
78
- })[];
79
- name?: undefined;
80
- } | {
81
- type: string;
82
- legend: string;
83
- name: string;
84
- items: {
85
- name: string;
86
- text: string;
87
- }[];
88
- })[];
89
- }[];
90
- lazy?: undefined;
91
- } | {
92
- title: string;
93
- items: {
94
- name: string;
95
- type: string;
96
- labelWidth: number;
97
- }[];
98
- labelWidth?: undefined;
99
- lazy?: undefined;
100
- } | {
101
- title: string;
102
- lazy: boolean;
103
- items: {
104
- name: string;
105
- text: string;
106
- labelWidth: string;
107
- type: string;
108
- }[];
109
- labelWidth?: undefined;
110
- })[];
17
+ lazy?: boolean | undefined;
18
+ labelWidth?: string | undefined;
19
+ items: FormConfig;
20
+ onTabClick?: ((mForm: FormState | undefined, tab: any, data: any) => void) | undefined;
21
+ }[];
111
22
  }[];
@@ -1,148 +0,0 @@
1
- <template>
2
- <div class="m-editor-wrapper" :class="isFullScreen ? 'fullScreen' : 'normal'">
3
- <magic-code-editor
4
- ref="codeEditor"
5
- class="m-editor-container"
6
- :init-values="`${codeContent}`"
7
- @save="saveCodeDraft"
8
- :language="language"
9
- :options="codeOptions"
10
- ></magic-code-editor>
11
- <div class="m-editor-content-bottom" v-if="editable">
12
- <TMagicButton type="primary" class="button" @click="toggleFullScreen">
13
- {{ isFullScreen ? '退出全屏' : '全屏' }}</TMagicButton
14
- >
15
- <TMagicButton type="primary" class="button" @click="saveAndClose">确认</TMagicButton>
16
- <TMagicButton class="button" @click="close">关闭</TMagicButton>
17
- </div>
18
- <div class="m-editor-content-bottom" v-else>
19
- <TMagicButton type="primary" class="button" @click="toggleFullScreen">
20
- {{ isFullScreen ? '退出全屏' : '全屏' }}</TMagicButton
21
- >
22
- <TMagicButton class="button" @click="close">关闭</TMagicButton>
23
- </div>
24
- </div>
25
- </template>
26
- <script lang="ts" setup>
27
- import { computed, inject, ref, watchEffect } from 'vue';
28
- import type * as monaco from 'monaco-editor';
29
-
30
- import { TMagicButton, tMagicMessage, tMagicMessageBox } from '@tmagic/design';
31
- import { Id } from '@tmagic/schema';
32
- import { datetimeFormatter } from '@tmagic/utils';
33
-
34
- import MagicCodeEditor from '@editor/layouts/CodeEditor.vue';
35
- import type { Services } from '@editor/type';
36
-
37
- defineOptions({
38
- name: 'MEditorCodeDraftEditor',
39
- });
40
-
41
- const props = withDefaults(
42
- defineProps<{
43
- /** 代码id */
44
- id: Id;
45
- /** 代码内容 */
46
- content: string;
47
- /** 是否可编辑 */
48
- editable?: boolean;
49
- /** 是否自动保存草稿 */
50
- autoSaveDraft?: boolean;
51
- /** 编辑器参数 */
52
- codeOptions?: Object;
53
- /** 编辑器语言 */
54
- language?: string;
55
- }>(),
56
- {
57
- editable: true,
58
- autoSaveDraft: true,
59
- },
60
- );
61
- const emit = defineEmits(['close', 'saveAndClose']);
62
-
63
- const services = inject<Services>('services');
64
-
65
- const codeContent = ref<string>('');
66
- const editorContent = ref<string>('');
67
- const codeEditor = ref<InstanceType<typeof MagicCodeEditor>>();
68
- // 原始代码内容
69
- const originCodeContent = ref<string>('');
70
- const isFullScreen = ref<boolean>(false);
71
-
72
- const codeOptions = computed(() => ({
73
- ...props.codeOptions,
74
- readOnly: !props.editable,
75
- }));
76
-
77
- watchEffect(() => {
78
- codeContent.value = props.content;
79
- if (!originCodeContent.value) {
80
- // 暂存原始的代码内容
81
- originCodeContent.value = codeContent.value;
82
- }
83
- // 有草稿时展示上次保存的草稿内容
84
- const codeDraft = services?.codeBlockService.getCodeDraft(props.id);
85
- if (codeDraft) {
86
- codeContent.value = codeDraft;
87
- }
88
- });
89
-
90
- // 保存草稿
91
- const saveCodeDraft = async (codeValue: string) => {
92
- if (!props.autoSaveDraft) return;
93
- if (originCodeContent.value === codeValue) {
94
- // 没修改或改回原样 有草稿的话删除草稿
95
- services?.codeBlockService.removeCodeDraft(props.id);
96
- return;
97
- }
98
- services?.codeBlockService.setCodeDraft(props.id, codeValue);
99
- tMagicMessage.success(`代码草稿成功保存到本地 ${datetimeFormatter(new Date())}`);
100
- };
101
-
102
- // 保存并关闭
103
- const saveAndClose = (): void => {
104
- if (!codeEditor.value || !props.editable) return;
105
- // 代码内容
106
- editorContent.value = (codeEditor.value.getEditor() as monaco.editor.IStandaloneCodeEditor)?.getValue();
107
- emit('saveAndClose', editorContent.value);
108
- };
109
-
110
- // 关闭弹窗
111
- const close = async (): Promise<void> => {
112
- const codeDraft = services?.codeBlockService.getCodeDraft(props.id);
113
- if (codeDraft) {
114
- try {
115
- await tMagicMessageBox.confirm('您有代码修改未保存,是否保存后再关闭?', '提示', {
116
- confirmButtonText: '保存并关闭',
117
- cancelButtonText: '直接关闭',
118
- type: 'warning',
119
- distinguishCancelAndClose: true,
120
- });
121
-
122
- // 保存之后再关闭
123
- saveAndClose();
124
- } catch (action: any) {
125
- if (action === 'cancel') {
126
- // 删除草稿 直接关闭
127
- services?.codeBlockService.removeCodeDraft(props.id);
128
- emit('close');
129
- }
130
- }
131
- } else {
132
- emit('close');
133
- }
134
- };
135
-
136
- // 切换全屏
137
- const toggleFullScreen = (): void => {
138
- isFullScreen.value = !isFullScreen.value;
139
- if (codeEditor.value) {
140
- codeEditor.value.focus();
141
- }
142
- };
143
-
144
- defineExpose({
145
- saveAndClose,
146
- close,
147
- });
148
- </script>