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