Viewer.js 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004
  1. MWF.xApplication.process = MWF.xApplication.process || {};
  2. MWF.xApplication.process.Application = MWF.xApplication.process.Application || {};
  3. MWF.require("MWF.widget.Common", null, false);
  4. MWF.require("MWF.xScript.Macro", null, false);
  5. MWF.xDesktop.requireApp("process.Application", "lp.zh-cn", null, false);
  6. MWF.xApplication.process.Application.Viewer = new Class({
  7. Implements: [Options, Events],
  8. Extends: MWF.widget.Common,
  9. options: {
  10. "style": "default",
  11. "resizeNode": true,
  12. "actions": {
  13. "lookup": {"uri": "/jaxrs/queryview/flag/{view}/application/flag/{application}/execute", "method":"PUT"},
  14. "getView": {"uri": "/jaxrs/queryview/flag/{view}/application/flag/{application}"},
  15. "listWorkByJob": {"uri": "/jaxrs/job/{job}/find/work/workcompleted"},
  16. "listTaskByWork": {"uri": "/jaxrs/work/{id}/assignment/manage"}
  17. },
  18. "actionRoot": "x_processplatform_assemble_surface"
  19. },
  20. initialize: function(container, json, options){
  21. this.setOptions(options);
  22. this.path = "/x_component_process_Application/$Viewer/";
  23. this.cssPath = "/x_component_process_Application/$Viewer/"+this.options.style+"/css.wcss";
  24. this._loadCss();
  25. this.lp = MWF.xApplication.process.Application.LP;
  26. this.container = $(container);
  27. this.json = json;
  28. this.viewJson = null;
  29. this.filterItems = [];
  30. this.searchStatus = "none"; //none, custom, default
  31. this.items = [];
  32. this.selectedItems = [];
  33. this.hideColumns = [];
  34. this.openColumns = [];
  35. this.gridJson = null;
  36. this.init(function(){
  37. this.load();
  38. }.bind(this));
  39. },
  40. init: function(callback){
  41. debugger;
  42. if (this.json.data){
  43. this.viewJson = JSON.decode(this.json.data);
  44. if (callback) callback();
  45. }else{
  46. this.getView(callback);
  47. }
  48. },
  49. load: function(){
  50. this.loadLayout();
  51. this.createSearchNode();
  52. this.createViewNode({"filterList": this.json.filter || null});
  53. if (this.options.resizeNode){
  54. this.setContentHeightFun = this.setContentHeight.bind(this);
  55. this.container.addEvent("resize", this.setContentHeightFun);
  56. this.setContentHeightFun();
  57. }
  58. },
  59. loadLayout: function(){
  60. this.node = new Element("div", {"styles": this.css.node}).inject(this.container);
  61. this.searchAreaNode = new Element("div", {"styles": this.css.searchAreaNode}).inject(this.node);
  62. this.viewAreaNode = new Element("div", {"styles": this.css.viewAreaNode}).inject(this.node);
  63. },
  64. createSearchNode: function(){
  65. if (this.viewJson.customFilterEntryList && this.viewJson.customFilterEntryList.length){
  66. this.searchStatus = "default";
  67. this.loadFilterSearch();
  68. }else{
  69. this.loadSimpleSearch();
  70. }
  71. },
  72. loadSimpleSearch: function(){
  73. this.searchSimpleNode = new Element("div", {"styles": this.css.searchSimpleNode}).inject(this.searchAreaNode);
  74. this.searchSimpleButtonNode = new Element("div", {"styles": this.css.searchSimpleButtonNode}).inject(this.searchSimpleNode);
  75. this.searchSimpleInputNode = new Element("input", {"type":"text", "styles": this.css.searchSimpleInputNode, "value": this.lp.searchKeywork}).inject(this.searchSimpleNode);
  76. this.searchSimpleButtonNode.addEvent("click", function(){
  77. this.search();
  78. }.bind(this));
  79. this.searchSimpleInputNode.addEvents({
  80. "focus": function(){
  81. if (this.searchSimpleInputNode.get("value")===this.lp.searchKeywork) this.searchSimpleInputNode.set("value", "");
  82. }.bind(this),
  83. "blur": function(){if (!this.searchSimpleInputNode.get("value")) this.searchSimpleInputNode.set("value", this.lp.searchKeywork);}.bind(this),
  84. "keydown": function(e){
  85. if (e.code===13) this.search();
  86. }.bind(this)
  87. });
  88. },
  89. search: function(){
  90. if (this.gridJson){
  91. var key = this.searchSimpleInputNode.get("value");
  92. var rows = this.viewTable.rows;
  93. var first = (this.json.isTitle!=="no") ? 1 : 0;
  94. for (var i = first; i<rows.length; i++){
  95. var tr = rows[i];
  96. if (!key || key==this.lp.searchKeywork){
  97. if (tr.getStyle("display")==="none") tr.setStyle("display", "table-row");
  98. }else{
  99. if (tr.get("text").indexOf(key)!==-1){
  100. if (tr.getStyle("display")==="none") tr.setStyle("display", "table-row");
  101. }else{
  102. if (tr.getStyle("display")!=="none") tr.setStyle("display", "none");
  103. }
  104. }
  105. }
  106. }
  107. },
  108. loadFilterSearch: function(){
  109. this.viewSearchCustomActionNode = new Element("div", {"styles": this.css.viewFilterSearchCustomActionNode, "text": this.lp.customSearch}).inject(this.searchAreaNode);
  110. this.viewSearchInputAreaNode = new Element("div", {"styles": this.css.viewFilterSearchInputAreaNode}).inject(this.searchAreaNode);
  111. this.viewSearchIconNode = new Element("div", {"styles": this.css.viewFilterSearchIconNode}).inject(this.viewSearchInputAreaNode);
  112. this.viewSearchInputBoxNode = new Element("div", {"styles": this.css.viewFilterSearchInputBoxNode}).inject(this.viewSearchInputAreaNode);
  113. this.viewSearchInputNode = new Element("input", {"styles": this.css.viewFilterSearchInputNode, "value": this.lp.searchKeywork}).inject(this.viewSearchInputBoxNode);
  114. this.viewSearchInputNode.addEvents({
  115. "focus": function(){
  116. if (this.viewSearchInputNode.get("value")===this.lp.searchKeywork) this.viewSearchInputNode.set("value", "");
  117. }.bind(this),
  118. "blur": function(){if (!this.viewSearchInputNode.get("value")) this.viewSearchInputNode.set("value", this.lp.searchKeywork);}.bind(this),
  119. "keydown": function(e){
  120. if (e.code===13) this.searchView();
  121. }.bind(this)
  122. });
  123. this.viewSearchIconNode.addEvents({
  124. "click": function(){this.searchView();}.bind(this)
  125. });
  126. this.viewSearchCustomActionNode.addEvents({
  127. "click": function(){this.loadCustomSearch();}.bind(this)
  128. });
  129. },
  130. searchView: function(){
  131. if (this.viewJson.customFilterEntryList){
  132. var key = this.viewSearchInputNode.get("value");
  133. if (key && key!==this.lp.searchKeywork){
  134. var filterData = this.json.filter || [];
  135. this.viewJson.customFilterEntryList.each(function(entry){
  136. if (entry.formatType==="textValue"){
  137. var d = {
  138. "path": entry.path,
  139. "value": key,
  140. "formatType": entry.formatType,
  141. "logic": "or",
  142. "comparison": "like"
  143. };
  144. filterData.push(d);
  145. }
  146. if (entry.formatType==="numberValue"){
  147. var v = key.toFloat();
  148. if (!isNaN(v)){
  149. var d = {
  150. "path": entry.path,
  151. "value": v,
  152. "formatType": entry.formatType,
  153. "logic": "or",
  154. "comparison": "like"
  155. };
  156. filterData.push(d);
  157. }
  158. }
  159. }.bind(this));
  160. this.createViewNode({"filterList": filterData});
  161. }
  162. }
  163. },
  164. searchCustomView: function(){
  165. if (this.filterItems.length){
  166. var filterData = this.json.filter || [];
  167. this.filterItems.each(function(filter){
  168. filterData.push(filter.data);
  169. }.bind(this));
  170. this.createViewNode({"filterList": filterData});
  171. }else{
  172. this.createViewNode({"filterList": this.json.filter || null});
  173. }
  174. },
  175. loadCustomSearch: function(){
  176. this.viewSearchIconNode.setStyle("display", "none");
  177. this.viewSearchInputBoxNode.setStyle("display", "none");
  178. this.viewSearchCustomActionNode.setStyle("display", "none");
  179. if (!this.searchMorph) this.searchMorph = new Fx.Morph(this.viewSearchInputAreaNode);
  180. var x = this.viewSearchInputAreaNode.getParent().getSize().x-2-20;
  181. this.css.viewFilterSearchInputAreaNode_custom.width = ""+x+"px";
  182. var x1 = this.viewSearchInputAreaNode.getSize().x-2;
  183. this.viewSearchInputAreaNode.setStyle("width", ""+x1+"px");
  184. this.searchMorph.start(this.css.viewFilterSearchInputAreaNode_custom).chain(function(){
  185. this.searchStatus = "custom";
  186. this.css.viewFilterSearchInputAreaNode_custom.width = "auto";
  187. this.viewSearchInputAreaNode.setStyle("width", "auto");
  188. if (this.viewSearchCustomContentNode){
  189. this.viewSearchCustomCloseActionNode.setStyle("display", "block");
  190. this.viewSearchCustomContentNode.setStyle("display", "block");
  191. }else{
  192. this.loadCustomSearchContent();
  193. }
  194. this.setContentHeightFun();
  195. }.bind(this));
  196. this.searchCustomView();
  197. },
  198. loadCustomSearchContent: function(){
  199. this.viewSearchCustomCloseActionNode = new Element("div", {"styles": this.css.viewFilterSearchCustomCloseActionNode}).inject(this.viewSearchInputAreaNode);
  200. this.viewSearchCustomContentNode = new Element("div", {"styles": this.css.viewFilterSearchCustomContentNode}).inject(this.viewSearchInputAreaNode);
  201. this.viewSearchCustomPathContentNode = new Element("div", {"styles": this.css.viewFilterSearchCustomPathContentNode}).inject(this.viewSearchCustomContentNode);
  202. this.viewSearchCustomComparisonContentNode = new Element("div", {"styles": this.css.viewFilterSearchCustomComparisonContentNode}).inject(this.viewSearchCustomContentNode);
  203. this.viewSearchCustomValueContentNode = new Element("div", {"styles": this.css.viewFilterSearchCustomValueContentNode}).inject(this.viewSearchCustomContentNode);
  204. this.viewSearchCustomAddContentNode = new Element("div", {"styles": this.css.viewFilterSearchCustomAddContentNode}).inject(this.viewSearchCustomContentNode);
  205. this.viewSearchCustomAddIconNode = new Element("div", {"styles": this.css.viewFilterSearchCustomAddIconNode}).inject(this.viewSearchCustomAddContentNode);
  206. this.viewSearchCustomFilterContentNode = new Element("div", {"styles": this.css.viewFilterSearchCustomFilterContentNode}).inject(this.viewSearchCustomContentNode);
  207. this.loadViewSearchCustomList();
  208. this.viewSearchCustomCloseActionNode.addEvents({
  209. "click": function(){this.closeCustomSearch();}.bind(this)
  210. });
  211. this.viewSearchCustomAddIconNode.addEvents({
  212. "click": function(){this.viewSearchCustomAddToFilter();}.bind(this)
  213. });
  214. },
  215. loadViewSearchCustomList: function(){
  216. this.viewSearchCustomPathListNode = new Element("select", {
  217. "styles": this.css.viewFilterSearchCustomPathListNode,
  218. "multiple": true
  219. }).inject(this.viewSearchCustomPathContentNode);
  220. this.viewSearchCustomComparisonListNode = new Element("select", {
  221. "styles": this.css.viewFilterSearchCustomComparisonListNode,
  222. "multiple": true
  223. }).inject(this.viewSearchCustomComparisonContentNode);
  224. this.viewJson.customFilterEntryList.each(function(entry){
  225. var option = new Element("option", {
  226. "style": this.css.viewFilterSearchOptionNode,
  227. "value": entry.path,
  228. "text": entry.title
  229. }).inject(this.viewSearchCustomPathListNode);
  230. option.store("entry", entry);
  231. }.bind(this));
  232. this.viewSearchCustomPathListNode.addEvent("change", function(){
  233. this.loadViewSearchCustomComparisonList();
  234. }.bind(this));
  235. },
  236. loadViewSearchCustomComparisonList: function(){
  237. var idx = this.viewSearchCustomPathListNode.selectedIndex;
  238. var option = this.viewSearchCustomPathListNode.options[idx];
  239. var entry = option.retrieve("entry");
  240. if (entry){
  241. switch (entry.formatType){
  242. case "numberValue":
  243. this.loadComparisonSelect(this.lp.numberFilter);
  244. this.loadViewSearchCustomValueNumberInput();
  245. break;
  246. case "dateTimeValue":
  247. this.loadComparisonSelect(this.lp.dateFilter);
  248. this.loadViewSearchCustomValueDateInput();
  249. break;
  250. case "booleanValue":
  251. this.loadComparisonSelect(this.lp.booleanFilter);
  252. this.loadViewSearchCustomValueBooleanInput();
  253. break;
  254. default:
  255. this.loadComparisonSelect(this.lp.textFilter);
  256. this.loadViewSearchCustomValueTextInput();
  257. }
  258. }
  259. },
  260. loadViewSearchCustomValueNumberInput: function(){
  261. this.viewSearchCustomValueContentNode.empty();
  262. this.viewSearchCustomValueNode = new Element("input", {
  263. "styles": this.css.viewFilterSearchCustomValueNode,
  264. "type": "number"
  265. }).inject(this.viewSearchCustomValueContentNode);
  266. },
  267. loadViewSearchCustomValueDateInput: function(){
  268. this.viewSearchCustomValueContentNode.empty();
  269. this.viewSearchCustomValueNode = new Element("input", {
  270. "styles": this.css.viewFilterSearchCustomValueNode,
  271. "type": "text",
  272. "readonly": true
  273. }).inject(this.viewSearchCustomValueContentNode);
  274. MWF.require("MWF.widget.Calendar", function(){
  275. this.calendar = new MWF.widget.Calendar(this.viewSearchCustomValueNode, {
  276. "style": "xform",
  277. "isTime": true,
  278. "target": this.container,
  279. "format": "db"
  280. });
  281. }.bind(this));
  282. },
  283. loadViewSearchCustomValueBooleanInput: function(){
  284. this.viewSearchCustomValueContentNode.empty();
  285. this.viewSearchCustomValueNode = new Element("select", {
  286. "styles": this.css.viewFilterSearchCustomValueSelectNode,
  287. "multiple": true
  288. }).inject(this.viewSearchCustomValueContentNode);
  289. new Element("option", {"value": "true","text": this.lp.yes}).inject(this.viewSearchCustomValueNode);
  290. new Element("option", {"value": "false","text": this.lp.no}).inject(this.viewSearchCustomValueNode);
  291. },
  292. loadViewSearchCustomValueTextInput: function(){
  293. this.viewSearchCustomValueContentNode.empty();
  294. this.viewSearchCustomValueNode = new Element("textarea", {
  295. "styles": this.css.viewFilterSearchCustomValueNode
  296. }).inject(this.viewSearchCustomValueContentNode);
  297. },
  298. loadComparisonSelect:function(obj){
  299. this.viewSearchCustomComparisonListNode.empty();
  300. Object.each(obj, function(v, k){
  301. var option = new Element("option", {"value": k,"text": v}).inject(this.viewSearchCustomComparisonListNode);
  302. }.bind(this));
  303. },
  304. closeCustomSearch: function(){
  305. if (this.viewSearchCustomContentNode && this.viewSearchCustomContentNode.getStyle("display")==="block"){
  306. this.viewSearchCustomCloseActionNode.setStyle("display", "none");
  307. this.viewSearchCustomContentNode.setStyle("display", "none");
  308. var x = this.viewSearchInputAreaNode.getParent().getSize().x;
  309. x1 = x-2-10-90;
  310. this.css.viewFilterSearchInputAreaNode.width = ""+x1+"px";
  311. var x1 = this.viewSearchInputAreaNode.getSize().x-2;
  312. this.viewSearchInputAreaNode.setStyle("width", ""+x1+"px");
  313. if (!this.searchMorph) this.searchMorph = new Fx.Morph(this.viewSearchInputAreaNode);
  314. this.searchMorph.start(this.css.viewFilterSearchInputAreaNode).chain(function(){
  315. this.searchStatus = "default";
  316. this.css.viewFilterSearchInputAreaNode.width = "auto";
  317. this.viewSearchInputAreaNode.setStyle("margin-right", "90px");
  318. this.viewSearchIconNode.setStyle("display", "block");
  319. this.viewSearchInputBoxNode.setStyle("display", "block");
  320. this.viewSearchCustomActionNode.setStyle("display", "block");
  321. this.setContentHeightFun();
  322. }.bind(this));
  323. this.createViewNode({"filterList": this.json.filter || null});
  324. }
  325. },
  326. viewSearchCustomAddToFilter: function(){
  327. var pathIdx = this.viewSearchCustomPathListNode.selectedIndex;
  328. var comparisonIdx = this.viewSearchCustomComparisonListNode.selectedIndex;
  329. if (pathIdx===-1){
  330. MWF.xDesktop.notice("error", {"x": "left", "y": "top"}, this.lp.filterErrorTitle, this.viewSearchCustomPathListNode, {"x": 0, "y": 85});
  331. return false;
  332. }
  333. if (comparisonIdx===-1){
  334. MWF.xDesktop.notice("error", {"x": "left", "y": "top"}, this.lp.filterErrorComparison, this.viewSearchCustomComparisonListNode, {"x": 0, "y": 85});
  335. return false;
  336. }
  337. var pathOption = this.viewSearchCustomPathListNode.options[pathIdx];
  338. var entry = pathOption.retrieve("entry");
  339. if (entry){
  340. var pathTitle = entry.title;
  341. var path = entry.path;
  342. var comparison = this.viewSearchCustomComparisonListNode.options[comparisonIdx].get("value");
  343. var comparisonTitle = this.viewSearchCustomComparisonListNode.options[comparisonIdx].get("text");
  344. var value = "";
  345. switch (entry.formatType){
  346. case "numberValue":
  347. value = this.viewSearchCustomValueNode.get("value");
  348. break;
  349. case "dateTimeValue":
  350. value = this.viewSearchCustomValueNode.get("value");
  351. break;
  352. case "booleanValue":
  353. var idx = this.viewSearchCustomValueNode.selectedIndex;
  354. if (idx!==-1){
  355. var v = this.viewSearchCustomValueNode.options[idx].get("value");
  356. value = (v==="true");
  357. }
  358. break;
  359. default:
  360. value = this.viewSearchCustomValueNode.get("value");
  361. }
  362. if (value===""){
  363. MWF.xDesktop.notice("error", {"x": "left", "y": "top"}, this.lp.filterErrorValue, this.viewSearchCustomValueContentNode, {"x": 0, "y": 85});
  364. return false;
  365. }
  366. this.filterItems.push(new MWF.xApplication.process.Application.Viewer.Filter(this, {
  367. "logic": "and",
  368. "path": path,
  369. "title": pathTitle,
  370. "comparison": comparison,
  371. "comparisonTitle": comparisonTitle,
  372. "value": value,
  373. "formatType": entry.formatType
  374. }, this.viewSearchCustomFilterContentNode));
  375. this.searchCustomView();
  376. }
  377. },
  378. searchViewRemoveFilter: function(filter){
  379. this.filterItems.erase(filter);
  380. filter.destroy();
  381. this.searchCustomView()
  382. },
  383. setContentHeight: function(){
  384. var size = this.node.getSize();
  385. var searchSize = this.searchAreaNode.getSize();
  386. var h = size.y-searchSize.y;
  387. this.viewAreaNode.setStyle("height", ""+h+"px");
  388. },
  389. createLoadding: function(){
  390. this.loadingAreaNode = new Element("div", {"styles": this.css.viewLoadingAreaNode}).inject(this.contentAreaNode);
  391. new Element("div", {"styles": {"height": "5px"}}).inject(this.loadingAreaNode);
  392. var loadingNode = new Element("div", {"styles": this.css.viewLoadingNode}).inject(this.loadingAreaNode);
  393. new Element("div", {"styles": this.css.viewLoadingIconNode}).inject(loadingNode);
  394. var loadingTextNode = new Element("div", {"styles": this.css.viewLoadingTextNode}).inject(loadingNode);
  395. loadingTextNode.set("text", "loading...");
  396. },
  397. createViewNode: function(data){
  398. this.viewAreaNode.empty();
  399. this.contentAreaNode = new Element("div", {"styles": this.css.contentAreaNode}).inject(this.viewAreaNode);
  400. this.viewTable = new Element("table", {
  401. "styles": this.css.viewTitleTableNode,
  402. "border": "0px",
  403. "cellPadding": "0",
  404. "cellSpacing": "0"
  405. }).inject(this.contentAreaNode);
  406. this.createLoadding();
  407. if (this.json.isTitle!=="no"){
  408. this.viewTitleLine = new Element("tr", {"styles": this.css.viewTitleLineNode}).inject(this.viewTable);
  409. //if (this.json.select==="single" || this.json.select==="multi") {
  410. this.selectTitleCell = new Element("td", {
  411. "styles": this.css.viewTitleCellNode
  412. }).inject(this.viewTitleLine);
  413. this.selectTitleCell.setStyle("width", "10px");
  414. if (this.json.titleStyles) this.selectTitleCell.setStyles(this.json.titleStyles);
  415. //}
  416. this.entries = {};
  417. this.viewJson.selectEntryList.each(function(column){
  418. this.entries[column.column] = column;
  419. if (!column.hideColumn){
  420. var viewCell = new Element("td", {
  421. "styles": this.css.viewTitleCellNode,
  422. "text": column.displayName
  423. }).inject(this.viewTitleLine);
  424. var size = MWF.getTextSize(column.displayName, this.css.viewTitleCellNode);
  425. viewCell.setStyle("min-width", ""+size.x+"px");
  426. if (this.json.titleStyles) viewCell.setStyles(this.json.titleStyles);
  427. }else{
  428. this.hideColumns.push(column.column);
  429. }
  430. if (column.allowOpen) this.openColumns.push(column.column);
  431. }.bind(this));
  432. this.lookup(data);
  433. }else{
  434. this.viewJson.selectEntryList.each(function(column){
  435. if (column.hideColumn) this.hideColumns.push(column.column);
  436. if (!column.allowOpen) this.openColumns.push(column.column);
  437. }.bind(this));
  438. this.lookup(data);
  439. }
  440. },
  441. lookup: function(data){
  442. this.getLookupAction(function(){
  443. if (this.json.application){
  444. this.lookupAction.invoke({"name": "lookup","async": true, "data": (data || null), "parameter": {"view": this.json.name, "application": this.json.application},"success": function(json){
  445. this.viewData = json.data;
  446. if (this.viewJson.groupEntry.column){
  447. this.gridJson = json.data.groupGrid;
  448. this.loadGroupData();
  449. }else{
  450. this.gridJson = json.data.grid;
  451. this.loadData();
  452. }
  453. if (this.loadingAreaNode){
  454. this.loadingAreaNode.destroy();
  455. this.loadingAreaNode = null;
  456. }
  457. }.bind(this)});
  458. }
  459. }.bind(this));
  460. },
  461. loadData: function(){
  462. if (this.gridJson.length){
  463. this.gridJson.each(function(line, i){
  464. this.items.push(new MWF.xApplication.process.Application.Viewer.Item(this, line, null, i));
  465. }.bind(this));
  466. }
  467. },
  468. loadGroupData: function(){
  469. if (this.selectTitleCell){
  470. this.selectTitleCell.set("html", "<span style='font-family: Webdings'>"+"<img src='/x_component_process_Application/$Viewer/"+this.options.style+"/icon/expand.png'/>"+"</span>");
  471. this.selectTitleCell.setStyle("cursor", "pointer");
  472. this.selectTitleCell.addEvent("click", this.expandOrCollapseAll.bind(this));
  473. }
  474. if (this.gridJson.length){
  475. this.gridJson.each(function(data){
  476. this.items.push(new MWF.xApplication.process.Application.Viewer.ItemCategory(this, data));
  477. }.bind(this));
  478. this.expandOrCollapseAll();
  479. }
  480. },
  481. expandOrCollapseAll: function(){
  482. var icon = this.selectTitleCell.getElement("span");
  483. if (icon.get("html").indexOf("expand.png")===-1){
  484. this.items.each(function(item){
  485. item.collapse();
  486. icon.set("html", "<img src='/x_component_process_Application/$Viewer/"+this.options.style+"/icon/expand.png'/>");
  487. }.bind(this));
  488. }else{
  489. this.items.each(function(item, i){
  490. window.setTimeout(function(){
  491. item.expand();
  492. }.bind(this), 10*i+5);
  493. icon.set("html", "<img src='/x_component_process_Application/$Viewer/"+this.options.style+"/icon/down.png'/>");
  494. }.bind(this));
  495. }
  496. },
  497. getView: function(callback){
  498. this.getLookupAction(function(){
  499. if (this.json.application){
  500. this.lookupAction.invoke({"name": "getView","async": true, "parameter": {"view": this.json.viewName, "application": this.json.application},"success": function(json){
  501. this.viewJson = JSON.decode(json.data.data);
  502. this.json = Object.merge(this.json, json.data);
  503. //var viewData = JSON.decode(json.data.data);
  504. if (callback) callback();
  505. }.bind(this)});
  506. }
  507. }.bind(this));
  508. },
  509. getLookupAction: function(callback){
  510. if (!this.lookupAction){
  511. var _self = this;
  512. MWF.require("MWF.xDesktop.Actions.RestActions", function(){
  513. this.lookupAction = new MWF.xDesktop.Actions.RestActions("", this.options.actionRoot, "");
  514. this.lookupAction.getActions = function(actionCallback){
  515. this.actions = _self.options.actions;
  516. if (actionCallback) actionCallback();
  517. };
  518. if (callback) callback();
  519. }.bind(this));
  520. }else{
  521. if (callback) callback();
  522. }
  523. },
  524. hide: function(){
  525. this.node.setStyle("display", "none");
  526. },
  527. reload: function(){
  528. this.node.setStyle("display", "block");
  529. if (this.loadingAreaNode) this.loadingAreaNode.setStyle("display", "block");
  530. this.filterItems.each(function(filter){
  531. filter.destroy();
  532. }.bind(this));
  533. this.filterItems = [];
  534. if (this.viewSearchInputNode) this.viewSearchInputNode.set("text", this.lp.searchKeywork);
  535. this.closeCustomSearch();
  536. this.viewAreaNode.empty();
  537. this.createViewNode({"filterList": this.json.filter || null});
  538. },
  539. getFilter: function(){
  540. debugger;
  541. var filterData = [];
  542. if (this.searchStatus==="custom"){
  543. if (this.filterItems.length){
  544. this.filterItems.each(function(filter){
  545. filterData.push(filter.data);
  546. }.bind(this));
  547. }
  548. }
  549. if (this.searchStatus==="default"){
  550. var key = this.viewSearchInputNode.get("value");
  551. if (key && key!==this.lp.searchKeywork){
  552. this.viewJson.customFilterEntryList.each(function(entry){
  553. if (entry.formatType==="textValue"){
  554. var d = {
  555. "path": entry.path,
  556. "value": key,
  557. "formatType": entry.formatType,
  558. "logic": "or",
  559. "comparison": "like"
  560. };
  561. filterData.push(d);
  562. }
  563. if (entry.formatType==="numberValue"){
  564. var v = key.toFloat();
  565. if (!isNaN(v)){
  566. var d = {
  567. "path": entry.path,
  568. "value": v,
  569. "formatType": entry.formatType,
  570. "logic": "or",
  571. "comparison": "like"
  572. };
  573. filterData.push(d);
  574. }
  575. }
  576. }.bind(this));
  577. }
  578. }
  579. return (filterData.length) ? filterData : null;
  580. },
  581. getData: function(){
  582. if (this.selectedItems.length){
  583. var arr = [];
  584. this.selectedItems.each(function(item){
  585. arr.push(item.data);
  586. });
  587. return arr;
  588. }else{
  589. return [];
  590. }
  591. }
  592. });
  593. MWF.xApplication.process.Application.Viewer.Item = new Class({
  594. initialize: function(view, data, prev, i){
  595. this.view = view;
  596. this.data = data;
  597. this.css = this.view.css;
  598. this.isSelected = false;
  599. this.prev = prev;
  600. this.load();
  601. },
  602. load: function(){
  603. this.node = new Element("tr", {"styles": this.css.viewContentTrNode});
  604. if (this.prev){
  605. this.node.inject(this.prev.node, "after");
  606. }else{
  607. this.node.inject(this.view.viewTable);
  608. }
  609. //if (this.view.json.select==="single" || this.view.json.select==="multi"){
  610. this.selectTd = new Element("td", {"styles": this.css.viewContentTdNode}).inject(this.node);
  611. this.selectTd.setStyles({"cursor": "pointer"});
  612. if (this.view.json.itemStyles) this.selectTd.setStyles(this.view.json.itemStyles);
  613. //}
  614. Object.each(this.data.data, function(cell, k){
  615. if (this.view.hideColumns.indexOf(k)===-1){
  616. var td = new Element("td", {"styles": this.css.viewContentTdNode}).inject(this.node);
  617. if (k!== this.view.viewJson.groupEntry.column){
  618. var v = (this.view.entries[k].code) ? MWF.Macro.exec(this.view.entries[k].code, {"value": cell, "gridData": this.view.gridJson, "data": this.view.viewData, "entry": this.data}) : cell
  619. td.set("text", v);
  620. }
  621. if (this.view.openColumns.indexOf(k)!==-1){
  622. this.setOpenWork(td)
  623. }
  624. if (this.view.json.itemStyles) td.setStyles(this.view.json.itemStyles);
  625. }
  626. }.bind(this));
  627. this.setEvent();
  628. },
  629. setOpenWork: function(td){
  630. td.setStyle("cursor", "pointer");
  631. td.addEvent("click", this.openWorkAndCompleted.bind(this));
  632. },
  633. openWorkAndCompleted: function(e){
  634. this.view.lookupAction.invoke({"name": "listWorkByJob","async": true, "parameter": {"job": this.data.job},"success": function(json){
  635. var workCompletedCount = json.data.workCompletedList.length;
  636. var workCount = json.data.workList.length;
  637. var count = workCount+workCompletedCount;
  638. if (count===1){
  639. if (workCompletedCount) {
  640. this.openWorkCompleted(json.data.workCompletedList[0].id, e);
  641. }else{
  642. this.openWork(json.data.workList[0].id, e);
  643. }
  644. }else if (count>1){
  645. var worksAreaNode = this.createWorksArea();
  646. json.data.workCompletedList.each(function(work){
  647. this.createWorkCompletedNode(work, worksAreaNode);
  648. }.bind(this));
  649. json.data.workList.each(function(work){
  650. this.createWorkNode(work, worksAreaNode);
  651. }.bind(this));
  652. this.showWorksArea(worksAreaNode, e);
  653. }else{
  654. }
  655. }.bind(this)});
  656. },
  657. createWorkNode: function(work, worksAreaNode){
  658. var worksAreaContentNode = worksAreaNode.getLast();
  659. var node = new Element("div", {"styles": this.css.workAreaNode}).inject(worksAreaContentNode);
  660. var actionNode = new Element("div", {"styles": this.css.workAreaActionNode, "text": this.view.lp.open}).inject(node);
  661. actionNode.store("workId", work.id);
  662. actionNode.addEvent("click", function(e){
  663. this.openWork(e.target.retrieve("workId"), e);
  664. this.mask.hide();
  665. worksAreaNode.destroy();
  666. }.bind(this));
  667. var areaNode = new Element("div", {"styles": this.css.workAreaLeftNode}).inject(node);
  668. var titleNode = new Element("div", {"styles": this.css.workAreaTitleNode, "text": work.title}).inject(areaNode);
  669. var contentNode = new Element("div", {"styles": this.css.workAreaContentNode}).inject(areaNode);
  670. new Element("div", {"styles": this.css.workAreaContentTitleNode, "text": this.view.lp.activity+": "}).inject(contentNode);
  671. new Element("div", {"styles": this.css.workAreaContentTextNode, "text": work.activityName}).inject(contentNode);
  672. var taskUsers = [];
  673. this.view.lookupAction.invoke({"name": "listTaskByWork","async": true, "parameter": {"id": work.id},"success": function(json){
  674. json.data.taskList.each(function(task){
  675. taskUsers.push(MWF.name.cn(task.person));
  676. }.bind(this));
  677. new Element("div", {"styles": this.css.workAreaContentTitleNode, "text": this.view.lp.taskPeople+": "}).inject(contentNode);
  678. new Element("div", {"styles": this.css.workAreaContentTextNode, "text": taskUsers.join(", ")}).inject(contentNode);
  679. }.bind(this)});
  680. },
  681. createWorkCompletedNode: function(work, worksAreaNode){
  682. var worksAreaContentNode = worksAreaNode.getLast();
  683. var node = new Element("div", {"styles": this.css.workAreaNode}).inject(worksAreaContentNode);
  684. var actionNode = new Element("div", {"styles": this.css.workAreaActionNode, "text": this.view.lp.open}).inject(node);
  685. actionNode.store("workId", work.id);
  686. actionNode.addEvent("click", function(e){
  687. this.mask.hide();
  688. worksAreaNode.destroy();
  689. this.openWorkCompleted(e.target.retrieve("workId"), e)
  690. }.bind(this));
  691. var areaNode = new Element("div", {"styles": this.css.workAreaLeftNode}).inject(node);
  692. var titleNode = new Element("div", {"styles": this.css.workAreaTitleNode, "text": work.title}).inject(areaNode);
  693. var contentNode = new Element("div", {"styles": this.css.workAreaContentNode}).inject(areaNode);
  694. new Element("div", {"styles": this.css.workAreaContentTitleNode, "text": this.view.lp.activity+": "}).inject(contentNode);
  695. new Element("div", {"styles": this.css.workAreaContentTextNode, "text": this.view.lp.processCompleted}).inject(contentNode);
  696. },
  697. createWorksArea: function(){
  698. var worksAreaNode = new Element("div", {"styles": this.css.worksAreaNode});
  699. var worksAreaTitleNode = new Element("div", {"styles": this.css.worksAreaTitleNode}).inject(worksAreaNode);
  700. var worksAreaTitleCloseNode = new Element("div", {"styles": this.css.worksAreaTitleCloseNode}).inject(worksAreaTitleNode);
  701. worksAreaTitleCloseNode.addEvent("click", function(e){
  702. this.mask.hide();
  703. e.target.getParent().getParent().destroy();
  704. }.bind(this));
  705. var worksAreaContentNode = new Element("div", {"styles": this.css.worksAreaContentNode}).inject(worksAreaNode);
  706. return worksAreaNode;
  707. },
  708. showWorksArea: function(node, e){
  709. this.mask = new MWF.widget.Mask({"style": "desktop", "loading": false});
  710. this.mask.loadNode(this.view.container);
  711. node.inject(this.view.node);
  712. this.setWorksAreaPosition(node, e.target);
  713. },
  714. setWorksAreaPosition: function(node, td){
  715. var p = td.getPosition(this.view.container);
  716. var containerS = this.view.container.getSize();
  717. var containerP = this.view.container.getPosition(this.view.container.getOffsetParent());
  718. var s = node.getSize();
  719. var offX = p.x+s.x-containerS.x;
  720. offX = (offX>0) ? offX+20 : 0;
  721. var offY = p.y+s.y-containerS.y;
  722. offY = (offY>0) ? offY+5 : 0;
  723. node.position({
  724. "relativeTo": td,
  725. "position": "lefttop",
  726. "edge": "lefttop",
  727. "offset": {
  728. "x": 0-offX,
  729. "y": 0-offY
  730. }
  731. });
  732. },
  733. openWork: function(id, e){
  734. var options = {"workId": id};
  735. layout.desktop.openApplication(e, "process.Work", options);
  736. },
  737. openWorkCompleted: function(id, e){
  738. var options = {"workCompletedId": id};
  739. layout.desktop.openApplication(e, "process.Work", options);
  740. },
  741. setEvent: function(){
  742. if (this.view.json.select==="single" || this.view.json.select==="multi"){
  743. this.node.addEvents({
  744. "mouseover": function(){
  745. if (!this.isSelected){
  746. var iconName = "checkbox";
  747. if (this.view.json.select==="single") iconName = "radiobox";
  748. this.selectTd.setStyles({"background": "url("+"/x_component_process_Application/$Viewer/default/icon/"+iconName+".png) center center no-repeat"});
  749. }
  750. }.bind(this),
  751. "mouseout": function(){
  752. if (!this.isSelected) this.selectTd.setStyles({"background": "transparent"});
  753. }.bind(this),
  754. "click": function(){this.select();}.bind(this)
  755. });
  756. }
  757. },
  758. select: function(){
  759. if (this.isSelected){
  760. if (this.view.json.select==="single"){
  761. this.unSelectedSingle();
  762. }else{
  763. this.unSelected();
  764. }
  765. }else{
  766. if (this.view.json.select==="single"){
  767. this.selectedSingle();
  768. }else{
  769. this.selected();
  770. }
  771. }
  772. this.view.fireEvent("select");
  773. },
  774. selected: function(){
  775. this.view.selectedItems.push(this);
  776. this.selectTd.setStyles({"background": "url("+"/x_component_process_Application/$Viewer/default/icon/checkbox_checked.png) center center no-repeat"});
  777. this.node.setStyles(this.css.viewContentTrNode_selected);
  778. this.isSelected = true;
  779. },
  780. unSelected: function(){
  781. this.view.selectedItems.erase(this);
  782. this.selectTd.setStyles({"background": "transparent"});
  783. this.node.setStyles(this.css.viewContentTrNode);
  784. this.isSelected = false;
  785. },
  786. selectedSingle: function(){
  787. if (this.view.currentSelectedItem) this.view.currentSelectedItem.unSelectedSingle();
  788. this.view.selectedItems = [this];
  789. this.view.currentSelectedItem = this;
  790. this.selectTd.setStyles({"background": "url("+"/x_component_process_Application/$Viewer/default/icon/radiobox_checked.png) center center no-repeat"});
  791. this.node.setStyles(this.css.viewContentTrNode_selected);
  792. this.isSelected = true;
  793. },
  794. unSelectedSingle: function(){
  795. this.view.selectedItems = [];
  796. this.view.currentSelectedItem = null;
  797. this.selectTd.setStyles({"background": "transparent"});
  798. this.node.setStyles(this.css.viewContentTrNode);
  799. this.isSelected = false;
  800. }
  801. });
  802. MWF.xApplication.process.Application.Viewer.ItemCategory = new Class({
  803. initialize: function(view, data){
  804. this.view = view;
  805. this.data = data;
  806. this.css = this.view.css;
  807. this.items = [];
  808. this.loadChild = false;
  809. this.load();
  810. },
  811. load: function(){
  812. this.node = new Element("tr", {"styles": this.css.viewContentTrNode}).inject(this.view.viewTable);
  813. //if (this.view.json.select==="single" || this.view.json.select==="multi"){
  814. this.selectTd = new Element("td", {"styles": this.css.viewContentCategoryTdNode}).inject(this.node);
  815. if (this.view.json.itemStyles) this.selectTd.setStyles(this.view.json.itemStyles);
  816. //}
  817. this.categoryTd = new Element("td", {
  818. "styles": this.css.viewContentCategoryTdNode,
  819. "colspan": this.view.viewJson.selectEntryList.length
  820. }).inject(this.node);
  821. this.groupColumn = null;
  822. for (var c = 0; c<this.view.viewJson.selectEntryList.length; c++){
  823. if (this.view.viewJson.selectEntryList[c].column === this.view.viewJson.groupEntry.column){
  824. this.groupColumn = this.view.viewJson.selectEntryList[c];
  825. break;
  826. }
  827. }
  828. if (this.groupColumn){
  829. var text = (this.groupColumn.code) ? MWF.Macro.exec(this.groupColumn.code, {"value": this.data.group, "gridData": this.view.gridJson, "data": this.view.viewData, "entry": this.data}) : this.data.group;
  830. }else{
  831. var text = this.data.group;
  832. }
  833. this.categoryTd.set("html", "<span style='font-family: Webdings'><img src='/x_component_process_Application/$Viewer/"+this.view.options.style+"/icon/expand.png'/></span> "+text);
  834. if (this.view.json.itemStyles) this.categoryTd.setStyles(this.view.json.itemStyles);
  835. this.setEvent();
  836. },
  837. setEvent: function(){
  838. //if (this.selectTd){
  839. this.node.addEvents({
  840. "click": function(){this.expandOrCollapse();}.bind(this)
  841. });
  842. //}
  843. },
  844. expandOrCollapse: function(){
  845. var t = this.node.getElement("span").get("html");
  846. if (t.indexOf("expand.png")===-1){
  847. this.collapse();
  848. }else{
  849. this.expand();
  850. }
  851. },
  852. collapse: function(){
  853. this.items.each(function(item){
  854. item.node.setStyle("display", "none");
  855. }.bind(this));
  856. this.node.getElement("span").set("html", "<img src='/x_component_process_Application/$Viewer/"+this.view.options.style+"/icon/expand.png'/>");
  857. },
  858. expand: function(){
  859. this.items.each(function(item){
  860. item.node.setStyle("display", "table-row");
  861. }.bind(this));
  862. this.node.getElement("span").set("html", "<img src='/x_component_process_Application/$Viewer/"+this.view.options.style+"/icon/down.png'/>");
  863. if (!this.loadChild){
  864. //window.setTimeout(function(){
  865. this.data.list.each(function(line){
  866. this.items.push(new MWF.xApplication.process.Application.Viewer.Item(this.view, line, this));
  867. }.bind(this));
  868. this.loadChild = true;
  869. //}.bind(this), 10);
  870. }
  871. }
  872. });
  873. MWF.xApplication.process.Application.Viewer.Filter = new Class({
  874. initialize: function(viewer, data, node){
  875. this.viewer = viewer;
  876. this.data = data;
  877. this.css = this.viewer.css;
  878. this.content = node;
  879. this.load();
  880. },
  881. load: function(){
  882. this.node = new Element("div", {"styles": this.css.viewSearchFilterNode}).inject(this.content);
  883. if (this.viewer.filterItems.length){
  884. this.logicNode = new Element("div", {"styles": this.css.viewSearchFilterSelectAreaNode}).inject(this.node);
  885. this.logicSelectNode = new Element("div", {
  886. "styles": this.css.viewSearchFilterSelectNode,
  887. "text": this.viewer.lp.and,
  888. "value": "and"
  889. }).inject(this.logicNode);
  890. this.logicSelectButtonNode = new Element("div", {"styles": this.css.viewSearchFilterSelectButtonNode}).inject(this.logicNode);
  891. this.logicNode.addEvents({
  892. "click": function(){
  893. var v = this.logicSelectNode.get("value");
  894. if (v==="and"){
  895. this.logicSelectButtonNode.setStyle("float", "left");
  896. this.logicSelectNode.setStyle("float", "right");
  897. this.logicSelectNode.set({
  898. "text": this.viewer.lp.or,
  899. "value": "or"
  900. });
  901. this.data.logic = "or";
  902. }else{
  903. this.logicSelectButtonNode.setStyle("float", "right");
  904. this.logicSelectNode.setStyle("float", "left");
  905. this.logicSelectNode.set({
  906. "text": this.viewer.lp.and,
  907. "value": "and"
  908. });
  909. this.data.logic = "and";
  910. }
  911. this.viewer.searchCustomView();
  912. }.bind(this)
  913. });
  914. }
  915. this.titleNode = new Element("div", {"styles": this.css.viewSearchFilterTextNode, "text": this.data.title}).inject(this.node);
  916. this.comparisonTitleNode = new Element("div", {"styles": this.css.viewSearchFilterTextNode, "text": this.data.comparisonTitle}).inject(this.node);
  917. this.valueNode = new Element("div", {"styles": this.css.viewSearchFilterTextNode, "text": "\""+this.data.value+"\""}).inject(this.node);
  918. this.deleteNode = new Element("div", {"styles": this.css.viewSearchFilterDeleteNode}).inject(this.node);
  919. this.node.addEvents({
  920. "mouseover": function(){
  921. this.node.setStyles(this.css.viewSearchFilterNode_over);
  922. this.deleteNode.setStyles(this.css.viewSearchFilterDeleteNode_over);
  923. }.bind(this),
  924. "mouseout": function(){
  925. this.node.setStyles(this.css.viewSearchFilterNode);
  926. this.deleteNode.setStyles(this.css.viewSearchFilterDeleteNode);
  927. }.bind(this)
  928. });
  929. this.deleteNode.addEvent("click", function(){
  930. this.viewer.searchViewRemoveFilter(this);
  931. }.bind(this));
  932. },
  933. destroy: function(){
  934. this.node.destroy();
  935. MWF.release(this);
  936. }
  937. });