vdreg.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /**
  2. * ЭЛЕКТРОННЫЙ ЖУРНАЛ «ШКАЛА»: ВНЕУРОЧНАЯ ДЕЯТЕЛЬНОСТЬ (ИНТЕРФЕЙС СОТРУДНИКА)
  3. * Copyright © 2021, А.М.Гольдин. Modified BSD License
  4. *
  5. * Скрипт использует библиотеку reglib.js !
  6. */
  7. "use strict";
  8. // Объекты для хранения тем и отметок (аналогичные определенным в register.js)
  9. let vdTopicsObj = {}, vdGradesObj = {};
  10. // Список учителей {"pupking" : "Пупкин В. И."}
  11. let vTeachList = {};
  12. // Текст placeholder'а в поле редактирования темы урока
  13. let vdTopPH = `Введите тему занятия\n(если тема пуста, колонка будет удалена)`;
  14. // Содержимое select выбора веса отметки
  15. let vdSelWInner = '';
  16. for (let i=0; i<9; i++) vdSelWInner += `<option value=${i}>${i/2}</option>`;
  17. vdSelWInner += "<option value=9>П</option>";
  18. // Содержимое select выбора количества часов
  19. let vdSelVInner = '';
  20. for (let i=1; i<8; i++) vdSelVInner += `<option value="${i}"> ${i} ч </option>`;
  21. // Экспорт странички текущей группы в html-файл
  22. const expVD = async () => {
  23. // Получаем данные текущей выбранной группы
  24. let selElem = dqs("#vdGroupSel"),
  25. grName = selElem.value.split('^')[0],
  26. teacher = selElem.value.split('^')[2],
  27. grFull = selElem.options[selElem.selectedIndex].text;
  28. // Получаем файл со скриптом показа журнала
  29. let scrContent = await (await fetch("/js/viewExportVD.js")).text();
  30. if (!scrContent.includes("use strict")) {
  31. info(1, "Не могу получить данные");
  32. return;
  33. }
  34. scrContent = scrContent.replace(/\r/g, '').replace(/\/\/.*?\n/g, '')
  35. . replace(/\/\*.*?\*\//g, '').replace(/ /g, '¤')
  36. . replace(/\s+/g, ' ').replace(/¤/g, ' ').trim();
  37. // Получаем отметки
  38. let gradesStr = await apireq("gradesGet", [grName, "s000", teacher]);
  39. if (gradesStr == "none") {info(1, "Не могу получить данные"); return;}
  40. // Получаем темы уроков
  41. let topicsStr = await apireq("topicsGet", [grName, "s000", teacher]);
  42. if (topicsStr == "none") {info(1, "Не могу получить данные"); return;}
  43. // Формируем объект данных для экспорта
  44. // {
  45. // pnList: ["Иванов И.", "Петров П.", ...],
  46. // d601: {t: "Африка", h: "Учить", w: 4, v: 2, g: ["нн", "5", ...]},
  47. // ...
  48. // }
  49. let expObj = {},
  50. grades = JSON.parse(gradesStr),
  51. topics = JSON.parse(topicsStr);
  52. if (!grades.pnList) {info(1, "Нечего экспортировать!"); return;}
  53. let DSset = new Set([...Object.keys(grades), ...Object.keys(topics)]);
  54. DSset.delete("puList"); DSset.delete("pnList");
  55. let DS = [...DSset];
  56. for (let k of DS.sort()) {
  57. let kNew = k.length == 4 ? dateConv(k) : DTSIT[k][0];
  58. let tp = topics[k] ? topics[k] : {},
  59. gr = grades[k] ? grades[k] : new Array(grades.pnList.length).fill('');
  60. expObj[kNew] = {...tp, g: gr};
  61. }
  62. expObj.pnList = grades.pnList;
  63. let linkElem = dqs("#expVD");
  64. linkElem.innerHTML = "Ждите...";
  65. let fileContent = "<!DOCTYPE html><html lang='ru'><head>"
  66. + `<meta charset='utf-8'></head><body><article>${JSON.stringify(expObj)}`
  67. + `</article><script>"use strict"; const grFull = "${grFull}";`
  68. + `</script><script>${scrContent}</script></body></html>`;
  69. let dataLink = new Blob([fileContent], {type: "text/html"});
  70. linkElem.href = window.URL.createObjectURL(dataLink);
  71. linkElem.download = `${grName}.html`;
  72. linkElem.innerHTML = "Скачать";
  73. linkElem.removeAttribute("onclick");
  74. }
  75. createSection("vdreg", `
  76. <select id="vdGroupSel" onChange="
  77. dqs('#expVD').innerHTML='&#128228;';
  78. dqs('#expVD').removeAttribute('href');
  79. dqs('#expVD').setAttribute('onclick', 'expVD(); return false');
  80. loadGrades(1)"></select>&nbsp;
  81. <a id="expVD" onclick="expVD(); return false" style="cursor:pointer"
  82. title="Экспорт">&#128228;</a><br>
  83. <div id="vdGrades"></div>
  84. <div id="vdTopics">
  85. <div id="vdNewTopic">
  86. <input id="vdTopDt" type="date" onChange="dtFocus(0, 1)"
  87. min="${regYst}" max="${regYfin}" value="${regNow}">
  88. <textarea placeholder="${vdTopPH}"></textarea>
  89. <div id="vdTopHTask" contenteditable="true"
  90. onFocus="clearPhr(1); clearPhr = () => {;}">Домашнее задание</div>
  91. <button id="vdLnk" onClick="insertLink('vdTopHTask')"
  92. title="Создать ссылку в домашнем задании">&#9875;</button>
  93. <select id="vdTopVol">${vdSelVInner}</select>
  94. <span>Вес отметок (от 0 до 4)</span>
  95. <select id="vdTopWeight">${vdSelWInner}</select>
  96. <button onClick="topicEdit(1)"> &gt;&gt; </button>
  97. </div>
  98. <div id="vdJustTopics"></div>
  99. </div>
  100. <h3 id="vdIsContent">У вас нет групп внеурочной деятельности</h3>
  101. `);
  102. // Динамически подгружаем контент страницы (имя метода = имени пункта меню!)
  103. getContent.vdreg = async () => {
  104. // Список учителей {"pupking" : "Пупкин В. И."}
  105. let apiResp = await apireq("teachList");
  106. if (apiResp != "none")
  107. for (let t of JSON.parse(apiResp)) vTeachList[t.login] = t.fio;
  108. // Выдача сообщения и скрытие контента страницы, если нет
  109. // доступных юзеру журнальных страниц
  110. const vdNoContent = () => {
  111. vdIsContent = false;
  112. dqs("#vdGroupSel") .style.display = "none";
  113. dqs("#vdGrades") .style.display = "none";
  114. dqs("#vdTopics") .style.display = "none";
  115. dqs("#expVD") .style.display = "none";
  116. dqs("#vdIsContent").style.display = "block";
  117. }
  118. // Формирование списка групп в селекте и отображение блоков контента
  119. let vdRole = dqs("#selRole").value,
  120. vdGrList = [],
  121. vdIsContent = true; // есть ли у юзера доступные журнальные страницы
  122. dqs("#vdGroupSel") .style.display = "inline";
  123. dqs("#vdGrades") .style.display = "inline-block";
  124. dqs("#vdTopics") .style.display = "inline-block";
  125. dqs("#expVD") .style.display = "inline";
  126. dqs("#vdIsContent").style.display = "none";
  127. // Получаем полный список всех групп
  128. // [
  129. // ["29Б", "Доп. главы математики", "ivanov"],
  130. // ...
  131. // ]
  132. apiResp = await apireq("interGroupList");
  133. if (apiResp != "none")
  134. vdGrList = JSON.parse(apiResp).sort((x,y) => x[0] > y[0]);
  135. // Администратору показываем все группы
  136. if (vdRole == "admin") {
  137. dqs("#vdNewTopic").style.display = "none";
  138. }
  139. // Учителю только свои группы (uLogin записан скриптом login.js)
  140. else if (vdRole == "teacher") {
  141. vdGrList = vdGrList.filter(gr => gr[2] == uLogin);
  142. if (!vdGrList.length) vdNoContent();
  143. else dqs("#vdNewTopic").style.display = "block";
  144. }
  145. else vdNoContent();
  146. let vdSelGrInner = '';
  147. for (let grp of vdGrList) vdSelGrInner +=
  148. `<option value="${grp[0]}^s000^${grp[2]}">${grp[0]}: ${grp[1]} ` +
  149. `(${vTeachList[grp[2]]})</option>`;
  150. dqs("#vdGroupSel").innerHTML = vdSelGrInner;
  151. if (vdIsContent) loadGrades(1); // список группы, отметки и темы занятий
  152. }