+ });
+
+ let message = `Are you sure you want to delete ${links.length} links?\n`;
+ message += 'This action is IRREVERSIBLE!\n\nTitles:\n';
+ const ids = [];
+ links.forEach((item) => {
+ message += ` - ${item.title}\n`;
+ ids.push(item.id);
+ });
+
+ if (window.confirm(message)) {
+ window.location = `${basePath}/admin/shaare/delete?id=${ids.join('+')}&token=${token.value}`;
+ }
+ });
+ }
+
+ const changeVisibilityButtons = document.querySelectorAll('.actions-change-visibility');
+ if (changeVisibilityButtons != null && token != null) {
+ [...changeVisibilityButtons].forEach((button) => {
+ button.addEventListener('click', (event) => {
+ event.preventDefault();
+ const visibility = event.target.getAttribute('data-visibility');
+
+ const links = [];
+ const linkCheckedCheckboxes = document.querySelectorAll('.link-checkbox:checked');
+ [...linkCheckedCheckboxes].forEach((checkbox) => {
+ links.push({
+ id: checkbox.value,
+ title: document.querySelector(`.linklist-item[data-id="${checkbox.value}"] .linklist-link`).innerHTML,
+ });
+ });
+
+ const ids = links.map((item) => item.id);
+ window.location = (
+ `${basePath}/admin/shaare/visibility?token=${token.value}&newVisibility=${visibility}&id=${ids.join('+')}`
+ );
+ });
+ });
+ }
+
+ /**
+ * Select all button
+ */
+ const selectAllButtons = document.querySelectorAll('.select-all-button');
+ [...selectAllButtons].forEach((selectAllButton) => {
+ selectAllButton.addEventListener('click', (e) => {
+ e.preventDefault();
+ const checked = selectAllButton.classList.contains('filter-off');
+ [...selectAllButtons].forEach((selectAllButton2) => {
+ selectAllButton2.classList.toggle('filter-off');
+ selectAllButton2.classList.toggle('filter-on');
+ });
+ [...linkCheckboxes].forEach((linkCheckbox) => {
+ linkCheckbox.checked = checked;
+ linkCheckbox.dispatchEvent(new Event('change'));
+ });
+ });
+ });
+
+ /**
+ * Tag list operations
+ *
+ * TODO: support error code in the backend for AJAX requests
+ */
+ const tagList = document.querySelector('input[name="taglist"]');
+ let existingTags = tagList ? tagList.value.split(' ') : [];
+ let awesomepletes = [];
+
+ // Display/Hide rename form
+ const renameTagButtons = document.querySelectorAll('.rename-tag');
+ [...renameTagButtons].forEach((rename) => {
+ rename.addEventListener('click', (event) => {
+ event.preventDefault();
+ const block = findParent(event.target, 'div', { class: 'tag-list-item' });
+ const form = block.querySelector('.rename-tag-form');
+ if (form.style.display === 'none' || form.style.display === '') {
+ form.style.display = 'block';
+ } else {
+ form.style.display = 'none';
+ }
+ block.querySelector('input').focus();
+ });
+ });
+
+ // Rename a tag with an AJAX request
+ const renameTagSubmits = document.querySelectorAll('.validate-rename-tag');
+ [...renameTagSubmits].forEach((rename) => {
+ rename.addEventListener('click', (event) => {
+ event.preventDefault();
+ const block = findParent(event.target, 'div', { class: 'tag-list-item' });
+ const input = block.querySelector('.rename-tag-input');
+ const totag = input.value.replace('/"/g', '\\"');
+ if (totag.trim() === '') {
+ return;
+ }
+ const refreshedToken = document.getElementById('token').value;
+ const fromtag = block.getAttribute('data-tag');
+ const fromtagUrl = block.getAttribute('data-tag-url');
+ const xhr = new XMLHttpRequest();
+ xhr.open('POST', `${basePath}/admin/tags`);
+ xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+ xhr.onload = () => {
+ if (xhr.status !== 200) {
+ alert(`An error occurred. Return code: ${xhr.status}`);
+ location.reload();
+ } else {
+ block.setAttribute('data-tag', totag);
+ block.setAttribute('data-tag-url', encodeURIComponent(totag));
+ input.setAttribute('name', totag);
+ input.setAttribute('value', totag);
+ findParent(input, 'div', { class: 'rename-tag-form' }).style.display = 'none';
+ block.querySelector('a.tag-link').innerHTML = he.encode(totag);
+ block
+ .querySelector('a.tag-link')
+ .setAttribute('href', `${basePath}/?searchtags=${encodeURIComponent(totag)}`);
+ block
+ .querySelector('a.count')
+ .setAttribute('href', `${basePath}/add-tag/${encodeURIComponent(totag)}`);
+ block
+ .querySelector('a.rename-tag')
+ .setAttribute('href', `${basePath}/admin/tags?fromtag=${encodeURIComponent(totag)}`);
+
+ // Refresh awesomplete values
+ existingTags = existingTags.map((tag) => (tag === fromtag ? totag : tag));
+ awesomepletes = updateAwesompleteList('.rename-tag-input', existingTags, awesomepletes);