@fui-org/fui-cli 2.1.4 → 2.2.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 (214) hide show
  1. package/README.md +16 -7
  2. package/dist/fui-xg17j3f9.js +396 -0
  3. package/dist/fui.js +1 -1
  4. package/package.json +1 -1
  5. package/skills/fui/SKILL.md +152 -39
  6. package/skills/{fui-skill → fui}/assets/projectdefaultstyle.css +489 -489
  7. package/skills/{fui-skill → fui}/examples/component.vue +162 -162
  8. package/skills/{fui-skill → fui}/references/INDEX.md +4 -5
  9. package/skills/{fui-skill → fui}/references/advanced-techniques.md +170 -168
  10. package/skills/{fui-skill → fui}/references/component-design.md +2 -2
  11. package/skills/{fui-skill → fui}/references/component-quickref.md +78 -78
  12. package/skills/{fui-skill → fui}/references/component-table.md +287 -287
  13. package/skills/{fui-skill → fui}/references/components-dialog.md +191 -191
  14. package/skills/{fui-skill → fui}/references/components-display.md +141 -141
  15. package/skills/{fui-skill → fui}/references/components-echart.md +316 -316
  16. package/skills/{fui-skill → fui}/references/components-input.md +335 -335
  17. package/skills/{fui-skill → fui}/references/controls-patterns.md +2 -2
  18. package/skills/{fui-skill → fui}/references/controls-styling-vocabulary.md +173 -173
  19. package/skills/{fui-skill → fui}/references/db-workflow.md +9 -9
  20. package/skills/{fui-skill → fui}/references/default-function.md +456 -456
  21. package/skills/{fui-skill → fui}/references/design-modes.md +57 -57
  22. package/skills/{fui-skill → fui}/references/echart-templates.md +489 -489
  23. package/skills/{fui-skill → fui}/references/fastproject.md +99 -99
  24. package/skills/{fui-skill → fui}/references/fullstack-workflow.md +314 -313
  25. package/skills/{fui-skill → fui}/references/module-data-patterns.md +117 -117
  26. package/skills/{fui-skill → fui}/references/module-json-anatomy.md +132 -132
  27. package/skills/{fui-skill → fui}/references/module-structure.md +144 -144
  28. package/skills/{fui-skill → fui}/references/new-session.md +3 -20
  29. package/skills/{fui-skill → fui}/references/pdfmake.md +60 -60
  30. package/skills/{fui-skill → fui}/references/permission-system.md +1 -1
  31. package/skills/{fui-skill → fui}/references/platform-architecture.md +269 -269
  32. package/skills/{fui-skill → fui}/references/project-config.md +303 -303
  33. package/skills/{fui-skill → fui}/references/project-provisioning.md +4 -4
  34. package/skills/{fui-skill → fui}/references/script-map.md +262 -262
  35. package/skills/{fui-skill → fui}/references/sql-clr-functions.md +225 -225
  36. package/skills/{fui-skill → fui}/references/system-design.md +3 -3
  37. package/skills/{fui-skill → fui}/references/tapi-permission-patterns.md +156 -156
  38. package/skills/{fui-skill → fui}/references/tapi-reference.md +474 -474
  39. package/skills/fui/references/tools-registry.md +214 -0
  40. package/skills/{fui-skill → fui}/references/ui-crosswindow-patterns.md +321 -321
  41. package/skills/{fui-skill → fui}/references/ui-dialog-patterns.md +255 -255
  42. package/skills/{fui-skill → fui}/references/ui-layout-patterns.md +176 -176
  43. package/skills/{fui-skill → fui}/references/ui-patterns.md +303 -303
  44. package/skills/{fui-skill → fui}/references/ui-screenshot-review.md +95 -95
  45. package/skills/{fui-skill → fui}/references/ui-table-cell-patterns.md +318 -318
  46. package/skills/{fui-skill → fui}/references/verification.md +18 -18
  47. package/skills/{fui-skill → fui}/references/watcher-patterns.md +163 -163
  48. package/skills/{fui-skill → fui}/references/websocket-realtime.md +271 -271
  49. package/skills/{fui-skill → fui}/scripts/component-3.0.js +2715 -2715
  50. package/skills/{fui-skill → fui}/scripts/component.js +3147 -3147
  51. package/skills/{fui-skill → fui}/scripts/componentTable-3.0.js +1038 -1038
  52. package/skills/{fui-skill → fui}/scripts/componentTable.js +891 -891
  53. package/skills/{fui-skill → fui}/scripts/defaultfunction-3.0.js +866 -866
  54. package/skills/{fui-skill → fui}/scripts/defaultfunction.js +1051 -1051
  55. package/skills/{fui-skill → fui}/scripts/fastproject-3.0.js +870 -870
  56. package/skills/{fui-skill → fui}/scripts/fastproject.js +828 -828
  57. package/dist/fui-h4z7zhk2.js +0 -381
  58. package/skills/fui-skill/SKILL.md +0 -139
  59. package/skills/fui-skill/references/tools-registry.md +0 -84
  60. /package/skills/{fui-skill → fui}/assets/projectdefaultstyle-3.0.css +0 -0
  61. /package/skills/{fui-skill → fui}/design-md/airbnb/DESIGN.md +0 -0
  62. /package/skills/{fui-skill → fui}/design-md/airbnb/README.md +0 -0
  63. /package/skills/{fui-skill → fui}/design-md/airtable/DESIGN.md +0 -0
  64. /package/skills/{fui-skill → fui}/design-md/airtable/README.md +0 -0
  65. /package/skills/{fui-skill → fui}/design-md/apple/DESIGN.md +0 -0
  66. /package/skills/{fui-skill → fui}/design-md/apple/README.md +0 -0
  67. /package/skills/{fui-skill → fui}/design-md/asu/DESIGN.md +0 -0
  68. /package/skills/{fui-skill → fui}/design-md/asu/README.md +0 -0
  69. /package/skills/{fui-skill → fui}/design-md/binance/DESIGN.md +0 -0
  70. /package/skills/{fui-skill → fui}/design-md/binance/README.md +0 -0
  71. /package/skills/{fui-skill → fui}/design-md/bmw/DESIGN.md +0 -0
  72. /package/skills/{fui-skill → fui}/design-md/bmw/README.md +0 -0
  73. /package/skills/{fui-skill → fui}/design-md/bmw-m/DESIGN.md +0 -0
  74. /package/skills/{fui-skill → fui}/design-md/bmw-m/README.md +0 -0
  75. /package/skills/{fui-skill → fui}/design-md/bugatti/DESIGN.md +0 -0
  76. /package/skills/{fui-skill → fui}/design-md/bugatti/README.md +0 -0
  77. /package/skills/{fui-skill → fui}/design-md/cal/DESIGN.md +0 -0
  78. /package/skills/{fui-skill → fui}/design-md/cal/README.md +0 -0
  79. /package/skills/{fui-skill → fui}/design-md/claude/DESIGN.md +0 -0
  80. /package/skills/{fui-skill → fui}/design-md/claude/README.md +0 -0
  81. /package/skills/{fui-skill → fui}/design-md/clay/DESIGN.md +0 -0
  82. /package/skills/{fui-skill → fui}/design-md/clay/README.md +0 -0
  83. /package/skills/{fui-skill → fui}/design-md/clickhouse/DESIGN.md +0 -0
  84. /package/skills/{fui-skill → fui}/design-md/clickhouse/README.md +0 -0
  85. /package/skills/{fui-skill → fui}/design-md/cohere/DESIGN.md +0 -0
  86. /package/skills/{fui-skill → fui}/design-md/cohere/README.md +0 -0
  87. /package/skills/{fui-skill → fui}/design-md/coinbase/DESIGN.md +0 -0
  88. /package/skills/{fui-skill → fui}/design-md/coinbase/README.md +0 -0
  89. /package/skills/{fui-skill → fui}/design-md/composio/DESIGN.md +0 -0
  90. /package/skills/{fui-skill → fui}/design-md/composio/README.md +0 -0
  91. /package/skills/{fui-skill → fui}/design-md/cursor/DESIGN.md +0 -0
  92. /package/skills/{fui-skill → fui}/design-md/cursor/README.md +0 -0
  93. /package/skills/{fui-skill → fui}/design-md/elevenlabs/DESIGN.md +0 -0
  94. /package/skills/{fui-skill → fui}/design-md/elevenlabs/README.md +0 -0
  95. /package/skills/{fui-skill → fui}/design-md/expo/DESIGN.md +0 -0
  96. /package/skills/{fui-skill → fui}/design-md/expo/README.md +0 -0
  97. /package/skills/{fui-skill → fui}/design-md/ferrari/DESIGN.md +0 -0
  98. /package/skills/{fui-skill → fui}/design-md/ferrari/README.md +0 -0
  99. /package/skills/{fui-skill → fui}/design-md/figma/DESIGN.md +0 -0
  100. /package/skills/{fui-skill → fui}/design-md/figma/README.md +0 -0
  101. /package/skills/{fui-skill → fui}/design-md/framer/DESIGN.md +0 -0
  102. /package/skills/{fui-skill → fui}/design-md/framer/README.md +0 -0
  103. /package/skills/{fui-skill → fui}/design-md/fui/DESIGN.md +0 -0
  104. /package/skills/{fui-skill → fui}/design-md/hashicorp/DESIGN.md +0 -0
  105. /package/skills/{fui-skill → fui}/design-md/hashicorp/README.md +0 -0
  106. /package/skills/{fui-skill → fui}/design-md/ibm/DESIGN.md +0 -0
  107. /package/skills/{fui-skill → fui}/design-md/ibm/README.md +0 -0
  108. /package/skills/{fui-skill → fui}/design-md/intercom/DESIGN.md +0 -0
  109. /package/skills/{fui-skill → fui}/design-md/intercom/README.md +0 -0
  110. /package/skills/{fui-skill → fui}/design-md/kraken/DESIGN.md +0 -0
  111. /package/skills/{fui-skill → fui}/design-md/kraken/README.md +0 -0
  112. /package/skills/{fui-skill → fui}/design-md/lamborghini/DESIGN.md +0 -0
  113. /package/skills/{fui-skill → fui}/design-md/lamborghini/README.md +0 -0
  114. /package/skills/{fui-skill → fui}/design-md/linear.app/DESIGN.md +0 -0
  115. /package/skills/{fui-skill → fui}/design-md/linear.app/README.md +0 -0
  116. /package/skills/{fui-skill → fui}/design-md/lovable/DESIGN.md +0 -0
  117. /package/skills/{fui-skill → fui}/design-md/lovable/README.md +0 -0
  118. /package/skills/{fui-skill → fui}/design-md/mastercard/DESIGN.md +0 -0
  119. /package/skills/{fui-skill → fui}/design-md/mastercard/README.md +0 -0
  120. /package/skills/{fui-skill → fui}/design-md/meta/DESIGN.md +0 -0
  121. /package/skills/{fui-skill → fui}/design-md/meta/README.md +0 -0
  122. /package/skills/{fui-skill → fui}/design-md/minimax/DESIGN.md +0 -0
  123. /package/skills/{fui-skill → fui}/design-md/minimax/README.md +0 -0
  124. /package/skills/{fui-skill → fui}/design-md/mintlify/DESIGN.md +0 -0
  125. /package/skills/{fui-skill → fui}/design-md/mintlify/README.md +0 -0
  126. /package/skills/{fui-skill → fui}/design-md/miro/DESIGN.md +0 -0
  127. /package/skills/{fui-skill → fui}/design-md/miro/README.md +0 -0
  128. /package/skills/{fui-skill → fui}/design-md/mistral.ai/DESIGN.md +0 -0
  129. /package/skills/{fui-skill → fui}/design-md/mistral.ai/README.md +0 -0
  130. /package/skills/{fui-skill → fui}/design-md/mongodb/DESIGN.md +0 -0
  131. /package/skills/{fui-skill → fui}/design-md/mongodb/README.md +0 -0
  132. /package/skills/{fui-skill → fui}/design-md/nike/DESIGN.md +0 -0
  133. /package/skills/{fui-skill → fui}/design-md/nike/README.md +0 -0
  134. /package/skills/{fui-skill → fui}/design-md/notion/DESIGN.md +0 -0
  135. /package/skills/{fui-skill → fui}/design-md/notion/README.md +0 -0
  136. /package/skills/{fui-skill → fui}/design-md/nvidia/DESIGN.md +0 -0
  137. /package/skills/{fui-skill → fui}/design-md/nvidia/README.md +0 -0
  138. /package/skills/{fui-skill → fui}/design-md/ollama/DESIGN.md +0 -0
  139. /package/skills/{fui-skill → fui}/design-md/ollama/README.md +0 -0
  140. /package/skills/{fui-skill → fui}/design-md/opencode.ai/DESIGN.md +0 -0
  141. /package/skills/{fui-skill → fui}/design-md/opencode.ai/README.md +0 -0
  142. /package/skills/{fui-skill → fui}/design-md/pinterest/DESIGN.md +0 -0
  143. /package/skills/{fui-skill → fui}/design-md/pinterest/README.md +0 -0
  144. /package/skills/{fui-skill → fui}/design-md/playstation/DESIGN.md +0 -0
  145. /package/skills/{fui-skill → fui}/design-md/playstation/README.md +0 -0
  146. /package/skills/{fui-skill → fui}/design-md/posthog/DESIGN.md +0 -0
  147. /package/skills/{fui-skill → fui}/design-md/posthog/README.md +0 -0
  148. /package/skills/{fui-skill → fui}/design-md/raycast/DESIGN.md +0 -0
  149. /package/skills/{fui-skill → fui}/design-md/raycast/README.md +0 -0
  150. /package/skills/{fui-skill → fui}/design-md/renault/DESIGN.md +0 -0
  151. /package/skills/{fui-skill → fui}/design-md/renault/README.md +0 -0
  152. /package/skills/{fui-skill → fui}/design-md/replicate/DESIGN.md +0 -0
  153. /package/skills/{fui-skill → fui}/design-md/replicate/README.md +0 -0
  154. /package/skills/{fui-skill → fui}/design-md/resend/DESIGN.md +0 -0
  155. /package/skills/{fui-skill → fui}/design-md/resend/README.md +0 -0
  156. /package/skills/{fui-skill → fui}/design-md/revolut/DESIGN.md +0 -0
  157. /package/skills/{fui-skill → fui}/design-md/revolut/README.md +0 -0
  158. /package/skills/{fui-skill → fui}/design-md/runwayml/DESIGN.md +0 -0
  159. /package/skills/{fui-skill → fui}/design-md/runwayml/README.md +0 -0
  160. /package/skills/{fui-skill → fui}/design-md/sanity/DESIGN.md +0 -0
  161. /package/skills/{fui-skill → fui}/design-md/sanity/README.md +0 -0
  162. /package/skills/{fui-skill → fui}/design-md/sentry/DESIGN.md +0 -0
  163. /package/skills/{fui-skill → fui}/design-md/sentry/README.md +0 -0
  164. /package/skills/{fui-skill → fui}/design-md/shopify/DESIGN.md +0 -0
  165. /package/skills/{fui-skill → fui}/design-md/shopify/README.md +0 -0
  166. /package/skills/{fui-skill → fui}/design-md/slack/DESIGN.md +0 -0
  167. /package/skills/{fui-skill → fui}/design-md/spacex/DESIGN.md +0 -0
  168. /package/skills/{fui-skill → fui}/design-md/spacex/README.md +0 -0
  169. /package/skills/{fui-skill → fui}/design-md/spotify/DESIGN.md +0 -0
  170. /package/skills/{fui-skill → fui}/design-md/spotify/README.md +0 -0
  171. /package/skills/{fui-skill → fui}/design-md/starbucks/DESIGN.md +0 -0
  172. /package/skills/{fui-skill → fui}/design-md/starbucks/README.md +0 -0
  173. /package/skills/{fui-skill → fui}/design-md/stripe/DESIGN.md +0 -0
  174. /package/skills/{fui-skill → fui}/design-md/stripe/README.md +0 -0
  175. /package/skills/{fui-skill → fui}/design-md/supabase/DESIGN.md +0 -0
  176. /package/skills/{fui-skill → fui}/design-md/supabase/README.md +0 -0
  177. /package/skills/{fui-skill → fui}/design-md/superhuman/DESIGN.md +0 -0
  178. /package/skills/{fui-skill → fui}/design-md/superhuman/README.md +0 -0
  179. /package/skills/{fui-skill → fui}/design-md/tesla/DESIGN.md +0 -0
  180. /package/skills/{fui-skill → fui}/design-md/tesla/README.md +0 -0
  181. /package/skills/{fui-skill → fui}/design-md/theverge/DESIGN.md +0 -0
  182. /package/skills/{fui-skill → fui}/design-md/theverge/README.md +0 -0
  183. /package/skills/{fui-skill → fui}/design-md/together.ai/DESIGN.md +0 -0
  184. /package/skills/{fui-skill → fui}/design-md/together.ai/README.md +0 -0
  185. /package/skills/{fui-skill → fui}/design-md/uber/DESIGN.md +0 -0
  186. /package/skills/{fui-skill → fui}/design-md/uber/README.md +0 -0
  187. /package/skills/{fui-skill → fui}/design-md/vercel/DESIGN.md +0 -0
  188. /package/skills/{fui-skill → fui}/design-md/vercel/README.md +0 -0
  189. /package/skills/{fui-skill → fui}/design-md/vodafone/DESIGN.md +0 -0
  190. /package/skills/{fui-skill → fui}/design-md/vodafone/README.md +0 -0
  191. /package/skills/{fui-skill → fui}/design-md/voltagent/DESIGN.md +0 -0
  192. /package/skills/{fui-skill → fui}/design-md/voltagent/README.md +0 -0
  193. /package/skills/{fui-skill → fui}/design-md/warp/DESIGN.md +0 -0
  194. /package/skills/{fui-skill → fui}/design-md/warp/README.md +0 -0
  195. /package/skills/{fui-skill → fui}/design-md/webflow/DESIGN.md +0 -0
  196. /package/skills/{fui-skill → fui}/design-md/webflow/README.md +0 -0
  197. /package/skills/{fui-skill → fui}/design-md/wired/DESIGN.md +0 -0
  198. /package/skills/{fui-skill → fui}/design-md/wired/README.md +0 -0
  199. /package/skills/{fui-skill → fui}/design-md/wise/DESIGN.md +0 -0
  200. /package/skills/{fui-skill → fui}/design-md/wise/README.md +0 -0
  201. /package/skills/{fui-skill → fui}/design-md/x.ai/DESIGN.md +0 -0
  202. /package/skills/{fui-skill → fui}/design-md/x.ai/README.md +0 -0
  203. /package/skills/{fui-skill → fui}/design-md/zapier/DESIGN.md +0 -0
  204. /package/skills/{fui-skill → fui}/design-md/zapier/README.md +0 -0
  205. /package/skills/{fui-skill → fui}/examples/f-table-patterns.json +0 -0
  206. /package/skills/{fui-skill → fui}/examples/module-patterns.json +0 -0
  207. /package/skills/{fui-skill → fui}/examples/project-patterns.json +0 -0
  208. /package/skills/{fui-skill → fui}/references/coding-standards.md +0 -0
  209. /package/skills/{fui-skill → fui}/references/db-table-design.md +0 -0
  210. /package/skills/{fui-skill → fui}/references/fsheet.md +0 -0
  211. /package/skills/{fui-skill → fui}/references/tapi-file-api.md +0 -0
  212. /package/skills/{fui-skill → fui}/references/ui-templates.md +0 -0
  213. /package/skills/{fui-skill → fui}/scripts/fechart.js +0 -0
  214. /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
+ //===========================================================================================