entity.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. ((dn, schema, inputs, ldifOutput, classContainer, addClassSelect, addClassBtn) => {
  2. let changes = [],
  3. multipleValues = {},
  4. maxInputId = 0,
  5. newClasses = {},
  6. attributeCount = {};
  7. function ComputeChanges() {
  8. let classChanges = [];
  9. let actualChanges = [];
  10. for (let i in newClasses)
  11. classChanges.push(`add: objectClass\nobjectClass: ${i}`);
  12. for (let i = 0; i < changes.length; ++i) {
  13. let ch = changes[i];
  14. if (!ch)
  15. continue;
  16. if (ch.initialValue.length && ch.newValue.length && (multipleValues[ch.attrName] || 0) === 1) {
  17. actualChanges.push(`replace: ${ch.attrName}\n${ch.attrName}: ${ch.newValue}`);
  18. } else {
  19. if (ch.initialValue.length) {
  20. if ((multipleValues[ch.attrName] || 0) === 1)
  21. actualChanges.push(`delete: ${ch.attrName}`);
  22. else
  23. actualChanges.push(`delete: ${ch.attrName}\n${ch.attrName}: ${ch.initialValue}`);
  24. }
  25. if (ch.newValue.length)
  26. actualChanges.push(`add: ${ch.attrName}\n${ch.attrName}: ${ch.newValue}`);
  27. }
  28. }
  29. let totalChanges = classChanges.concat(actualChanges.sort((a, b) => b.localeCompare(a)));
  30. if (!totalChanges.length)
  31. return "";
  32. return `dn: ${dn}\nchangetype: modify\n` + totalChanges.join("\n-\n");
  33. }
  34. function UpdateLdif() {
  35. ldifOutput.textContent = ComputeChanges();
  36. ldifOutput.style.height = ldifOutput.scrollHeight + "px"
  37. }
  38. function onValueChanged(input) {
  39. let initialValue = input.dataset.initialValue || "",
  40. inputId = input.dataset.inputId,
  41. newValue = input.value || "",
  42. attrName = input.dataset.attributeName;
  43. if (initialValue === newValue)
  44. changes[inputId] = undefined;
  45. else
  46. changes[inputId] = { initialValue: initialValue, newValue: newValue, attrName: attrName };
  47. UpdateLdif();
  48. }
  49. let prevItem = null; // input field
  50. function removeButtonHandler(input, li) {
  51. return (e) => {
  52. e?.preventDefault();
  53. input.value = "";
  54. onValueChanged(input);
  55. li.parentNode.removeChild(li);
  56. };
  57. }
  58. function addAddButton(input, li) {
  59. let addButton = document.createElement("a");
  60. addButton.innerText = "";
  61. addButton.className = "button button-add bi bi-plus-circle";
  62. addButton.src = "#";
  63. addButton.parentInput = input;
  64. addButton.addEventListener("click", (e) => {
  65. e.preventDefault();
  66. let line = addButton.parentInput.parentNode.parentNode;
  67. let copy = line.cloneNode(true);
  68. line.parentNode.insertBefore(copy, line);
  69. let input = copy.querySelector("label > input");
  70. input.value = "";
  71. input.dataset.initialValue = "";
  72. input.addEventListener("change", e => onValueChanged(e.currentTarget));
  73. input.dataset.inputId = ++maxInputId;
  74. copy.querySelector(".button-remove")?.addEventListener("click", removeButtonHandler(input, copy));
  75. let button = copy.querySelector("label > span > .button-add");
  76. button.parentNode.removeChild(button);
  77. });
  78. li.querySelector(".LDAPAttribute > span").appendChild(addButton);
  79. }
  80. function addRemoveButton(input, li) { // item is the input field
  81. if (input.parentNode.children[0].classList.contains("mandatory"))
  82. return;
  83. let button = document.createElement("a");
  84. button.innerText = "";
  85. button.className = "button button-remove bi bi-dash-circle";
  86. button.src = "#";
  87. button.addEventListener("click", removeButtonHandler(input, li));
  88. li.querySelector(".LDAPAttribute > span").appendChild(button);
  89. }
  90. function manageDuplicateAttributes(li, input) {
  91. attributeCount[input.dataset.attributeName] = (attributeCount[input.dataset.attributeName] || {});
  92. attributeCount[input.dataset.attributeName][input.dataset.klass] = true;
  93. if (Object.keys(attributeCount[input.dataset.attributeName]).length > 1)
  94. li.style.display = "none";
  95. }
  96. inputs.forEach(i => {
  97. maxInputId = Math.max(i.dataset.inputId, maxInputId);
  98. let attrName = i.dataset.attributeName;
  99. if ((i.dataset.initialValue || "").length)
  100. multipleValues[attrName] = (multipleValues[attrName] || 0) + 1;
  101. i.addEventListener("change", e => onValueChanged(e.currentTarget))
  102. if (prevItem != null &&
  103. prevItem.dataset.attributeName !== i.dataset.attributeName) {
  104. addAddButton(prevItem, prevItem.parentNode.parentNode);
  105. }
  106. addRemoveButton(i, i.parentNode.parentNode);
  107. prevItem = i;
  108. manageDuplicateAttributes(i.parentElement.parentElement, i);
  109. });
  110. prevItem && addAddButton(prevItem, prevItem.parentNode.parentNode);
  111. function CreateClassAttributeDom(className, name, init, isMandatory) {
  112. let li = document.createElement("li");
  113. let label = document.createElement("label");
  114. label.classList.add("LDAPAttribute");
  115. label.classList.add("form-label");
  116. li.appendChild(label);
  117. let span = document.createElement("span");
  118. if (isMandatory)
  119. span.classList.add("mandatory");
  120. span.innerText = name;
  121. let input = document.createElement("input");
  122. input.type = "text";
  123. input.value = init;
  124. input.dataset.initialValue = init;
  125. input.dataset.inputId = ++maxInputId;
  126. input.dataset.name = name;
  127. input.dataset.klass = className;
  128. input.dataset.attributeName = name;
  129. input.required = isMandatory;
  130. input.className = "form-control";
  131. input.addEventListener("change", e => onValueChanged(e.currentTarget))
  132. label.appendChild(span);
  133. label.appendChild(input);
  134. addAddButton(input);
  135. manageDuplicateAttributes(li, input);
  136. return li;
  137. }
  138. function CreateClassDom(schema, className) {
  139. let classDom = document.createElement("fieldset");
  140. classDom.classList.add("LDAPClass");
  141. let legend = document.createElement("legend");
  142. let legendInner = document.createElement("h3");
  143. legendInner.innerText = className +' (' +schema["type"] +')';
  144. legend.appendChild(legendInner);
  145. classDom.appendChild(legend);
  146. let list = document.createElement("ul");
  147. for (let i of schema["must"])
  148. list.appendChild(CreateClassAttributeDom(className, i, "", true));
  149. for (let i of schema["may"])
  150. list.appendChild(CreateClassAttributeDom(className, i, "", false));
  151. classDom.appendChild(list);
  152. return classDom;
  153. }
  154. addClassBtn.addEventListener("click", () => {
  155. let targetClass = addClassSelect.value;
  156. if (!schema[targetClass])
  157. return;
  158. for (let i of addClassSelect.children) {
  159. if (i.value === targetClass) {
  160. addClassSelect.removeChild(i);
  161. break;
  162. }
  163. }
  164. newClasses[targetClass] = true;
  165. let dom = CreateClassDom(schema[targetClass], targetClass);
  166. classContainer.appendChild(dom);
  167. UpdateLdif();
  168. });
  169. })(
  170. window['dn'], window['schema'],
  171. document.querySelectorAll(".LDAPAttribute > input"), document.getElementById("ldifOutput"),
  172. document.getElementById("classContainer"),
  173. document.getElementById("addClassSelect"), document.getElementById("addClassBtn"));