Virtonomica:Notes

Система добавления и показа оповещений

当前为 2016-12-05 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Virtonomica:Notes
  3. // @name:en Virtonomica:Notes
  4. // @namespace Virtonomica
  5. // @description Система добавления и показа оповещений
  6. // @description:en The list of notes
  7. // @version 0.24
  8. // @include https://*virtonomic*.*/*/main/unit/view/*
  9. // @include https://*virtonomic*.*/*/main/company/view/*/unit_list
  10. // @include https://*irtonomic*.*/*/main/politics/president/*
  11. // @include https://*virtonomic*.*/*/main/politics/governor/*
  12. // @include https://*virtonomic*.*/*/main/politics/mayor/*
  13. // ==/UserScript==
  14. var run = function() {
  15. var win = (typeof(unsafeWindow) != 'undefined' ? unsafeWindow : top.window);
  16. $ = win.$;
  17.  
  18. var loc_storage = function(){
  19. return({
  20. 'save': function (name, val){
  21. try {
  22. window.localStorage.setItem( name, JSON.stringify( val ) );
  23. } catch(e) {
  24. out = "Ошибка добавления в локальное хранилище";
  25. //console.log(out);
  26. }
  27. },
  28. 'load': function(name){
  29. obj = JSON.parse( window.localStorage.getItem(name) );
  30. if ( obj == null ) obj = new Object();
  31. return obj;
  32. }
  33. });
  34. }
  35. var LS = new loc_storage();
  36.  
  37. // определяем интерфейс
  38. // autodefined language interface
  39. var lang = 'undef';
  40. //var bt_logout = $("li[class='icon menulogout']");
  41. //var logout_string = bt_logout.attr('title');
  42. var logout_string = $("a[href*='user/logout']").text();
  43. console.log(logout_string);
  44. // язык по умолчанию
  45. lang = 'En';
  46. if (logout_string == 'Выход') {
  47. lang = 'Ru';
  48. } else if(logout_string == 'Logout') {
  49. lang = 'En';
  50. }
  51. console.log(lang);
  52. if ( lang == 'undef') {
  53. alert('Unsupported language for userscript "Notes"');
  54. return;
  55. }
  56.  
  57. // Строки зависимые от языка
  58. // language definitions
  59. var LangMsg = new Object();
  60. LangMsg['Ru'] = new Object();
  61. LangMsg['En'] = new Object();
  62.  
  63. LangMsg['Ru']['governor'] = "Губернатор";
  64. LangMsg['En']['governor'] = "Governor";
  65. LangMsg['Ru']['president'] = "Президент";
  66. LangMsg['En']['president'] = "President";
  67. LangMsg['Ru']['mayor'] = "Мэр";
  68. LangMsg['En']['mayor'] = "Mayor";
  69.  
  70. LangMsg['Ru']['notes'] = "Напоминание";
  71. LangMsg['En']['notes'] = "Notes";
  72.  
  73. LangMsg['Ru']['list_notes'] = "Список напоминаний";
  74. LangMsg['En']['list_notes'] = "List of Notes";
  75.  
  76. LangMsg['Ru']['save'] = "Сохранить";
  77. LangMsg['En']['save'] = "Save";
  78. LangMsg['Ru']['del'] = "Удалить";
  79. LangMsg['En']['del'] = "Delete";
  80.  
  81. LangMsg['Ru']['add_notes'] = "Добавить напоминание";
  82. LangMsg['En']['add_notes'] = "Add Notes";
  83.  
  84. LangMsg['Ru']['export'] = "Окно экспорта/импорта";
  85. LangMsg['En']['export'] = "Windwow export/import";
  86. LangMsg['Ru']['import'] = "Импортировать данные из окна";
  87. LangMsg['En']['import'] = "Importing data from textarea";
  88. LangMsg['Ru']['data_export'] = "Данные экспорта";
  89. LangMsg['En']['data_export'] = "Data exporting";
  90. // --- virtonomica user interface
  91. LangMsg['Ru']['comp'] = "компании";
  92. LangMsg['En']['comp'] = "of a company";
  93. //console.log( LangMsg );
  94. /**
  95. * записать данные в локальнео хранилище, с проверкой ошибок
  96. */
  97. function ToStorage(name, val)
  98. {
  99. try {
  100. window.localStorage.setItem( name, JSON.stringify( val ) );
  101. } catch(e) {
  102. out = "Ошибка добавления в локальное хранилище";
  103. //console.log(out);
  104. }
  105. }
  106.  
  107. function getFromStorage(obj, id_shop)
  108. {
  109. if (obj[id_shop] == null) return '';
  110. return JSON.stringify(obj[id_shop]);
  111. }
  112.  
  113. /**
  114. * Добавить заметку к текущему предприятию
  115. * следует вызывать на страницах где одно подраздление, ИД которого виден в url
  116. *
  117. * @param msg текст сообщения, можно использовать html теги
  118. */
  119. function addNotes( msg ){
  120. // объект для хранения сообщений
  121. notes = JSON.parse( window.localStorage.getItem('notes') );
  122. if ( notes == null ) notes = new Object();
  123.  
  124. // Идентификатор подразделения
  125. var id = /(\d+)/.exec(location.href)[0];
  126. var head = $("#headerInfo");
  127. var title = $("h1", head).text();
  128.  
  129. head = $("div.officePlace");
  130. var type = head.text();
  131. var nn = type.indexOf("компании");
  132. if (nn > 0){
  133. type = type.substring(0, nn);
  134. var ptrn = /\s*((\S+\s*)*)/;
  135. type = type.replace(ptrn, "$1");
  136. ptrn = /((\s*\S+)*)\s*/;
  137. type = type.replace(ptrn, "$1");
  138. } else {
  139. type = '';
  140. }
  141.  
  142. if ( notes[id] == null ) notes[id] = new Object();
  143.  
  144. var d = new Date();
  145.  
  146. if ( notes[id]['text'] != null) {
  147. // сообщение для этого подраздления уже есть
  148. msg = notes[id]['text'] + "<br>" + msg;
  149. }
  150.  
  151. notes[id]['text'] = msg;
  152. // Количество миллисекунд
  153. notes[id]['time'] = d.getTime();
  154. notes[id]['name'] = title;
  155. notes[id]['type'] = type;
  156.  
  157. ToStorage('notes', notes);
  158. }
  159.  
  160. var txt = "<table><tr><td><td><table width=100%><tr><td align=rigth id=notes_title><td align=center><h3>" + LangMsg[ lang ]['notes'] + "</h3><div id=notes_link style='color:grey'></div></table><td>&nbsp;";
  161. txt+= "";
  162. txt+= "<tr><td>&nbsp;<td align=center id=notes_form>&nbsp;<td>&nbsp;" + "<tr><td colspan=3></table>";
  163. var div_form = "<div id=notes style='background: none repeat scroll 0% 0% rgb(223, 223, 223); z-index: 1002; position: absolute; border: 1px solid rgb(0, 0, 0); display: none;'>" + txt + "</div>";
  164.  
  165. var div_export = "<div id=notes_export style='background: none repeat scroll 0% 0% rgb(223, 223, 223); z-index: 1003; position: absolute; border: 1px solid rgb(0, 0, 0); display: none;'>"
  166. + "<h3 style='margin:4px'>" + LangMsg[ lang ]['data_export'] + "</h3>"
  167. + "<table><tr><td>&nbsp;<td>"
  168. + "<textarea name=export_text id=export_text rows=10 cols=64></textarea>"
  169. + "<br><center><span id=export_load></span></center>"
  170. + "</table>";
  171. + "</div>";
  172.  
  173. var tu = $("table.unit-list-2014");
  174. if (tu.length == 1) {
  175. // Это у нас список подразделений - рисуем кнопку отображения отчета со сылками
  176. // Оповещения
  177. notes = JSON.parse( window.localStorage.getItem('notes') );
  178. if ( notes == null ) notes = new Object();
  179. var len = 0;
  180.  
  181. // проверить, какие оповещения отразить как актуальные
  182. for (key in notes){
  183. len++;
  184. }
  185.  
  186. // http://cdn1.iconfinder.com/data/icons/Upojenie_by_SoundForge/Icons/Notes.png
  187. // http://www.iconsearch.ru/uploads/icons/crystalclear/24x24/kedit.png
  188.  
  189. var wc = $("<li><div id=main_notes style='float:left;cursor:pointer; color: white;'> <img alt='" + LangMsg[ lang ]['list_notes'] +"' src=http://cdn1.iconfinder.com/data/icons/humano2/32x32/apps/gnome-sticky-notes-applet.png> <span id=all_notes> ("+ len+")</span></div>").click( function() {
  190. $("#notes").toggle();
  191. if( $('#notes').is(':visible') ) {
  192. // код для visible
  193. // Оповещения
  194. notes = JSON.parse( window.localStorage.getItem('notes') );
  195. if ( notes == null ) notes = new Object();
  196.  
  197. // Формируем ссылку на торговый зал
  198. var url = /^https:\/\/virtonomic[as]\.(\w+)\/\w+\//.exec(location.href)[0];
  199. console.log(url);
  200.  
  201. var all_count = 0;
  202. $("#notes_form").html('');
  203. var out = $("<table>");
  204. for (key in notes){
  205. if (notes[key] == null) continue;
  206. if (notes[key]['time'] == null) continue;
  207.  
  208. // подсчитываем сколько у нас оповещениий
  209. // TODO - учитывать только акутальные
  210. all_count++;
  211.  
  212. var d = new Date();
  213. d.setTime(notes[key]['time']);
  214.  
  215. link = "<a href=" + url + "main/unit/view/" + key + ">" + notes[key]['name'] + "</a>";
  216. if ( notes[key]['link'] != null ) {
  217. link = "<a href=" + notes[key]['link'] + ">" + notes[key]['name'] + "</a>";
  218. }
  219. span = $("<span name=" + key + " style='cursor:pointer;' title='del'><font color=red><b>Х</b></font></span>").click(
  220. function(){
  221. idp = $(this).attr('name');
  222. //alert('del = ' + idp);
  223. delete notes[idp];
  224. ToStorage('notes', notes);
  225. $(this).parent().css("text-decoration","line-through").css("color","grey");
  226. //$("#main_notes").click().click();
  227. });
  228.  
  229. out_tr = $("<tr>");
  230. out_tr.append("<td>" + d.toLocaleDateString())
  231. .append("<td>" + link)
  232. .append("<td>(" + notes[key]['type'] + ")")
  233. .append("<td style='border: 1px solid gray; border-radius: 4px 4px 4px 4px; box-shadow: 0 1px 3px 0 #999999; display: block; float: left; margin-top: 4px; overflow: hidden; padding: 2px 4px; text-align:left'>" + notes[key]['text'])
  234. .append("<td>").append(span);
  235. out.append(out_tr);
  236. str = "(" + all_count +")";
  237. if (all_count == 0) str = '';
  238. $("#all_notes").html("(" + all_count +")");
  239. }
  240. $("#notes_form").html( out );
  241.  
  242. }
  243. });
  244.  
  245. // http://cdn1.iconfinder.com/data/icons/basicset/save_32.png
  246. // http://www.iconsearch.ru/uploads/icons/ultimategnome/48x48/stock_export.png
  247. var wc_export = $("<span id=main_notes_export style='cursor:pointer; color: white;'><img src=http://cdn1.iconfinder.com/data/icons/basicset/save_32.png title='" + LangMsg[ lang]['export']+ "' alt='О" + LangMsg[ lang]['export']+ "'></span>").click( function() {
  248. $("#export_text").val( JSON.stringify( notes ) );
  249. $("#notes_export").toggle();
  250. });
  251.  
  252. // http://cdn1.iconfinder.com/data/icons/freeapplication/png/24x24/Load.png
  253. // http://www.iconsearch.ru/uploads/icons/freeapplication/24x24/load.png
  254. var wc_load = $("<img src=http://cdn1.iconfinder.com/data/icons/freeapplication/png/24x24/Load.png title='" + LangMsg[ lang ]['import'] + "' alt='" + LangMsg[ lang ]['import'] + "'>").click( function() {
  255. //alert("Load");
  256. var text = $("#export_text").val() ;
  257. try {
  258. notes = JSON.parse( text );
  259. ToStorage('notes', notes);
  260. $("#notes_export").hide();
  261. $("#main_notes").click().click();
  262. } catch(e) {
  263. alert("Неверные данным для импорта");
  264. }
  265. });
  266.  
  267. var container = $('ul.tabu');
  268. container.append( wc );
  269.  
  270. $("table.unit-top").before ( div_form);
  271. //container.append( div_form );
  272. //var container = $('#topblock');
  273. //container.append( $('<table><tr><td>').append(wc) );
  274. //container.append( div_form );
  275. $("#notes_title").append(wc_export).append( div_export );
  276. $("#export_load").append(wc_load);
  277.  
  278.  
  279. return;
  280. }
  281.  
  282. // Идентификатор подразделения
  283. var id = /(\d+)/.exec(location.href)[0];
  284. console.log("id=" + id);
  285. // тип подразделения
  286. var type = '';
  287. // название подразделения
  288. var title = '';
  289. var pos = location.href.indexOf("politics");
  290. // проверяем на объект политики
  291. if (pos > 0) {
  292. console.log("politics");
  293. // вычитываем название объекта политики
  294. var polit_name = "";
  295. var el = $("#headerInfoCenter h1");
  296. var el2 = $("a", el);
  297. if (el2.length > 0 ) {
  298. polit_name = el2.text();
  299. } else {
  300. polit_name = el.text();
  301. }
  302. if ( location.href.indexOf("president") > 0 ) {
  303. type = LangMsg[ lang ]['president'];
  304. }
  305. if ( location.href.indexOf("governor") > 0 ) {
  306. type = LangMsg[ lang ]['governor'] ;
  307. }
  308. if ( location.href.indexOf("mayor") > 0 ) {
  309. type = LangMsg[ lang ]['mayor'] ;
  310. polit_name = el.html();
  311. pos = polit_name.indexOf("<img");
  312. polit_name = $.trim( polit_name.substr(0, pos) );
  313. }
  314. console.log( polit_name );
  315. title = polit_name;
  316. console.log( type );
  317. } else {
  318. // обработка обыных юнитов (units)
  319. var head = $("#headerInfo");
  320. var title = $("h1", head).text();
  321.  
  322. head = $("div.officePlace");
  323. var type = head.text();
  324. var nn = type.indexOf( LangMsg[ lang ]['comp'] );
  325. if (nn > 0){
  326. type = type.substring(0, nn);
  327. var ptrn = /\s*((\S+\s*)*)/;
  328. type = type.replace(ptrn, "$1");
  329. ptrn = /((\s*\S+)*)\s*/;
  330. type = type.replace(ptrn, "$1");
  331. } else {
  332. type = '';
  333. }
  334. }
  335. // Оповещения
  336. notes = JSON.parse( window.localStorage.getItem('notes') );
  337. if ( notes == null ) notes = new Object();
  338. if ( notes[id] == null) notes[id] = new Object();
  339.  
  340. notes_html = "";
  341. if ( notes[id]['text'] != null) notes_html = notes[id]['text'];
  342.  
  343. var form = "";
  344. form += "<span id=notes_error style='color:red;'></span><br>";
  345. form += "<div id=notes_preview style='border: 1px solid gray; border-radius: 4px 4px 4px 4px; box-shadow: 0 1px 3px 0 #999999; display: block; float: left; margin-top: 4px; margin-right: 4px; overflow: hidden; padding: 2px 4px; text-align:left'>" + notes_html +"</div>";
  346. form += " <textarea name=notes_txt id=notes_txt rows=5 cols=48>";
  347. form += notes_html;
  348. form+= "</textarea><br>";
  349.  
  350. var form_button = $("<button id=notes_btn style='cursor:pointer'>" +LangMsg[ lang ]['save'] + "</button>").click( function() {
  351. $("#notes_error").text('');
  352. var text = $("#notes_txt").val() ;
  353. $("#notes_preview").html( text );
  354. if (text == '') {
  355. $("#notes_error").text('Ошибка - нет описания');
  356. return;
  357. }
  358.  
  359. var d = new Date();
  360. // Оповещения
  361. notes = JSON.parse( window.localStorage.getItem('notes') );
  362. if ( notes == null ) notes = new Object();
  363.  
  364. if ( notes[id] == null) notes[id] = new Object();
  365.  
  366. notes[id]['text'] = text;
  367. notes[id]['time'] = d.getTime();
  368. notes[id]['name'] = title;
  369. notes[id]['type'] = type;
  370. notes[id]['link'] = location.href;
  371.  
  372. ToStorage('notes', notes);
  373. $("#notes").toggle();
  374. });
  375.  
  376. var form_button_del = $(" <button style='cursor:pointer'>" +LangMsg[ lang ]['del'] + "</button>").click( function() {
  377. // Оповещения
  378. notes = JSON.parse( window.localStorage.getItem('notes') );
  379. if ( notes == null ) notes = new Object();
  380.  
  381. if ( notes[id] == null) notes[id] = new Object();
  382.  
  383. $("#notes_txt").val("");
  384. $("#notes_preview").html( "" );
  385. delete notes[id];
  386. ToStorage('notes', notes);
  387. });
  388.  
  389. // http://cdn1.iconfinder.com/data/icons/oxygen/32x32/actions/document-new.png
  390. // http://www.iconsearch.ru/uploads/icons/ull_icons/24x24/message_add.png
  391. var wc = $("<li style='cursor:pointer; color: white;'><img alt='"+ LangMsg[ lang ]['add_notes'] + "' src=http://cdn1.iconfinder.com/data/icons/oxygen/32x32/actions/document-new.png title='"+ LangMsg[ lang ]['add_notes'] + "'> </li>").click( function() {
  392. $("#notes").toggle();
  393. // Обновить зампетку
  394. notes = JSON.parse( window.localStorage.getItem('notes') );
  395. if ( notes == null ) notes = new Object();
  396. if ( notes[id] == null) notes[id] = new Object();
  397.  
  398. $("#notes_txt").change(function() {
  399. console.log('change ' + $("#notes_txt").val() );
  400. $("#notes_preview").html( $("#notes_txt").val() );
  401. });
  402. if ( notes[id]['text'] == null ) return;
  403. $("#notes_txt").val( notes[id]['text'] );
  404. $("#notes_preview").html( notes[id]['text'] );
  405. if (notes[id]['link'] != null) {
  406. $("#notes_link").html( notes[id]['link'] );
  407. }
  408. });
  409. //var container = $('#topblock');
  410. //var container = $('#topblock').next();
  411. var container = $('ul.tabu');
  412.  
  413. if (tu.length == 0) {
  414. container = $("li:last", container).prev().parent();
  415. container.append(wc) ;
  416. //container.append( $('<table><tr><td>').append(wc) );
  417. $("#childMenu").before ( div_form);
  418.  
  419. $("#notes_form").append(form).append(form_button).append(form_button_del);
  420. }
  421. }
  422.  
  423. if(window.top == window) {
  424. var script = document.createElement("script");
  425. script.textContent = '(' + run.toString() + ')();';
  426. document.documentElement.appendChild(script);
  427. }