@fui-org/fui-cli 2.1.3 → 2.2.0

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 (219) hide show
  1. package/README.md +27 -7
  2. package/dist/fui-qrb1j9jz.js +397 -0
  3. package/dist/fui.js +1 -1
  4. package/package.json +1 -1
  5. package/skills/fui/SKILL.md +143 -38
  6. package/skills/fui/agents/fui-builder.md +62 -0
  7. package/skills/fui/agents/fui-tester.md +77 -0
  8. package/skills/{fui-skill → fui}/assets/projectdefaultstyle.css +489 -489
  9. package/skills/{fui-skill → fui}/examples/component.vue +162 -162
  10. package/skills/{fui-skill → fui}/references/INDEX.md +5 -4
  11. package/skills/{fui-skill → fui}/references/advanced-techniques.md +170 -168
  12. package/skills/{fui-skill → fui}/references/component-design.md +2 -2
  13. package/skills/{fui-skill → fui}/references/component-quickref.md +78 -78
  14. package/skills/{fui-skill → fui}/references/component-table.md +287 -287
  15. package/skills/{fui-skill → fui}/references/components-dialog.md +191 -191
  16. package/skills/{fui-skill → fui}/references/components-display.md +141 -141
  17. package/skills/{fui-skill → fui}/references/components-echart.md +316 -316
  18. package/skills/{fui-skill → fui}/references/components-input.md +335 -335
  19. package/skills/{fui-skill → fui}/references/controls-patterns.md +2 -2
  20. package/skills/{fui-skill → fui}/references/controls-styling-vocabulary.md +173 -173
  21. package/skills/{fui-skill → fui}/references/db-workflow.md +9 -9
  22. package/skills/{fui-skill → fui}/references/default-function.md +456 -456
  23. package/skills/{fui-skill → fui}/references/design-modes.md +57 -57
  24. package/skills/{fui-skill → fui}/references/echart-templates.md +489 -489
  25. package/skills/{fui-skill → fui}/references/fastproject.md +99 -99
  26. package/skills/{fui-skill → fui}/references/fullstack-workflow.md +314 -313
  27. package/skills/{fui-skill → fui}/references/module-data-patterns.md +117 -117
  28. package/skills/{fui-skill → fui}/references/module-json-anatomy.md +132 -132
  29. package/skills/{fui-skill → fui}/references/module-structure.md +144 -144
  30. package/skills/{fui-skill → fui}/references/new-session.md +1 -2
  31. package/skills/{fui-skill → fui}/references/pdfmake.md +60 -60
  32. package/skills/{fui-skill → fui}/references/permission-system.md +1 -1
  33. package/skills/{fui-skill → fui}/references/platform-architecture.md +269 -269
  34. package/skills/{fui-skill → fui}/references/project-config.md +303 -303
  35. package/skills/{fui-skill → fui}/references/project-provisioning.md +4 -4
  36. package/skills/{fui-skill → fui}/references/script-map.md +262 -262
  37. package/skills/{fui-skill → fui}/references/sql-clr-functions.md +225 -225
  38. package/skills/{fui-skill → fui}/references/system-design.md +2 -2
  39. package/skills/{fui-skill → fui}/references/tapi-permission-patterns.md +156 -156
  40. package/skills/{fui-skill → fui}/references/tapi-reference.md +474 -474
  41. package/skills/fui/references/team-run.md +141 -0
  42. package/skills/fui/references/tools-registry.md +211 -0
  43. package/skills/{fui-skill → fui}/references/ui-crosswindow-patterns.md +321 -321
  44. package/skills/{fui-skill → fui}/references/ui-dialog-patterns.md +255 -255
  45. package/skills/{fui-skill → fui}/references/ui-layout-patterns.md +176 -176
  46. package/skills/{fui-skill → fui}/references/ui-patterns.md +303 -303
  47. package/skills/{fui-skill → fui}/references/ui-screenshot-review.md +95 -95
  48. package/skills/{fui-skill → fui}/references/ui-table-cell-patterns.md +318 -318
  49. package/skills/{fui-skill → fui}/references/verification.md +11 -11
  50. package/skills/{fui-skill → fui}/references/watcher-patterns.md +163 -163
  51. package/skills/{fui-skill → fui}/references/websocket-realtime.md +271 -271
  52. package/skills/{fui-skill → fui}/scripts/component-3.0.js +2715 -2715
  53. package/skills/{fui-skill → fui}/scripts/component.js +3147 -3147
  54. package/skills/{fui-skill → fui}/scripts/componentTable-3.0.js +1038 -1038
  55. package/skills/{fui-skill → fui}/scripts/componentTable.js +891 -891
  56. package/skills/{fui-skill → fui}/scripts/defaultfunction-3.0.js +866 -866
  57. package/skills/{fui-skill → fui}/scripts/defaultfunction.js +1051 -1051
  58. package/skills/{fui-skill → fui}/scripts/fastproject-3.0.js +870 -870
  59. package/skills/{fui-skill → fui}/scripts/fastproject.js +828 -828
  60. package/skills/fui-target/hooks/register.tsx +2 -0
  61. package/skills/fui-target/types/index.d.ts +1 -0
  62. package/dist/fui-hk5frcn2.js +0 -381
  63. package/skills/fui-skill/SKILL.md +0 -139
  64. package/skills/fui-skill/references/tools-registry.md +0 -84
  65. /package/skills/{fui-skill → fui}/assets/projectdefaultstyle-3.0.css +0 -0
  66. /package/skills/{fui-skill → fui}/design-md/airbnb/DESIGN.md +0 -0
  67. /package/skills/{fui-skill → fui}/design-md/airbnb/README.md +0 -0
  68. /package/skills/{fui-skill → fui}/design-md/airtable/DESIGN.md +0 -0
  69. /package/skills/{fui-skill → fui}/design-md/airtable/README.md +0 -0
  70. /package/skills/{fui-skill → fui}/design-md/apple/DESIGN.md +0 -0
  71. /package/skills/{fui-skill → fui}/design-md/apple/README.md +0 -0
  72. /package/skills/{fui-skill → fui}/design-md/asu/DESIGN.md +0 -0
  73. /package/skills/{fui-skill → fui}/design-md/asu/README.md +0 -0
  74. /package/skills/{fui-skill → fui}/design-md/binance/DESIGN.md +0 -0
  75. /package/skills/{fui-skill → fui}/design-md/binance/README.md +0 -0
  76. /package/skills/{fui-skill → fui}/design-md/bmw/DESIGN.md +0 -0
  77. /package/skills/{fui-skill → fui}/design-md/bmw/README.md +0 -0
  78. /package/skills/{fui-skill → fui}/design-md/bmw-m/DESIGN.md +0 -0
  79. /package/skills/{fui-skill → fui}/design-md/bmw-m/README.md +0 -0
  80. /package/skills/{fui-skill → fui}/design-md/bugatti/DESIGN.md +0 -0
  81. /package/skills/{fui-skill → fui}/design-md/bugatti/README.md +0 -0
  82. /package/skills/{fui-skill → fui}/design-md/cal/DESIGN.md +0 -0
  83. /package/skills/{fui-skill → fui}/design-md/cal/README.md +0 -0
  84. /package/skills/{fui-skill → fui}/design-md/claude/DESIGN.md +0 -0
  85. /package/skills/{fui-skill → fui}/design-md/claude/README.md +0 -0
  86. /package/skills/{fui-skill → fui}/design-md/clay/DESIGN.md +0 -0
  87. /package/skills/{fui-skill → fui}/design-md/clay/README.md +0 -0
  88. /package/skills/{fui-skill → fui}/design-md/clickhouse/DESIGN.md +0 -0
  89. /package/skills/{fui-skill → fui}/design-md/clickhouse/README.md +0 -0
  90. /package/skills/{fui-skill → fui}/design-md/cohere/DESIGN.md +0 -0
  91. /package/skills/{fui-skill → fui}/design-md/cohere/README.md +0 -0
  92. /package/skills/{fui-skill → fui}/design-md/coinbase/DESIGN.md +0 -0
  93. /package/skills/{fui-skill → fui}/design-md/coinbase/README.md +0 -0
  94. /package/skills/{fui-skill → fui}/design-md/composio/DESIGN.md +0 -0
  95. /package/skills/{fui-skill → fui}/design-md/composio/README.md +0 -0
  96. /package/skills/{fui-skill → fui}/design-md/cursor/DESIGN.md +0 -0
  97. /package/skills/{fui-skill → fui}/design-md/cursor/README.md +0 -0
  98. /package/skills/{fui-skill → fui}/design-md/elevenlabs/DESIGN.md +0 -0
  99. /package/skills/{fui-skill → fui}/design-md/elevenlabs/README.md +0 -0
  100. /package/skills/{fui-skill → fui}/design-md/expo/DESIGN.md +0 -0
  101. /package/skills/{fui-skill → fui}/design-md/expo/README.md +0 -0
  102. /package/skills/{fui-skill → fui}/design-md/ferrari/DESIGN.md +0 -0
  103. /package/skills/{fui-skill → fui}/design-md/ferrari/README.md +0 -0
  104. /package/skills/{fui-skill → fui}/design-md/figma/DESIGN.md +0 -0
  105. /package/skills/{fui-skill → fui}/design-md/figma/README.md +0 -0
  106. /package/skills/{fui-skill → fui}/design-md/framer/DESIGN.md +0 -0
  107. /package/skills/{fui-skill → fui}/design-md/framer/README.md +0 -0
  108. /package/skills/{fui-skill → fui}/design-md/fui/DESIGN.md +0 -0
  109. /package/skills/{fui-skill → fui}/design-md/hashicorp/DESIGN.md +0 -0
  110. /package/skills/{fui-skill → fui}/design-md/hashicorp/README.md +0 -0
  111. /package/skills/{fui-skill → fui}/design-md/ibm/DESIGN.md +0 -0
  112. /package/skills/{fui-skill → fui}/design-md/ibm/README.md +0 -0
  113. /package/skills/{fui-skill → fui}/design-md/intercom/DESIGN.md +0 -0
  114. /package/skills/{fui-skill → fui}/design-md/intercom/README.md +0 -0
  115. /package/skills/{fui-skill → fui}/design-md/kraken/DESIGN.md +0 -0
  116. /package/skills/{fui-skill → fui}/design-md/kraken/README.md +0 -0
  117. /package/skills/{fui-skill → fui}/design-md/lamborghini/DESIGN.md +0 -0
  118. /package/skills/{fui-skill → fui}/design-md/lamborghini/README.md +0 -0
  119. /package/skills/{fui-skill → fui}/design-md/linear.app/DESIGN.md +0 -0
  120. /package/skills/{fui-skill → fui}/design-md/linear.app/README.md +0 -0
  121. /package/skills/{fui-skill → fui}/design-md/lovable/DESIGN.md +0 -0
  122. /package/skills/{fui-skill → fui}/design-md/lovable/README.md +0 -0
  123. /package/skills/{fui-skill → fui}/design-md/mastercard/DESIGN.md +0 -0
  124. /package/skills/{fui-skill → fui}/design-md/mastercard/README.md +0 -0
  125. /package/skills/{fui-skill → fui}/design-md/meta/DESIGN.md +0 -0
  126. /package/skills/{fui-skill → fui}/design-md/meta/README.md +0 -0
  127. /package/skills/{fui-skill → fui}/design-md/minimax/DESIGN.md +0 -0
  128. /package/skills/{fui-skill → fui}/design-md/minimax/README.md +0 -0
  129. /package/skills/{fui-skill → fui}/design-md/mintlify/DESIGN.md +0 -0
  130. /package/skills/{fui-skill → fui}/design-md/mintlify/README.md +0 -0
  131. /package/skills/{fui-skill → fui}/design-md/miro/DESIGN.md +0 -0
  132. /package/skills/{fui-skill → fui}/design-md/miro/README.md +0 -0
  133. /package/skills/{fui-skill → fui}/design-md/mistral.ai/DESIGN.md +0 -0
  134. /package/skills/{fui-skill → fui}/design-md/mistral.ai/README.md +0 -0
  135. /package/skills/{fui-skill → fui}/design-md/mongodb/DESIGN.md +0 -0
  136. /package/skills/{fui-skill → fui}/design-md/mongodb/README.md +0 -0
  137. /package/skills/{fui-skill → fui}/design-md/nike/DESIGN.md +0 -0
  138. /package/skills/{fui-skill → fui}/design-md/nike/README.md +0 -0
  139. /package/skills/{fui-skill → fui}/design-md/notion/DESIGN.md +0 -0
  140. /package/skills/{fui-skill → fui}/design-md/notion/README.md +0 -0
  141. /package/skills/{fui-skill → fui}/design-md/nvidia/DESIGN.md +0 -0
  142. /package/skills/{fui-skill → fui}/design-md/nvidia/README.md +0 -0
  143. /package/skills/{fui-skill → fui}/design-md/ollama/DESIGN.md +0 -0
  144. /package/skills/{fui-skill → fui}/design-md/ollama/README.md +0 -0
  145. /package/skills/{fui-skill → fui}/design-md/opencode.ai/DESIGN.md +0 -0
  146. /package/skills/{fui-skill → fui}/design-md/opencode.ai/README.md +0 -0
  147. /package/skills/{fui-skill → fui}/design-md/pinterest/DESIGN.md +0 -0
  148. /package/skills/{fui-skill → fui}/design-md/pinterest/README.md +0 -0
  149. /package/skills/{fui-skill → fui}/design-md/playstation/DESIGN.md +0 -0
  150. /package/skills/{fui-skill → fui}/design-md/playstation/README.md +0 -0
  151. /package/skills/{fui-skill → fui}/design-md/posthog/DESIGN.md +0 -0
  152. /package/skills/{fui-skill → fui}/design-md/posthog/README.md +0 -0
  153. /package/skills/{fui-skill → fui}/design-md/raycast/DESIGN.md +0 -0
  154. /package/skills/{fui-skill → fui}/design-md/raycast/README.md +0 -0
  155. /package/skills/{fui-skill → fui}/design-md/renault/DESIGN.md +0 -0
  156. /package/skills/{fui-skill → fui}/design-md/renault/README.md +0 -0
  157. /package/skills/{fui-skill → fui}/design-md/replicate/DESIGN.md +0 -0
  158. /package/skills/{fui-skill → fui}/design-md/replicate/README.md +0 -0
  159. /package/skills/{fui-skill → fui}/design-md/resend/DESIGN.md +0 -0
  160. /package/skills/{fui-skill → fui}/design-md/resend/README.md +0 -0
  161. /package/skills/{fui-skill → fui}/design-md/revolut/DESIGN.md +0 -0
  162. /package/skills/{fui-skill → fui}/design-md/revolut/README.md +0 -0
  163. /package/skills/{fui-skill → fui}/design-md/runwayml/DESIGN.md +0 -0
  164. /package/skills/{fui-skill → fui}/design-md/runwayml/README.md +0 -0
  165. /package/skills/{fui-skill → fui}/design-md/sanity/DESIGN.md +0 -0
  166. /package/skills/{fui-skill → fui}/design-md/sanity/README.md +0 -0
  167. /package/skills/{fui-skill → fui}/design-md/sentry/DESIGN.md +0 -0
  168. /package/skills/{fui-skill → fui}/design-md/sentry/README.md +0 -0
  169. /package/skills/{fui-skill → fui}/design-md/shopify/DESIGN.md +0 -0
  170. /package/skills/{fui-skill → fui}/design-md/shopify/README.md +0 -0
  171. /package/skills/{fui-skill → fui}/design-md/slack/DESIGN.md +0 -0
  172. /package/skills/{fui-skill → fui}/design-md/spacex/DESIGN.md +0 -0
  173. /package/skills/{fui-skill → fui}/design-md/spacex/README.md +0 -0
  174. /package/skills/{fui-skill → fui}/design-md/spotify/DESIGN.md +0 -0
  175. /package/skills/{fui-skill → fui}/design-md/spotify/README.md +0 -0
  176. /package/skills/{fui-skill → fui}/design-md/starbucks/DESIGN.md +0 -0
  177. /package/skills/{fui-skill → fui}/design-md/starbucks/README.md +0 -0
  178. /package/skills/{fui-skill → fui}/design-md/stripe/DESIGN.md +0 -0
  179. /package/skills/{fui-skill → fui}/design-md/stripe/README.md +0 -0
  180. /package/skills/{fui-skill → fui}/design-md/supabase/DESIGN.md +0 -0
  181. /package/skills/{fui-skill → fui}/design-md/supabase/README.md +0 -0
  182. /package/skills/{fui-skill → fui}/design-md/superhuman/DESIGN.md +0 -0
  183. /package/skills/{fui-skill → fui}/design-md/superhuman/README.md +0 -0
  184. /package/skills/{fui-skill → fui}/design-md/tesla/DESIGN.md +0 -0
  185. /package/skills/{fui-skill → fui}/design-md/tesla/README.md +0 -0
  186. /package/skills/{fui-skill → fui}/design-md/theverge/DESIGN.md +0 -0
  187. /package/skills/{fui-skill → fui}/design-md/theverge/README.md +0 -0
  188. /package/skills/{fui-skill → fui}/design-md/together.ai/DESIGN.md +0 -0
  189. /package/skills/{fui-skill → fui}/design-md/together.ai/README.md +0 -0
  190. /package/skills/{fui-skill → fui}/design-md/uber/DESIGN.md +0 -0
  191. /package/skills/{fui-skill → fui}/design-md/uber/README.md +0 -0
  192. /package/skills/{fui-skill → fui}/design-md/vercel/DESIGN.md +0 -0
  193. /package/skills/{fui-skill → fui}/design-md/vercel/README.md +0 -0
  194. /package/skills/{fui-skill → fui}/design-md/vodafone/DESIGN.md +0 -0
  195. /package/skills/{fui-skill → fui}/design-md/vodafone/README.md +0 -0
  196. /package/skills/{fui-skill → fui}/design-md/voltagent/DESIGN.md +0 -0
  197. /package/skills/{fui-skill → fui}/design-md/voltagent/README.md +0 -0
  198. /package/skills/{fui-skill → fui}/design-md/warp/DESIGN.md +0 -0
  199. /package/skills/{fui-skill → fui}/design-md/warp/README.md +0 -0
  200. /package/skills/{fui-skill → fui}/design-md/webflow/DESIGN.md +0 -0
  201. /package/skills/{fui-skill → fui}/design-md/webflow/README.md +0 -0
  202. /package/skills/{fui-skill → fui}/design-md/wired/DESIGN.md +0 -0
  203. /package/skills/{fui-skill → fui}/design-md/wired/README.md +0 -0
  204. /package/skills/{fui-skill → fui}/design-md/wise/DESIGN.md +0 -0
  205. /package/skills/{fui-skill → fui}/design-md/wise/README.md +0 -0
  206. /package/skills/{fui-skill → fui}/design-md/x.ai/DESIGN.md +0 -0
  207. /package/skills/{fui-skill → fui}/design-md/x.ai/README.md +0 -0
  208. /package/skills/{fui-skill → fui}/design-md/zapier/DESIGN.md +0 -0
  209. /package/skills/{fui-skill → fui}/design-md/zapier/README.md +0 -0
  210. /package/skills/{fui-skill → fui}/examples/f-table-patterns.json +0 -0
  211. /package/skills/{fui-skill → fui}/examples/module-patterns.json +0 -0
  212. /package/skills/{fui-skill → fui}/examples/project-patterns.json +0 -0
  213. /package/skills/{fui-skill → fui}/references/coding-standards.md +0 -0
  214. /package/skills/{fui-skill → fui}/references/db-table-design.md +0 -0
  215. /package/skills/{fui-skill → fui}/references/fsheet.md +0 -0
  216. /package/skills/{fui-skill → fui}/references/tapi-file-api.md +0 -0
  217. /package/skills/{fui-skill → fui}/references/ui-templates.md +0 -0
  218. /package/skills/{fui-skill → fui}/scripts/fechart.js +0 -0
  219. /package/skills/{fui-skill → fui}/scripts/fsheet.js +0 -0
@@ -1,870 +1,870 @@
1
- const { createApp, createVNode, render, ref, reactive, computed, watch, defineComponent, resolveComponent, markRaw } = Vue
2
- $awt = 'Bearer ' + getCookie('awt');
3
- var frameWorkSettingDefault = {
4
- "V3": {
5
- mainLayout: `<v-form ref="form" @submit.prevent="formSubmit">
6
- <v-layout>
7
- <header-bar v-if="v_Set.menu || v_Set.menuLeft" :logo="v_Set.logo" :title="v_Set.title" :menu="v_Set.menu" :menu-left="v_Set.menuLeft" :component="v_Set.menuComponent" :user-profile="v_Set.userProfile" :menu-style="v_Set.menuStyle"></header-bar>
8
- <v-main id="mainContainer" v-if="v_containerOn" ></v-main>
9
- </v-layout>
10
- <f-window v-for="(w,index) in v_OpenWindowList" :win-data="w"></f-window>
11
- </v-form>`,
12
- layoutTag: "v-container",
13
- layoutTagAttr: ["fluid"],
14
- rowTag: "v-row",
15
- rowTagAttr: ["dense", "no-gutters"],
16
- colTag: "v-col",
17
- colWidthClass: "v-col-",
18
- },
19
- "A3": {
20
- mainLayout: `<a-layout><a-layout id="mainContainer" v-if="v_containerOn" ></a-layout></a-layout>`,
21
- layoutTag: "a-layout",
22
- layoutTagAttr: [],
23
- rowTag: "a-row",
24
- rowTagAttr: [],
25
- colTag: "a-col",
26
- colWidthClass: "ant-col-",
27
- }
28
- }
29
- var defaultControlAttr = {}
30
- var frameWorkSetting = frameWorkSettingDefault[Framework];
31
- var vueData = reactive({
32
- p_domain: extractHostname(window.location.origin),
33
- p_routers: [],
34
- p_params: null,
35
- p_urlReferrer: (typeof urlReferrer === 'undefined' ? "" : urlReferrer),
36
- p_router: window.location.href.replace(window.location.origin, "").replace(window.location.search, ""),
37
- user: {
38
- UserID: null,
39
- UserName: null,
40
- LastName: null,
41
- FirstName: null,
42
- Sex: null,
43
- Phone: null,
44
- Email: null,
45
- DepartmentID: null,
46
- GroupID: null,
47
- SystemRight: null,
48
- FunctionRight: null,
49
- LastLogin: null
50
- },
51
- v_Set: {
52
- title: null,
53
- apiDomain: "",
54
- login: false,
55
- menu: [],
56
- userInfo: ""
57
- }
58
- });
59
-
60
- var vueOBJ = {
61
- data() { return vueData },
62
- methods: {
63
- async formvalidate() {
64
- if (vueData.v_Set.disableValidate) return true;
65
- const { valid } = await app._instance.refs.form.validate()
66
- return valid
67
- },
68
- async formSubmit() {
69
- if (!await this.formvalidate()) {
70
- showMessage({ type: "red", title: "Hãy điền đầy đủ dữ liệu bắt buộc !" });
71
- return false;
72
- }
73
- return true;
74
- }
75
- }
76
- };
77
-
78
- //===========================================================================================
79
- const app = createApp(vueOBJ);
80
- app.config.globalProperties = reactive({
81
- vueData,
82
- v_isMobile: $isMobile,
83
- v_Loading: false,
84
- v_LoadingOverlay: [],
85
- v_OpenWindowList: [],
86
- v_containerOn: true,
87
- })
88
-
89
- Vue.component = app.component;
90
- Vue.$toast = VueToast.useToast();
91
- //===========================================================================================
92
- //===========================================================================================
93
- $(document).ready(function () {
94
- try {
95
- loadModuleInfo();
96
- } catch (ex) {
97
- console.log("%cGet data error ", 'color: red; font-size: 30px; margin-top: 10px', ex);
98
- }
99
- });
100
- //===========================================================================================
101
- function buildParamURL() {
102
- //-------- build param from url ----------------------------
103
- vueData.p_routers = vueData.p_router.split('/').filter(w => w != '');
104
-
105
- vueData.p_params = window.location.search;
106
- const urlParams = new URLSearchParams(vueData.p_params);
107
-
108
- for (const key of urlParams.keys()) {
109
- vueData[key] = urlParams.get(key);
110
- }
111
- }
112
- //===========================================================================================
113
- function loadModuleInfo() {
114
- _.templateSettings.interpolate = /{{([\s\S]+?)}}/g; // thiet lap nay là cho lodash
115
- if (typeof $moduleUI == "undefined") $moduleUI = {};
116
-
117
- if (typeof $projectData == "undefined") {
118
- errorMess(1, "Chưa thiết lập cấu hình cho dự án");
119
- return
120
- }
121
-
122
- if (typeof $projectGroupSetting == "undefined") $projectGroupSetting = {}
123
-
124
- $.extend(vueData.v_Set, $projectGroupSetting, $projectData, $moduleUI.set);
125
-
126
- if (vueData.v_Set.domainSetting) {
127
- if (vueData.v_Set.domainSetting[vueData.p_domain]) {
128
- $.extend(vueData.v_Set, vueData.v_Set.domainSetting[vueData.p_domain]);
129
- }
130
- delete vueData.v_Set.domainSetting;
131
- }
132
-
133
- buildParamURL();
134
-
135
- //------- lay thong tin user nếu co ----------
136
- if (vueData.v_Set.userInfo && vueData.v_Set.userInfo != '') {
137
- $.ajax({
138
- type: "POST",
139
- headers: {
140
- authorization: $awt
141
- },
142
- url: fixURL(vueData.v_Set.userInfo),
143
- contentType: "application/json; charset=utf-8",
144
- dataType: "json",
145
- crossDomain: true,
146
- success: function (d) {
147
- vueData.user = d;
148
- },
149
- complete: function (data) {
150
- createModuleDom();
151
- }
152
- });
153
- } else createModuleDom();
154
- }
155
-
156
- //===========================================================================================
157
- function createModuleDom() {
158
-
159
- //=========== kiem tra đang nhap ================
160
- if (_.isString(vueData.v_Set.login) && vueData.v_Set.login != "") {
161
- if ($awt == 'Bearer ' || !vueData.user.UserID) {
162
- loginFUN();
163
- return
164
- }
165
- }
166
-
167
-
168
- //===============================================
169
- if (!$moduleUI.watch) $moduleUI.watch = {};
170
-
171
- //========= day la moi ================
172
- console.log(`FUI 3.0 Editor : https://fui.vn/fp/module?pid=${ProjectID}&mid=${ModuleID}&pageurl=${encodeURI(location.href)}`)
173
-
174
- console.log("DATA", vueData);
175
-
176
- //--------------------------------------------------------------------------------
177
- //---------- create data opject and load api data --------------------------------
178
- //--------------------------------------------------------------------------------
179
-
180
- runAction($moduleUI.data);
181
-
182
- //-------------------- build DOM for VUE -----------------------------------------
183
- var vue2MainLayout = $(frameWorkSetting.mainLayout)
184
-
185
- $("#mainContainer", vue2MainLayout).prepend(buildModuleUI($moduleUI.controls, vueData))
186
- $("#fastProjectAPP").prepend(vue2MainLayout)
187
- //============ websocket ===========================
188
- if (vueData.webSocket) {
189
- vueData.webSocketState = { code: 0, text: "" };
190
- if (_.isPlainObject(vueData.webSocket)) {
191
- let objW = {}
192
- _.forEach(vueData.webSocket, function (value, key) {
193
- objW[bindDataToString(key, vueData)] = value;
194
- });
195
- vueData.webSocket = objW;
196
- }
197
- webSocketConnection('https://ws.fui.vn/signalr', vueData.webSocket, vueData.webSocketState);
198
- webSocketJoinGroup(vueData.webSocket);
199
- }
200
-
201
- //============ run UI ====================================================
202
-
203
- if (Framework == 'V3') {
204
- vueData.v_Set.themeStyle = $.extend({}, vuetifyDefaultSetting, vueData.v_Set.themeStyle)
205
- app.use(Vuetify.createVuetify(vueData.v_Set.themeStyle));
206
- }
207
- if (Framework == 'A3') app.use(antd);
208
-
209
- app.mount('#fastProjectAPP');
210
-
211
- //=========== add watch ================
212
- createWatch($moduleUI.watch);
213
-
214
- //=============== lay du lieu tu iframe ==============================================
215
- window.onmessage = function (event) {
216
- var evt = event || window.event;
217
-
218
- // console.log("on message", evt.data)
219
- switch (evt.data.cmd) {
220
- case "setData":
221
- setWindowData(evt.data.value.key, evt.data.value.data);
222
- break;
223
- case "getData":
224
- let data = { key: evt.data.value.key, data: getWindowData(evt.data.value.val) };
225
- windowSendMessage(evt.source, "sendData", data);
226
- break;
227
- case "openWindow":
228
- openWindow(evt.data.value);
229
- break;
230
- case "LOGIN":
231
- setCookie('awt', evt.data.token, 365, (vueData.v_Set.authDomain ? vueData.v_Set.authDomain : ''));
232
- location.assign(location.href);
233
- break;
234
- default:
235
- // code block
236
- }
237
- };
238
- }
239
- //===========================================================================================
240
- //===========================================================================================
241
- function buildAttr(P, tagAttr) {
242
- var returnObj = {}
243
- if (!P) return {};
244
- if (typeof P == 'string') {
245
- var d = $(`<div ${P}>`)
246
- $.each(Object.assign({}, d[0].attributes), (i, a) => {
247
- if (a.value == "" && tagAttr.indexOf(a.name) == -1) {
248
- d.addClass(a.name)
249
- d.removeAttr(a.name)
250
- }
251
- })
252
- $.each(d[0].attributes, (i, a) => {
253
- returnObj[a.name] = a.value;
254
- })
255
- return returnObj;
256
- } else return P;
257
- }
258
- //===========================================================================================
259
- function buildModuleUI(controlsList, target) {
260
- var container = $("<div>");
261
-
262
- _.forEach(controlsList, function (C) {
263
- //var cont;
264
- // if(C.prop == undefined) C.prop = "";
265
- // if (_.isString(C.prop)) {
266
- // console.log("xxxxxxxxx", buildAttr(C.prop, frameWorkSetting.layoutTagAttr))
267
- // cont = $(`<${frameWorkSetting.layoutTag} ${C.prop}>`);
268
- // }
269
- // else cont = $(`<${frameWorkSetting.layoutTag}>`).attr(C.prop);
270
-
271
- var cont = $(`<${frameWorkSetting.layoutTag}>`).attr(buildAttr(C.prop, frameWorkSetting.layoutTagAttr));
272
-
273
- _.forEach(C.rows, function (R) {
274
- // var row;
275
- // if(R.prop == undefined) R.prop = "";
276
- // if (_.isString(R.prop)) row = $(`<${frameWorkSetting.rowTag} ${R.prop}>`);
277
- // else row = $(`<${frameWorkSetting.rowTag}>`).attr(R.prop);
278
-
279
- var row = $(`<${frameWorkSetting.rowTag}>`).attr(buildAttr(R.prop, frameWorkSetting.rowTagAttr));
280
-
281
- row.append(buildControl(R.cols, true, target));
282
- cont.append(row);
283
- });
284
- container.append(cont);
285
- });
286
-
287
- return container.children();
288
- }
289
- //===========================================================================================
290
- function buildControl(controlsList, flex, target) {
291
- var container = $("<div>");
292
-
293
- _.forEach(controlsList, function (c) {
294
- if (typeof (c.el) != "undefined" && c.el != "") {
295
- if (c.el == 'layout') c.el = frameWorkSetting.rowTag
296
-
297
- if (!c.attr) c.attr = {}
298
-
299
- var defCom = defaultControlAttr[c.el];
300
-
301
- if (defCom) {
302
- if (defCom.attr) c.attr = $.extend(true, _.cloneDeep(defCom.attr), c.attr);
303
- }
304
-
305
- //---------------- chuyen doi du lieu thanh biến -------------
306
- buildVisualValForObj(c.attr, target);
307
-
308
- if (!c.attr[":required"]) delete c.attr[":rules"];
309
- var ctl = $("<" + c.el + ">").attr(c.attr);
310
-
311
- if (c.innerHTML) {
312
- if (_.isString(c.innerHTML)) ctl.html(c.innerHTML);
313
- else if (_.isArray(c.innerHTML)) {
314
- if (c.el == frameWorkSetting.rowTag) {
315
- ctl.append(buildControl(c.innerHTML, true, target));
316
- } else {
317
- ctl.append(buildControl(c.innerHTML, false, target));
318
- }
319
- }
320
- }
321
-
322
- // if (flex) {
323
- // if (!_.isPlainObject(c.col)) c.col = {};
324
- // if (c.w) {
325
- // if (!c.col["cols"]) c.col["cols"] = c.w;
326
- // } else {
327
- // if ($isMobile && !c.col["cols"]) c.col["cols"] = 12;
328
- // }
329
-
330
- // if (c.el == 'v-col') ctl.attr(_.assignIn({}, c.col, c.attr));
331
- // else ctl = $("<v-col>").attr(c.col).append(ctl);
332
- // }
333
-
334
- if (flex) {
335
- // if(c.col == undefined) c.col = ""
336
- // if (c.el == frameWorkSetting.colTag) ctl.attr(buildAttr(c.col));
337
- // else if (_.isString(c.col)) ctl = $(`<${frameWorkSetting.colTag} ${c.col}>`).append(ctl);
338
- // else ctl = $(`<${frameWorkSetting.colTag}>`).attr(c.col).append(ctl);
339
-
340
-
341
- if (c.el == frameWorkSetting.colTag) ctl.attr(buildAttr(c.col, []));
342
- else ctl = $(`<${frameWorkSetting.colTag}>`).attr(buildAttr(c.col, [])).append(ctl);
343
-
344
- if (c.w) {
345
- if (c.w > 24) ctl.css("flex-basis", c.w + "px");
346
- else ctl.addClass(frameWorkSetting.colWidthClass + c.w);
347
- }
348
- if ($isMobile) ctl.addClass(frameWorkSetting.colWidthClass + "12");
349
- }
350
-
351
-
352
- container.append(ctl);
353
- }
354
- });
355
- return container.children();
356
- }
357
-
358
- //===========================================================================================
359
- //===========================================================================================
360
- //===========================================================================================
361
- //===========================================================================================
362
- function createWatch(obj) {
363
- if (obj) {
364
- if (_.isPlainObject(obj)) {
365
- _.forEach(obj, function (value, key) {
366
- if (!vueData.hasOwnProperty(key)) setValue(vueData, key, undefined);
367
- });
368
-
369
- if (obj['deep-watch']) {
370
- _.forEach(obj['deep-watch'], function (value, key) {
371
- key = bindDataToString(key, vueData);
372
- console.log("ADD Deep Watch : " + key);
373
- watch(key, function (newValue, oldValue) {
374
- runAction(value);
375
- }, { deep: true });
376
- });
377
- delete obj['deep-watch'];
378
- }
379
- //----------------------------
380
-
381
- _.forEach(obj, function (value, key) {
382
- key = bindDataToString(key, vueData);
383
- console.log("ADD Watch : " + key);
384
- watch(() => vueData[key], function (newValue, oldValue) {
385
- runAction(value);
386
- }, { deep: false });
387
- });
388
- }
389
- }
390
- }
391
- //===========================================================================================
392
- function buildVisualValForObj(controlAttr, target) {
393
- _.forEach(controlAttr, function (val, key) {
394
- if (_.isObjectLike(val)) {
395
- controlAttr[key] = JSON.stringify(val);
396
- } else if (target) {
397
- if (key == "v-model") {
398
- if (val.indexOf('vueData.') < 0 && getVueData(val, target) == undefined) {
399
- let mapObj = {};
400
- mapObj[val] = undefined;
401
-
402
- mapData(mapObj, target, {});
403
- }
404
- } else if (_.isString(val) && key[0] == ":") {
405
- let regexValCheck = /^[a-zA-Z0-9$_\[\]\-\.]*$/gm;
406
-
407
- if (val.indexOf('vueData.') < 0 && regexValCheck.test(val) && getVueData(val, target) == undefined) {
408
- let mapObj = {};
409
- if (key == ":items") mapObj[val] = [];
410
- else mapObj[val] = undefined;
411
-
412
- mapData(mapObj, target, {});
413
- }
414
- }
415
-
416
- }
417
- });
418
- }
419
- //===========================================================================================
420
- function runAction(obj, includeData) {
421
- if (!obj) return;
422
-
423
- let dataSrc = _.assignIn({}, vueData, includeData);
424
- if (_.isString(obj)) obj = getVueData(obj, dataSrc);
425
-
426
- if (!obj) {
427
- console.log("Action Undefined");
428
- return;
429
- }
430
-
431
- if (!_.isArray(obj)) obj = _.castArray(obj);
432
- //-------------------------------------------------
433
- _.forEach(obj, function (value) {
434
- if (value.CONFIRM) {
435
- confirm({
436
- title: bindDataToString(value.CONFIRM, dataSrc),
437
- action: function () {
438
- let action = _.cloneDeep(value);
439
- delete action.CONFIRM;
440
- delete action.CANCEL;
441
- vueAction(action, includeData);
442
- },
443
- cancel: function () {
444
- if (value.CANCEL) vueAction(value.CANCEL, includeData);
445
- else if (includeData && _.isFunction(includeData.cancelConfirm)) includeData.cancelConfirm();
446
- }
447
- });
448
- } else vueAction(value, includeData);
449
- });
450
- }
451
- //===========================================================================================
452
- function vueAction(objAction, includeData, callBack) {
453
- var obj = _.cloneDeep(objAction);
454
- var dataSrc = _.assignIn({}, vueData, includeData);
455
-
456
- if (!obj) return;
457
-
458
- if (obj.IN) {
459
- if (_.isString(obj.IN)) mapData({ "IN": obj.IN }, obj, dataSrc);
460
- else {
461
- var objIN = {};
462
- mapData(obj.IN, objIN, dataSrc);
463
- obj.IN = objIN;
464
- }
465
- //}
466
- }
467
- //--------------------------------------------------------------
468
- if (obj.API) {
469
- obj.API = bindDataToString(obj.API, dataSrc);
470
-
471
- if (obj.HEADER) {
472
- if (_.isString(obj.HEADER)) mapData({ "HEADER": obj.HEADER }, obj, dataSrc);
473
- else mapData(obj.HEADER, obj.HEADER, dataSrc);
474
- }
475
-
476
- defProp(obj.OUT);
477
- callAPI(obj, function (d) {
478
- if (_.isFunction(callBack)) callBack(d);
479
- runAction(obj.CALLBACK, includeData);
480
- }, includeData);
481
- return;
482
- }
483
-
484
- if (obj.CALL) {
485
- runAction(obj.CALL, includeData);
486
- return;
487
- }
488
-
489
- if (obj.EXE) {
490
- templateCompiled(`<% ${obj.EXE} %>`), { ...includeData, ...vueData }
491
- return;
492
- }
493
-
494
- if (obj.FUN) {
495
- obj.FUN = bindDataToString(obj.FUN, dataSrc);
496
- runFunction(obj, function (d) {
497
- mapData(obj.OUT, vueData, d);
498
-
499
- if (_.isFunction(callBack)) callBack(d);
500
- runAction(obj.CALLBACK, includeData);
501
- });
502
- return;
503
- }
504
-
505
- if (obj.IF) {
506
- if (templateCompiled(`<%- ${obj.IF} %>`, { ...includeData, ...vueData }) == 'true') {
507
- if (_.isString(obj.THEN)) templateCompiled(`<% ${obj.THEN} %>`, { ...includeData, ...vueData });
508
- else runAction(obj.THEN, includeData);
509
- } else {
510
- if (_.isString(obj.ELSE)) templateCompiled(`<% ${obj.ELSE} %>`, { ...includeData, ...vueData });
511
- else runAction(obj.ELSE, includeData);
512
- }
513
- return;
514
- }
515
-
516
- if (obj.MESS) {
517
- obj.MESS = bindDataToString(obj.MESS, dataSrc);
518
- Vue.$toast.success(obj.MESS, { position: 'top' });
519
- return;
520
- }
521
-
522
- if (obj.MESSBOX) {
523
- obj.MESSBOX = bindDataToString(obj.MESSBOX, dataSrc);
524
- showMessage({ title: obj.MESSBOX })
525
- return;
526
- }
527
-
528
- mapData(obj, vueData, vueData, includeData);
529
- }
530
- //===========================================================================================
531
- function mapData(map, target, src, includeData) {
532
- if (_.isString(map)) {
533
- setValue(target, map, src);
534
- } else {
535
- if (_.isPlainObject(map)) {
536
- _.forEach(map, function (value, key) {
537
- if (includeData) src = _.assignIn({}, vueData, includeData);
538
- //Get data of window
539
- if (_.isString(value) && value[0] == "#") {
540
- let windowData;
541
- try {
542
- if (window != top) windowData = parent.getWindowData(value);
543
- setValue(target, key, windowData);
544
- }
545
- catch (err) {
546
- let patternBlocked = /Blocked(.*)cross-origin(.*)/g;
547
- // Khi bi Blocked ko cho set du lieu vi khac ten mien
548
- if (patternBlocked.test(err)) windowSendMessage('#PARENT', "getData", { key: key, val: value });
549
- else console.log("Set value error:", key, err);
550
- }
551
- } else
552
- if (key[0] == "#") {// Set data to Window
553
- try {
554
- if (window != top) parent.setWindowData(key, getVueData(value, src));
555
- else setWindowData(key, getVueData(value, src));
556
- }
557
- catch (err) {
558
- let patternBlocked = /Blocked(.*)cross-origin(.*)/g;
559
- // Khi bi Blocked ko cho set du lieu vi khac ten mien
560
- if (patternBlocked.test(err)) windowSendMessage('#PARENT', "setData", { key: key, data: getVueData(value, src) });
561
- else console.log("Set value error:", key, err);
562
- }
563
- } else {
564
- setValue(target, key, getVueData(value, src), src);
565
- }
566
- });
567
- }
568
- }
569
- }
570
- //===========================================================================================
571
- function defProp(obj) {
572
- if (_.isString(obj)) {
573
- if (typeof vueData[obj] == "undefined") vueData[obj] = [];
574
- } else
575
- if (_.isPlainObject(obj))
576
- for (k in obj) {
577
- if (typeof vueData[k] == "undefined")
578
- vueData[k] = undefined;
579
- }
580
- }
581
- //===========================================================================================
582
- function bindData(obj) {
583
- if (_.isObjectLike(obj)) return obj;
584
- else return getVueData(obj, vueData);
585
- }
586
- //===========================================================================================
587
- function getVueData(key, src) {
588
- if (_.isString(key)) {
589
- if (key == "") return "";
590
- key = _.replace(key, 'vueData.', '').trim();
591
-
592
- if (key[0] == "`") {
593
- return _.trim(bindDataToString(key, src), "`");
594
- } else {
595
- if ((/^{{.*}}$/gm).test(key)) key = key.replace(/^{{|}}$/gm, ''); // bo cap {{ }} dau va cuoi
596
-
597
- try {
598
- templateCompiled(`<% ReturnValue = ${key} %>`, src);
599
- return ReturnValue;
600
- } catch (err) {
601
- let pattern = /Blocked(.*)cross-origin(.*)/g;
602
- if (pattern.test(err)) throw err;
603
- else {
604
- if ((/({{.*}}|[ ])/gm).test(key)) return _.trim(bindDataToString(key, src), "`");
605
- else {
606
- if (err.name != "ReferenceError") console.log("%cGet data error ", 'color: red; font-size: 16px; margin-top: 10px', key, err);
607
- }
608
- }
609
- //console.log("Error ", err);
610
- }
611
-
612
- return undefined;
613
- //console.log("ERROR", key)
614
- }
615
-
616
- } else if (_.isPlainObject(key) && key.ARRAY && key.COL) {
617
- return _.map(_.at(src, key.ARRAY)[0], _.property(key.COL));
618
- }
619
-
620
- return key;
621
- }
622
- //===========================================================================================
623
- function setValue(target, key, value, srcData, index) {
624
- if (_.isArray(key)) {
625
- let k = key[index];
626
- if (k[k.length - 1] == ']') {
627
- k = k.replaceAll("]", "");
628
- if ((/^[0-9]*$/gm).test(k)) k = parseInt(k); // kiem tra xem chuoi la numner
629
- else {
630
- if (k[0] == "'") k = k.replaceAll("'", "");
631
- else {
632
- k = getVueData(k, srcData);
633
- }
634
- }
635
- }
636
-
637
- if (key.length - 1 == index) {
638
- target[k] = value;
639
- return;
640
- }
641
-
642
- if (typeof target[k] == "undefined") {
643
- let kn = key[index + 1];
644
- if (kn[kn.length - 1] == ']') target[k] = [];
645
- else target[k] = {};
646
- }
647
- setValue(target[k], key, value, srcData, index + 1);
648
- } else {
649
- if (key[0] == "`" || key[0] == "'") {
650
- key = key.replaceAll("'", "").replaceAll("`", "");
651
- setValue(target, [key], value, srcData, 0);
652
- }
653
- else setValue(target, _.words(key, /[^.\[]+/g), value, srcData, 0);
654
- }
655
- }
656
- //===========================================================================================
657
- function bindDataToString(str, data) {
658
- if (!_.isString(str)) return str;
659
-
660
- let compiled = _.template(str);
661
- return compiled(data);
662
- }
663
- //===========================================================================================
664
- function templateCompiled(str, data) {
665
- var compiled = _.template(str);
666
- return compiled(data);
667
- }
668
- //===========================================================================================
669
- function getWindowData(value) {
670
- let winName = _.split(value, '.', 1)[0];
671
- let key = _.replace(value, winName + '.', '');
672
-
673
- if (winName == '#PARENT') return bindData(key);
674
-
675
- let win = $('iframe' + winName)[0];
676
-
677
- if (win) return win.contentWindow.bindData(key);
678
- else console.log("Window ID not found", winName);
679
-
680
- return undefined;
681
- }
682
- //===========================================================================================
683
- function setWindowData(key, value) {
684
- let W = _.split(key, '.', 1)[0];
685
- let K = _.replace(key, W + '.', '');
686
-
687
- if (W == '#PARENT') {
688
- if (K == W) {
689
- runAction(value);
690
- }
691
- else setValue(vueData, K, value);
692
- return
693
- }
694
- let win = $('iframe' + W)[0];
695
-
696
- if (win) win.contentWindow.setWindowData(_.replace(key, W, '#PARENT'), value);
697
- else console.log("Window ID not found", W);
698
- }
699
-
700
- //===========================================================================================
701
- function runFunction(obj, callback) {
702
- console.log("Run function", obj)
703
- let fn = window[obj.FUN];
704
- if (_.isFunction(fn)) {
705
- callback(fn(obj.IN));
706
- } else console.log("Func:", obj.FUN, "not found");
707
- }
708
- //===========================================================================================
709
- function tableActionEvent(ctrl) {
710
- let action = ctrl["action"]
711
- if (!action) action = ctrl[":action"];
712
-
713
- // let oldValue = ctrl.modelValue;
714
- // console.log("oldValue",oldValue);
715
- // if (!_.isUndefined(ctrl.ctlValue)) ctrl.$emit('input', ctrl.ctlValue);
716
- if (action) {
717
- console.log("Table Action", ctrl);
718
- runAction(action, {
719
- item: ctrl['item'],
720
- cancelConfirm: function () {
721
- // if (!_.isUndefined(oldValue)) ctrl.ctlValue = oldValue;
722
- // if (!_.isUndefined(ctrl.ctlValue)) ctrl.$emit('input', ctrl.ctlValue);
723
- }
724
- });
725
- }
726
- }
727
- //===========================================================================================
728
- function callAPI(objApi, callBack, includeData) {
729
- if (objApi.API) {
730
- let loadingID = generateID();
731
- app.config.globalProperties.v_LoadingOverlay.push(loadingID);
732
- app.config.globalProperties.v_Loading = true;
733
-
734
- $.ajax({
735
- type: (objApi.METHOD ? objApi.METHOD : "POST"),
736
- headers: (objApi.HEADER ? objApi.HEADER : {
737
- authorization: $awt
738
- }),
739
- url: fixURL(objApi.API),
740
- data: JSON.stringify(objApi.IN),
741
- contentType: "application/json; charset=utf-8",
742
- dataType: "json",
743
- crossDomain: true,
744
- success: function (d) {
745
- //---- convert to json object ------------
746
- json_data_parse(d, 0);
747
- //--------------------------------
748
- console.log("API:", _.cloneDeep(objApi.API), "IN:", objApi.IN ? _.cloneDeep(objApi.IN) : "");
749
- console.log("OUT:", _.cloneDeep(d));
750
- //--------------------------------------
751
- if (objApi.OUT) {
752
- if (_.isString(objApi.OUT) && Object.keys(d).length == 1 && d.data) d = d.data;
753
- mapData(objApi.OUT, vueData, d);
754
- }
755
- if (objApi.MESS) Vue.$toast.success(bindDataToString(objApi.MESS, vueData), { position: 'top' })
756
- if (_.isFunction(callBack)) callBack(d);
757
- },
758
- error: function (xhr, ajaxOptions, thrownError) {
759
- console.log("API:", objApi.API, "IN:", objApi.IN ? objApi.IN : "");
760
- if (objApi.ERROROUT) {
761
- mapData(objApi.ERROROUT, vueData, xhr);
762
- }
763
- if (objApi.ERRORCALLBACK) {
764
- runAction(objApi.ERRORCALLBACK, includeData);
765
- }
766
- if (objApi.ERROROUT) return;
767
-
768
- if (xhr.status == 200) {
769
- console.log("Error XHR:", xhr);
770
- mapData(objApi.OUT, vueData, xhr.responseText);
771
- } else {
772
- console.log("Error XHR:", xhr);
773
- errorMess(xhr.status, (_.isString(xhr.responseJSON) ? xhr.responseJSON : (_.isPlainObject(xhr.responseJSON) ? xhr.responseJSON.Message : "")))
774
- }
775
- },
776
- complete: function (data) {
777
- app.config.globalProperties.v_LoadingOverlay = _.without(app.config.globalProperties.v_LoadingOverlay, loadingID);
778
- if (app.config.globalProperties.v_LoadingOverlay.length == 0) app.config.globalProperties.v_Loading = false;
779
- }
780
- });
781
- }
782
- }
783
- //===========================================================================================
784
- function loginFUN() {
785
- if (!vueData.v_Set.login || vueData.v_Set.login == "") return;
786
- // if (vueData.v_Set.login.indexOf('login.fui.vn') >= 0) {
787
- // openWindow({
788
- // headerbar: false,
789
- // transition: 'fade-transition',
790
- // title: 'Đăng nhập',
791
- // url: vueData.v_Set.login,
792
- // onclose: function () {
793
- // location.assign(location.href);
794
- // }
795
- // });
796
- // }
797
- // else
798
- location.assign(vueData.v_Set.login);
799
- }
800
-
801
- //===========================================================================================
802
- function errorMess(code, message) {
803
- let errorText = {
804
- "400": ["Bad Request", "The server did not understand the request"],
805
- "401": ["Unauthorized", "The requested page needs a username and a password"],
806
- "402": ["Payment Required", "You can not use this code yet"],
807
- "403": ["Forbidden", "Access is forbidden to the requested page"],
808
- "404": ["Not Found", "The server can not find the requested page"],
809
- "405": ["Method Not Allowed", "The method specified in the request is not allowed"],
810
- "406": ["Not Acceptable", "The server can only generate a response that is not accepted by the client"],
811
- "407": ["Proxy Authentication Required", "You must authenticate with a proxy server before this request can be served"],
812
- "408": ["Request Timeout", "The request took longer than the server was prepared to wait"],
813
- "411": ["Length Required", "The 'Content-Length' is not defined. The server will not accept the request without it"],
814
- "413": ["Request Entity Too Large", ""],
815
- "414": ["Request-url Too Long", ""],
816
- "415": ["Unsupported Media Type", ""],
817
- "500": ["Internal Server Error", "The request was not completed. The server met an unexpected condition"],
818
- "501": ["Not Implemented", "The request was not completed. The server did not support the functionality required"],
819
- "502": ["Bad Gateway", ""],
820
- "503": ["Service Unavailable", "The request was not completed. The server is temporarily overloading or down"],
821
- "504": ["Gateway Timeout", "The gateway has timed out"],
822
- };
823
- let err = errorText[code];
824
- let title;
825
-
826
- if (code == "403") {
827
- if (message == '') title = 'Bạn chưa được phân quyền tính năng này.';
828
- else {
829
- title = message;
830
- message = '';
831
- }
832
- app.config.globalProperties.v_containerOn = false;
833
- } else if (code == "401") {
834
- if (vueData.v_Set.login && ($awt == 'Bearer ' || message.toLowerCase().indexOf('token') >= 0)) {
835
- loginFUN();
836
- return
837
- } else {
838
- if (!vueData.v_Set.login || vueData.v_Set.login == "") {
839
- title = 'Hãy đăng nhập lại';
840
- message = "Chứng thực của bạn không còn hiệu lực";
841
- } else {
842
- confirm({
843
- title: message,
844
- message: 'Bạn có muốn đăng nhập lại hay không ?',
845
- action: function () {
846
- loginFUN();
847
- }
848
- });
849
- return;
850
- }
851
- }
852
- } else if (!err) {
853
- title = "Error " + code + ': Hãy kiểm tra kết nối mạng';
854
- } else {
855
- if (code == '400') title = '';
856
- else title = code + ": " + err[0];
857
-
858
- if (!message) message = err[1];
859
- }
860
-
861
- //---------------------------------------------------------------------------------------------------------------------------
862
- showMessage({
863
- icon: 'mdi mdi-alert-circle-outline',
864
- title: title,
865
- message: message,
866
- type: 'red'
867
- });
868
- }
869
- //===========================================================================================
870
- //===========================================================================================
1
+ const { createApp, createVNode, render, ref, reactive, computed, watch, defineComponent, resolveComponent, markRaw } = Vue
2
+ $awt = 'Bearer ' + getCookie('awt');
3
+ var frameWorkSettingDefault = {
4
+ "V3": {
5
+ mainLayout: `<v-form ref="form" @submit.prevent="formSubmit">
6
+ <v-layout>
7
+ <header-bar v-if="v_Set.menu || v_Set.menuLeft" :logo="v_Set.logo" :title="v_Set.title" :menu="v_Set.menu" :menu-left="v_Set.menuLeft" :component="v_Set.menuComponent" :user-profile="v_Set.userProfile" :menu-style="v_Set.menuStyle"></header-bar>
8
+ <v-main id="mainContainer" v-if="v_containerOn" ></v-main>
9
+ </v-layout>
10
+ <f-window v-for="(w,index) in v_OpenWindowList" :win-data="w"></f-window>
11
+ </v-form>`,
12
+ layoutTag: "v-container",
13
+ layoutTagAttr: ["fluid"],
14
+ rowTag: "v-row",
15
+ rowTagAttr: ["dense", "no-gutters"],
16
+ colTag: "v-col",
17
+ colWidthClass: "v-col-",
18
+ },
19
+ "A3": {
20
+ mainLayout: `<a-layout><a-layout id="mainContainer" v-if="v_containerOn" ></a-layout></a-layout>`,
21
+ layoutTag: "a-layout",
22
+ layoutTagAttr: [],
23
+ rowTag: "a-row",
24
+ rowTagAttr: [],
25
+ colTag: "a-col",
26
+ colWidthClass: "ant-col-",
27
+ }
28
+ }
29
+ var defaultControlAttr = {}
30
+ var frameWorkSetting = frameWorkSettingDefault[Framework];
31
+ var vueData = reactive({
32
+ p_domain: extractHostname(window.location.origin),
33
+ p_routers: [],
34
+ p_params: null,
35
+ p_urlReferrer: (typeof urlReferrer === 'undefined' ? "" : urlReferrer),
36
+ p_router: window.location.href.replace(window.location.origin, "").replace(window.location.search, ""),
37
+ user: {
38
+ UserID: null,
39
+ UserName: null,
40
+ LastName: null,
41
+ FirstName: null,
42
+ Sex: null,
43
+ Phone: null,
44
+ Email: null,
45
+ DepartmentID: null,
46
+ GroupID: null,
47
+ SystemRight: null,
48
+ FunctionRight: null,
49
+ LastLogin: null
50
+ },
51
+ v_Set: {
52
+ title: null,
53
+ apiDomain: "",
54
+ login: false,
55
+ menu: [],
56
+ userInfo: ""
57
+ }
58
+ });
59
+
60
+ var vueOBJ = {
61
+ data() { return vueData },
62
+ methods: {
63
+ async formvalidate() {
64
+ if (vueData.v_Set.disableValidate) return true;
65
+ const { valid } = await app._instance.refs.form.validate()
66
+ return valid
67
+ },
68
+ async formSubmit() {
69
+ if (!await this.formvalidate()) {
70
+ showMessage({ type: "red", title: "Hãy điền đầy đủ dữ liệu bắt buộc !" });
71
+ return false;
72
+ }
73
+ return true;
74
+ }
75
+ }
76
+ };
77
+
78
+ //===========================================================================================
79
+ const app = createApp(vueOBJ);
80
+ app.config.globalProperties = reactive({
81
+ vueData,
82
+ v_isMobile: $isMobile,
83
+ v_Loading: false,
84
+ v_LoadingOverlay: [],
85
+ v_OpenWindowList: [],
86
+ v_containerOn: true,
87
+ })
88
+
89
+ Vue.component = app.component;
90
+ Vue.$toast = VueToast.useToast();
91
+ //===========================================================================================
92
+ //===========================================================================================
93
+ $(document).ready(function () {
94
+ try {
95
+ loadModuleInfo();
96
+ } catch (ex) {
97
+ console.log("%cGet data error ", 'color: red; font-size: 30px; margin-top: 10px', ex);
98
+ }
99
+ });
100
+ //===========================================================================================
101
+ function buildParamURL() {
102
+ //-------- build param from url ----------------------------
103
+ vueData.p_routers = vueData.p_router.split('/').filter(w => w != '');
104
+
105
+ vueData.p_params = window.location.search;
106
+ const urlParams = new URLSearchParams(vueData.p_params);
107
+
108
+ for (const key of urlParams.keys()) {
109
+ vueData[key] = urlParams.get(key);
110
+ }
111
+ }
112
+ //===========================================================================================
113
+ function loadModuleInfo() {
114
+ _.templateSettings.interpolate = /{{([\s\S]+?)}}/g; // thiet lap nay là cho lodash
115
+ if (typeof $moduleUI == "undefined") $moduleUI = {};
116
+
117
+ if (typeof $projectData == "undefined") {
118
+ errorMess(1, "Chưa thiết lập cấu hình cho dự án");
119
+ return
120
+ }
121
+
122
+ if (typeof $projectGroupSetting == "undefined") $projectGroupSetting = {}
123
+
124
+ $.extend(vueData.v_Set, $projectGroupSetting, $projectData, $moduleUI.set);
125
+
126
+ if (vueData.v_Set.domainSetting) {
127
+ if (vueData.v_Set.domainSetting[vueData.p_domain]) {
128
+ $.extend(vueData.v_Set, vueData.v_Set.domainSetting[vueData.p_domain]);
129
+ }
130
+ delete vueData.v_Set.domainSetting;
131
+ }
132
+
133
+ buildParamURL();
134
+
135
+ //------- lay thong tin user nếu co ----------
136
+ if (vueData.v_Set.userInfo && vueData.v_Set.userInfo != '') {
137
+ $.ajax({
138
+ type: "POST",
139
+ headers: {
140
+ authorization: $awt
141
+ },
142
+ url: fixURL(vueData.v_Set.userInfo),
143
+ contentType: "application/json; charset=utf-8",
144
+ dataType: "json",
145
+ crossDomain: true,
146
+ success: function (d) {
147
+ vueData.user = d;
148
+ },
149
+ complete: function (data) {
150
+ createModuleDom();
151
+ }
152
+ });
153
+ } else createModuleDom();
154
+ }
155
+
156
+ //===========================================================================================
157
+ function createModuleDom() {
158
+
159
+ //=========== kiem tra đang nhap ================
160
+ if (_.isString(vueData.v_Set.login) && vueData.v_Set.login != "") {
161
+ if ($awt == 'Bearer ' || !vueData.user.UserID) {
162
+ loginFUN();
163
+ return
164
+ }
165
+ }
166
+
167
+
168
+ //===============================================
169
+ if (!$moduleUI.watch) $moduleUI.watch = {};
170
+
171
+ //========= day la moi ================
172
+ console.log(`FUI 3.0 Editor : https://fui.vn/fp/module?pid=${ProjectID}&mid=${ModuleID}&pageurl=${encodeURI(location.href)}`)
173
+
174
+ console.log("DATA", vueData);
175
+
176
+ //--------------------------------------------------------------------------------
177
+ //---------- create data opject and load api data --------------------------------
178
+ //--------------------------------------------------------------------------------
179
+
180
+ runAction($moduleUI.data);
181
+
182
+ //-------------------- build DOM for VUE -----------------------------------------
183
+ var vue2MainLayout = $(frameWorkSetting.mainLayout)
184
+
185
+ $("#mainContainer", vue2MainLayout).prepend(buildModuleUI($moduleUI.controls, vueData))
186
+ $("#fastProjectAPP").prepend(vue2MainLayout)
187
+ //============ websocket ===========================
188
+ if (vueData.webSocket) {
189
+ vueData.webSocketState = { code: 0, text: "" };
190
+ if (_.isPlainObject(vueData.webSocket)) {
191
+ let objW = {}
192
+ _.forEach(vueData.webSocket, function (value, key) {
193
+ objW[bindDataToString(key, vueData)] = value;
194
+ });
195
+ vueData.webSocket = objW;
196
+ }
197
+ webSocketConnection('https://ws.fui.vn/signalr', vueData.webSocket, vueData.webSocketState);
198
+ webSocketJoinGroup(vueData.webSocket);
199
+ }
200
+
201
+ //============ run UI ====================================================
202
+
203
+ if (Framework == 'V3') {
204
+ vueData.v_Set.themeStyle = $.extend({}, vuetifyDefaultSetting, vueData.v_Set.themeStyle)
205
+ app.use(Vuetify.createVuetify(vueData.v_Set.themeStyle));
206
+ }
207
+ if (Framework == 'A3') app.use(antd);
208
+
209
+ app.mount('#fastProjectAPP');
210
+
211
+ //=========== add watch ================
212
+ createWatch($moduleUI.watch);
213
+
214
+ //=============== lay du lieu tu iframe ==============================================
215
+ window.onmessage = function (event) {
216
+ var evt = event || window.event;
217
+
218
+ // console.log("on message", evt.data)
219
+ switch (evt.data.cmd) {
220
+ case "setData":
221
+ setWindowData(evt.data.value.key, evt.data.value.data);
222
+ break;
223
+ case "getData":
224
+ let data = { key: evt.data.value.key, data: getWindowData(evt.data.value.val) };
225
+ windowSendMessage(evt.source, "sendData", data);
226
+ break;
227
+ case "openWindow":
228
+ openWindow(evt.data.value);
229
+ break;
230
+ case "LOGIN":
231
+ setCookie('awt', evt.data.token, 365, (vueData.v_Set.authDomain ? vueData.v_Set.authDomain : ''));
232
+ location.assign(location.href);
233
+ break;
234
+ default:
235
+ // code block
236
+ }
237
+ };
238
+ }
239
+ //===========================================================================================
240
+ //===========================================================================================
241
+ function buildAttr(P, tagAttr) {
242
+ var returnObj = {}
243
+ if (!P) return {};
244
+ if (typeof P == 'string') {
245
+ var d = $(`<div ${P}>`)
246
+ $.each(Object.assign({}, d[0].attributes), (i, a) => {
247
+ if (a.value == "" && tagAttr.indexOf(a.name) == -1) {
248
+ d.addClass(a.name)
249
+ d.removeAttr(a.name)
250
+ }
251
+ })
252
+ $.each(d[0].attributes, (i, a) => {
253
+ returnObj[a.name] = a.value;
254
+ })
255
+ return returnObj;
256
+ } else return P;
257
+ }
258
+ //===========================================================================================
259
+ function buildModuleUI(controlsList, target) {
260
+ var container = $("<div>");
261
+
262
+ _.forEach(controlsList, function (C) {
263
+ //var cont;
264
+ // if(C.prop == undefined) C.prop = "";
265
+ // if (_.isString(C.prop)) {
266
+ // console.log("xxxxxxxxx", buildAttr(C.prop, frameWorkSetting.layoutTagAttr))
267
+ // cont = $(`<${frameWorkSetting.layoutTag} ${C.prop}>`);
268
+ // }
269
+ // else cont = $(`<${frameWorkSetting.layoutTag}>`).attr(C.prop);
270
+
271
+ var cont = $(`<${frameWorkSetting.layoutTag}>`).attr(buildAttr(C.prop, frameWorkSetting.layoutTagAttr));
272
+
273
+ _.forEach(C.rows, function (R) {
274
+ // var row;
275
+ // if(R.prop == undefined) R.prop = "";
276
+ // if (_.isString(R.prop)) row = $(`<${frameWorkSetting.rowTag} ${R.prop}>`);
277
+ // else row = $(`<${frameWorkSetting.rowTag}>`).attr(R.prop);
278
+
279
+ var row = $(`<${frameWorkSetting.rowTag}>`).attr(buildAttr(R.prop, frameWorkSetting.rowTagAttr));
280
+
281
+ row.append(buildControl(R.cols, true, target));
282
+ cont.append(row);
283
+ });
284
+ container.append(cont);
285
+ });
286
+
287
+ return container.children();
288
+ }
289
+ //===========================================================================================
290
+ function buildControl(controlsList, flex, target) {
291
+ var container = $("<div>");
292
+
293
+ _.forEach(controlsList, function (c) {
294
+ if (typeof (c.el) != "undefined" && c.el != "") {
295
+ if (c.el == 'layout') c.el = frameWorkSetting.rowTag
296
+
297
+ if (!c.attr) c.attr = {}
298
+
299
+ var defCom = defaultControlAttr[c.el];
300
+
301
+ if (defCom) {
302
+ if (defCom.attr) c.attr = $.extend(true, _.cloneDeep(defCom.attr), c.attr);
303
+ }
304
+
305
+ //---------------- chuyen doi du lieu thanh biến -------------
306
+ buildVisualValForObj(c.attr, target);
307
+
308
+ if (!c.attr[":required"]) delete c.attr[":rules"];
309
+ var ctl = $("<" + c.el + ">").attr(c.attr);
310
+
311
+ if (c.innerHTML) {
312
+ if (_.isString(c.innerHTML)) ctl.html(c.innerHTML);
313
+ else if (_.isArray(c.innerHTML)) {
314
+ if (c.el == frameWorkSetting.rowTag) {
315
+ ctl.append(buildControl(c.innerHTML, true, target));
316
+ } else {
317
+ ctl.append(buildControl(c.innerHTML, false, target));
318
+ }
319
+ }
320
+ }
321
+
322
+ // if (flex) {
323
+ // if (!_.isPlainObject(c.col)) c.col = {};
324
+ // if (c.w) {
325
+ // if (!c.col["cols"]) c.col["cols"] = c.w;
326
+ // } else {
327
+ // if ($isMobile && !c.col["cols"]) c.col["cols"] = 12;
328
+ // }
329
+
330
+ // if (c.el == 'v-col') ctl.attr(_.assignIn({}, c.col, c.attr));
331
+ // else ctl = $("<v-col>").attr(c.col).append(ctl);
332
+ // }
333
+
334
+ if (flex) {
335
+ // if(c.col == undefined) c.col = ""
336
+ // if (c.el == frameWorkSetting.colTag) ctl.attr(buildAttr(c.col));
337
+ // else if (_.isString(c.col)) ctl = $(`<${frameWorkSetting.colTag} ${c.col}>`).append(ctl);
338
+ // else ctl = $(`<${frameWorkSetting.colTag}>`).attr(c.col).append(ctl);
339
+
340
+
341
+ if (c.el == frameWorkSetting.colTag) ctl.attr(buildAttr(c.col, []));
342
+ else ctl = $(`<${frameWorkSetting.colTag}>`).attr(buildAttr(c.col, [])).append(ctl);
343
+
344
+ if (c.w) {
345
+ if (c.w > 24) ctl.css("flex-basis", c.w + "px");
346
+ else ctl.addClass(frameWorkSetting.colWidthClass + c.w);
347
+ }
348
+ if ($isMobile) ctl.addClass(frameWorkSetting.colWidthClass + "12");
349
+ }
350
+
351
+
352
+ container.append(ctl);
353
+ }
354
+ });
355
+ return container.children();
356
+ }
357
+
358
+ //===========================================================================================
359
+ //===========================================================================================
360
+ //===========================================================================================
361
+ //===========================================================================================
362
+ function createWatch(obj) {
363
+ if (obj) {
364
+ if (_.isPlainObject(obj)) {
365
+ _.forEach(obj, function (value, key) {
366
+ if (!vueData.hasOwnProperty(key)) setValue(vueData, key, undefined);
367
+ });
368
+
369
+ if (obj['deep-watch']) {
370
+ _.forEach(obj['deep-watch'], function (value, key) {
371
+ key = bindDataToString(key, vueData);
372
+ console.log("ADD Deep Watch : " + key);
373
+ watch(key, function (newValue, oldValue) {
374
+ runAction(value);
375
+ }, { deep: true });
376
+ });
377
+ delete obj['deep-watch'];
378
+ }
379
+ //----------------------------
380
+
381
+ _.forEach(obj, function (value, key) {
382
+ key = bindDataToString(key, vueData);
383
+ console.log("ADD Watch : " + key);
384
+ watch(() => vueData[key], function (newValue, oldValue) {
385
+ runAction(value);
386
+ }, { deep: false });
387
+ });
388
+ }
389
+ }
390
+ }
391
+ //===========================================================================================
392
+ function buildVisualValForObj(controlAttr, target) {
393
+ _.forEach(controlAttr, function (val, key) {
394
+ if (_.isObjectLike(val)) {
395
+ controlAttr[key] = JSON.stringify(val);
396
+ } else if (target) {
397
+ if (key == "v-model") {
398
+ if (val.indexOf('vueData.') < 0 && getVueData(val, target) == undefined) {
399
+ let mapObj = {};
400
+ mapObj[val] = undefined;
401
+
402
+ mapData(mapObj, target, {});
403
+ }
404
+ } else if (_.isString(val) && key[0] == ":") {
405
+ let regexValCheck = /^[a-zA-Z0-9$_\[\]\-\.]*$/gm;
406
+
407
+ if (val.indexOf('vueData.') < 0 && regexValCheck.test(val) && getVueData(val, target) == undefined) {
408
+ let mapObj = {};
409
+ if (key == ":items") mapObj[val] = [];
410
+ else mapObj[val] = undefined;
411
+
412
+ mapData(mapObj, target, {});
413
+ }
414
+ }
415
+
416
+ }
417
+ });
418
+ }
419
+ //===========================================================================================
420
+ function runAction(obj, includeData) {
421
+ if (!obj) return;
422
+
423
+ let dataSrc = _.assignIn({}, vueData, includeData);
424
+ if (_.isString(obj)) obj = getVueData(obj, dataSrc);
425
+
426
+ if (!obj) {
427
+ console.log("Action Undefined");
428
+ return;
429
+ }
430
+
431
+ if (!_.isArray(obj)) obj = _.castArray(obj);
432
+ //-------------------------------------------------
433
+ _.forEach(obj, function (value) {
434
+ if (value.CONFIRM) {
435
+ confirm({
436
+ title: bindDataToString(value.CONFIRM, dataSrc),
437
+ action: function () {
438
+ let action = _.cloneDeep(value);
439
+ delete action.CONFIRM;
440
+ delete action.CANCEL;
441
+ vueAction(action, includeData);
442
+ },
443
+ cancel: function () {
444
+ if (value.CANCEL) vueAction(value.CANCEL, includeData);
445
+ else if (includeData && _.isFunction(includeData.cancelConfirm)) includeData.cancelConfirm();
446
+ }
447
+ });
448
+ } else vueAction(value, includeData);
449
+ });
450
+ }
451
+ //===========================================================================================
452
+ function vueAction(objAction, includeData, callBack) {
453
+ var obj = _.cloneDeep(objAction);
454
+ var dataSrc = _.assignIn({}, vueData, includeData);
455
+
456
+ if (!obj) return;
457
+
458
+ if (obj.IN) {
459
+ if (_.isString(obj.IN)) mapData({ "IN": obj.IN }, obj, dataSrc);
460
+ else {
461
+ var objIN = {};
462
+ mapData(obj.IN, objIN, dataSrc);
463
+ obj.IN = objIN;
464
+ }
465
+ //}
466
+ }
467
+ //--------------------------------------------------------------
468
+ if (obj.API) {
469
+ obj.API = bindDataToString(obj.API, dataSrc);
470
+
471
+ if (obj.HEADER) {
472
+ if (_.isString(obj.HEADER)) mapData({ "HEADER": obj.HEADER }, obj, dataSrc);
473
+ else mapData(obj.HEADER, obj.HEADER, dataSrc);
474
+ }
475
+
476
+ defProp(obj.OUT);
477
+ callAPI(obj, function (d) {
478
+ if (_.isFunction(callBack)) callBack(d);
479
+ runAction(obj.CALLBACK, includeData);
480
+ }, includeData);
481
+ return;
482
+ }
483
+
484
+ if (obj.CALL) {
485
+ runAction(obj.CALL, includeData);
486
+ return;
487
+ }
488
+
489
+ if (obj.EXE) {
490
+ templateCompiled(`<% ${obj.EXE} %>`), { ...includeData, ...vueData }
491
+ return;
492
+ }
493
+
494
+ if (obj.FUN) {
495
+ obj.FUN = bindDataToString(obj.FUN, dataSrc);
496
+ runFunction(obj, function (d) {
497
+ mapData(obj.OUT, vueData, d);
498
+
499
+ if (_.isFunction(callBack)) callBack(d);
500
+ runAction(obj.CALLBACK, includeData);
501
+ });
502
+ return;
503
+ }
504
+
505
+ if (obj.IF) {
506
+ if (templateCompiled(`<%- ${obj.IF} %>`, { ...includeData, ...vueData }) == 'true') {
507
+ if (_.isString(obj.THEN)) templateCompiled(`<% ${obj.THEN} %>`, { ...includeData, ...vueData });
508
+ else runAction(obj.THEN, includeData);
509
+ } else {
510
+ if (_.isString(obj.ELSE)) templateCompiled(`<% ${obj.ELSE} %>`, { ...includeData, ...vueData });
511
+ else runAction(obj.ELSE, includeData);
512
+ }
513
+ return;
514
+ }
515
+
516
+ if (obj.MESS) {
517
+ obj.MESS = bindDataToString(obj.MESS, dataSrc);
518
+ Vue.$toast.success(obj.MESS, { position: 'top' });
519
+ return;
520
+ }
521
+
522
+ if (obj.MESSBOX) {
523
+ obj.MESSBOX = bindDataToString(obj.MESSBOX, dataSrc);
524
+ showMessage({ title: obj.MESSBOX })
525
+ return;
526
+ }
527
+
528
+ mapData(obj, vueData, vueData, includeData);
529
+ }
530
+ //===========================================================================================
531
+ function mapData(map, target, src, includeData) {
532
+ if (_.isString(map)) {
533
+ setValue(target, map, src);
534
+ } else {
535
+ if (_.isPlainObject(map)) {
536
+ _.forEach(map, function (value, key) {
537
+ if (includeData) src = _.assignIn({}, vueData, includeData);
538
+ //Get data of window
539
+ if (_.isString(value) && value[0] == "#") {
540
+ let windowData;
541
+ try {
542
+ if (window != top) windowData = parent.getWindowData(value);
543
+ setValue(target, key, windowData);
544
+ }
545
+ catch (err) {
546
+ let patternBlocked = /Blocked(.*)cross-origin(.*)/g;
547
+ // Khi bi Blocked ko cho set du lieu vi khac ten mien
548
+ if (patternBlocked.test(err)) windowSendMessage('#PARENT', "getData", { key: key, val: value });
549
+ else console.log("Set value error:", key, err);
550
+ }
551
+ } else
552
+ if (key[0] == "#") {// Set data to Window
553
+ try {
554
+ if (window != top) parent.setWindowData(key, getVueData(value, src));
555
+ else setWindowData(key, getVueData(value, src));
556
+ }
557
+ catch (err) {
558
+ let patternBlocked = /Blocked(.*)cross-origin(.*)/g;
559
+ // Khi bi Blocked ko cho set du lieu vi khac ten mien
560
+ if (patternBlocked.test(err)) windowSendMessage('#PARENT', "setData", { key: key, data: getVueData(value, src) });
561
+ else console.log("Set value error:", key, err);
562
+ }
563
+ } else {
564
+ setValue(target, key, getVueData(value, src), src);
565
+ }
566
+ });
567
+ }
568
+ }
569
+ }
570
+ //===========================================================================================
571
+ function defProp(obj) {
572
+ if (_.isString(obj)) {
573
+ if (typeof vueData[obj] == "undefined") vueData[obj] = [];
574
+ } else
575
+ if (_.isPlainObject(obj))
576
+ for (k in obj) {
577
+ if (typeof vueData[k] == "undefined")
578
+ vueData[k] = undefined;
579
+ }
580
+ }
581
+ //===========================================================================================
582
+ function bindData(obj) {
583
+ if (_.isObjectLike(obj)) return obj;
584
+ else return getVueData(obj, vueData);
585
+ }
586
+ //===========================================================================================
587
+ function getVueData(key, src) {
588
+ if (_.isString(key)) {
589
+ if (key == "") return "";
590
+ key = _.replace(key, 'vueData.', '').trim();
591
+
592
+ if (key[0] == "`") {
593
+ return _.trim(bindDataToString(key, src), "`");
594
+ } else {
595
+ if ((/^{{.*}}$/gm).test(key)) key = key.replace(/^{{|}}$/gm, ''); // bo cap {{ }} dau va cuoi
596
+
597
+ try {
598
+ templateCompiled(`<% ReturnValue = ${key} %>`, src);
599
+ return ReturnValue;
600
+ } catch (err) {
601
+ let pattern = /Blocked(.*)cross-origin(.*)/g;
602
+ if (pattern.test(err)) throw err;
603
+ else {
604
+ if ((/({{.*}}|[ ])/gm).test(key)) return _.trim(bindDataToString(key, src), "`");
605
+ else {
606
+ if (err.name != "ReferenceError") console.log("%cGet data error ", 'color: red; font-size: 16px; margin-top: 10px', key, err);
607
+ }
608
+ }
609
+ //console.log("Error ", err);
610
+ }
611
+
612
+ return undefined;
613
+ //console.log("ERROR", key)
614
+ }
615
+
616
+ } else if (_.isPlainObject(key) && key.ARRAY && key.COL) {
617
+ return _.map(_.at(src, key.ARRAY)[0], _.property(key.COL));
618
+ }
619
+
620
+ return key;
621
+ }
622
+ //===========================================================================================
623
+ function setValue(target, key, value, srcData, index) {
624
+ if (_.isArray(key)) {
625
+ let k = key[index];
626
+ if (k[k.length - 1] == ']') {
627
+ k = k.replaceAll("]", "");
628
+ if ((/^[0-9]*$/gm).test(k)) k = parseInt(k); // kiem tra xem chuoi la numner
629
+ else {
630
+ if (k[0] == "'") k = k.replaceAll("'", "");
631
+ else {
632
+ k = getVueData(k, srcData);
633
+ }
634
+ }
635
+ }
636
+
637
+ if (key.length - 1 == index) {
638
+ target[k] = value;
639
+ return;
640
+ }
641
+
642
+ if (typeof target[k] == "undefined") {
643
+ let kn = key[index + 1];
644
+ if (kn[kn.length - 1] == ']') target[k] = [];
645
+ else target[k] = {};
646
+ }
647
+ setValue(target[k], key, value, srcData, index + 1);
648
+ } else {
649
+ if (key[0] == "`" || key[0] == "'") {
650
+ key = key.replaceAll("'", "").replaceAll("`", "");
651
+ setValue(target, [key], value, srcData, 0);
652
+ }
653
+ else setValue(target, _.words(key, /[^.\[]+/g), value, srcData, 0);
654
+ }
655
+ }
656
+ //===========================================================================================
657
+ function bindDataToString(str, data) {
658
+ if (!_.isString(str)) return str;
659
+
660
+ let compiled = _.template(str);
661
+ return compiled(data);
662
+ }
663
+ //===========================================================================================
664
+ function templateCompiled(str, data) {
665
+ var compiled = _.template(str);
666
+ return compiled(data);
667
+ }
668
+ //===========================================================================================
669
+ function getWindowData(value) {
670
+ let winName = _.split(value, '.', 1)[0];
671
+ let key = _.replace(value, winName + '.', '');
672
+
673
+ if (winName == '#PARENT') return bindData(key);
674
+
675
+ let win = $('iframe' + winName)[0];
676
+
677
+ if (win) return win.contentWindow.bindData(key);
678
+ else console.log("Window ID not found", winName);
679
+
680
+ return undefined;
681
+ }
682
+ //===========================================================================================
683
+ function setWindowData(key, value) {
684
+ let W = _.split(key, '.', 1)[0];
685
+ let K = _.replace(key, W + '.', '');
686
+
687
+ if (W == '#PARENT') {
688
+ if (K == W) {
689
+ runAction(value);
690
+ }
691
+ else setValue(vueData, K, value);
692
+ return
693
+ }
694
+ let win = $('iframe' + W)[0];
695
+
696
+ if (win) win.contentWindow.setWindowData(_.replace(key, W, '#PARENT'), value);
697
+ else console.log("Window ID not found", W);
698
+ }
699
+
700
+ //===========================================================================================
701
+ function runFunction(obj, callback) {
702
+ console.log("Run function", obj)
703
+ let fn = window[obj.FUN];
704
+ if (_.isFunction(fn)) {
705
+ callback(fn(obj.IN));
706
+ } else console.log("Func:", obj.FUN, "not found");
707
+ }
708
+ //===========================================================================================
709
+ function tableActionEvent(ctrl) {
710
+ let action = ctrl["action"]
711
+ if (!action) action = ctrl[":action"];
712
+
713
+ // let oldValue = ctrl.modelValue;
714
+ // console.log("oldValue",oldValue);
715
+ // if (!_.isUndefined(ctrl.ctlValue)) ctrl.$emit('input', ctrl.ctlValue);
716
+ if (action) {
717
+ console.log("Table Action", ctrl);
718
+ runAction(action, {
719
+ item: ctrl['item'],
720
+ cancelConfirm: function () {
721
+ // if (!_.isUndefined(oldValue)) ctrl.ctlValue = oldValue;
722
+ // if (!_.isUndefined(ctrl.ctlValue)) ctrl.$emit('input', ctrl.ctlValue);
723
+ }
724
+ });
725
+ }
726
+ }
727
+ //===========================================================================================
728
+ function callAPI(objApi, callBack, includeData) {
729
+ if (objApi.API) {
730
+ let loadingID = generateID();
731
+ app.config.globalProperties.v_LoadingOverlay.push(loadingID);
732
+ app.config.globalProperties.v_Loading = true;
733
+
734
+ $.ajax({
735
+ type: (objApi.METHOD ? objApi.METHOD : "POST"),
736
+ headers: (objApi.HEADER ? objApi.HEADER : {
737
+ authorization: $awt
738
+ }),
739
+ url: fixURL(objApi.API),
740
+ data: JSON.stringify(objApi.IN),
741
+ contentType: "application/json; charset=utf-8",
742
+ dataType: "json",
743
+ crossDomain: true,
744
+ success: function (d) {
745
+ //---- convert to json object ------------
746
+ json_data_parse(d, 0);
747
+ //--------------------------------
748
+ console.log("API:", _.cloneDeep(objApi.API), "IN:", objApi.IN ? _.cloneDeep(objApi.IN) : "");
749
+ console.log("OUT:", _.cloneDeep(d));
750
+ //--------------------------------------
751
+ if (objApi.OUT) {
752
+ if (_.isString(objApi.OUT) && Object.keys(d).length == 1 && d.data) d = d.data;
753
+ mapData(objApi.OUT, vueData, d);
754
+ }
755
+ if (objApi.MESS) Vue.$toast.success(bindDataToString(objApi.MESS, vueData), { position: 'top' })
756
+ if (_.isFunction(callBack)) callBack(d);
757
+ },
758
+ error: function (xhr, ajaxOptions, thrownError) {
759
+ console.log("API:", objApi.API, "IN:", objApi.IN ? objApi.IN : "");
760
+ if (objApi.ERROROUT) {
761
+ mapData(objApi.ERROROUT, vueData, xhr);
762
+ }
763
+ if (objApi.ERRORCALLBACK) {
764
+ runAction(objApi.ERRORCALLBACK, includeData);
765
+ }
766
+ if (objApi.ERROROUT) return;
767
+
768
+ if (xhr.status == 200) {
769
+ console.log("Error XHR:", xhr);
770
+ mapData(objApi.OUT, vueData, xhr.responseText);
771
+ } else {
772
+ console.log("Error XHR:", xhr);
773
+ errorMess(xhr.status, (_.isString(xhr.responseJSON) ? xhr.responseJSON : (_.isPlainObject(xhr.responseJSON) ? xhr.responseJSON.Message : "")))
774
+ }
775
+ },
776
+ complete: function (data) {
777
+ app.config.globalProperties.v_LoadingOverlay = _.without(app.config.globalProperties.v_LoadingOverlay, loadingID);
778
+ if (app.config.globalProperties.v_LoadingOverlay.length == 0) app.config.globalProperties.v_Loading = false;
779
+ }
780
+ });
781
+ }
782
+ }
783
+ //===========================================================================================
784
+ function loginFUN() {
785
+ if (!vueData.v_Set.login || vueData.v_Set.login == "") return;
786
+ // if (vueData.v_Set.login.indexOf('login.fui.vn') >= 0) {
787
+ // openWindow({
788
+ // headerbar: false,
789
+ // transition: 'fade-transition',
790
+ // title: 'Đăng nhập',
791
+ // url: vueData.v_Set.login,
792
+ // onclose: function () {
793
+ // location.assign(location.href);
794
+ // }
795
+ // });
796
+ // }
797
+ // else
798
+ location.assign(vueData.v_Set.login);
799
+ }
800
+
801
+ //===========================================================================================
802
+ function errorMess(code, message) {
803
+ let errorText = {
804
+ "400": ["Bad Request", "The server did not understand the request"],
805
+ "401": ["Unauthorized", "The requested page needs a username and a password"],
806
+ "402": ["Payment Required", "You can not use this code yet"],
807
+ "403": ["Forbidden", "Access is forbidden to the requested page"],
808
+ "404": ["Not Found", "The server can not find the requested page"],
809
+ "405": ["Method Not Allowed", "The method specified in the request is not allowed"],
810
+ "406": ["Not Acceptable", "The server can only generate a response that is not accepted by the client"],
811
+ "407": ["Proxy Authentication Required", "You must authenticate with a proxy server before this request can be served"],
812
+ "408": ["Request Timeout", "The request took longer than the server was prepared to wait"],
813
+ "411": ["Length Required", "The 'Content-Length' is not defined. The server will not accept the request without it"],
814
+ "413": ["Request Entity Too Large", ""],
815
+ "414": ["Request-url Too Long", ""],
816
+ "415": ["Unsupported Media Type", ""],
817
+ "500": ["Internal Server Error", "The request was not completed. The server met an unexpected condition"],
818
+ "501": ["Not Implemented", "The request was not completed. The server did not support the functionality required"],
819
+ "502": ["Bad Gateway", ""],
820
+ "503": ["Service Unavailable", "The request was not completed. The server is temporarily overloading or down"],
821
+ "504": ["Gateway Timeout", "The gateway has timed out"],
822
+ };
823
+ let err = errorText[code];
824
+ let title;
825
+
826
+ if (code == "403") {
827
+ if (message == '') title = 'Bạn chưa được phân quyền tính năng này.';
828
+ else {
829
+ title = message;
830
+ message = '';
831
+ }
832
+ app.config.globalProperties.v_containerOn = false;
833
+ } else if (code == "401") {
834
+ if (vueData.v_Set.login && ($awt == 'Bearer ' || message.toLowerCase().indexOf('token') >= 0)) {
835
+ loginFUN();
836
+ return
837
+ } else {
838
+ if (!vueData.v_Set.login || vueData.v_Set.login == "") {
839
+ title = 'Hãy đăng nhập lại';
840
+ message = "Chứng thực của bạn không còn hiệu lực";
841
+ } else {
842
+ confirm({
843
+ title: message,
844
+ message: 'Bạn có muốn đăng nhập lại hay không ?',
845
+ action: function () {
846
+ loginFUN();
847
+ }
848
+ });
849
+ return;
850
+ }
851
+ }
852
+ } else if (!err) {
853
+ title = "Error " + code + ': Hãy kiểm tra kết nối mạng';
854
+ } else {
855
+ if (code == '400') title = '';
856
+ else title = code + ": " + err[0];
857
+
858
+ if (!message) message = err[1];
859
+ }
860
+
861
+ //---------------------------------------------------------------------------------------------------------------------------
862
+ showMessage({
863
+ icon: 'mdi mdi-alert-circle-outline',
864
+ title: title,
865
+ message: message,
866
+ type: 'red'
867
+ });
868
+ }
869
+ //===========================================================================================
870
+ //===========================================================================================