digitalfabrik/integreat-cms

View on GitHub
integreat_cms/static/src/js/forms/update-permalink.ts

Summary

Maintainability
A
0 mins
Test Coverage
/* this file updates the permalink of the current page form
when the user edited the page translations title
or when the user clicks the permalinks edit button */

import { getCsrfToken } from "../utils/csrf-token";
import { copyToClipboard } from "../copy-clipboard";
import SubmissionPrevention from "./prevent-premature-submission";

const slugify = async (url: string, data: any) => {
    const response = await fetch(url, {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
            "HTTP_X_REQUESTED_WITH": "XMLHttpRequest",
            "X-CSRFToken": getCsrfToken(),
        },
        body: JSON.stringify(data),
    }).then((response) => response.json());
    return response;
};

window.addEventListener("load", () => {
    /* slug field buffer for restoring input value */
    let currentSlug: string;
    /* slug field to be updated */
    const slugField = <HTMLInputElement>document.getElementById("id_slug");
    const linkContainer = document.getElementById("link-container");

    const updatePermalink = (currentSlug: string) => {
        // get complete permalink string
        const linkElement = document.getElementById("slug-link");
        const currentLink = linkElement.textContent;
        // remove trailing slug from link
        const updatedLink = currentLink.substr(0, currentLink.lastIndexOf("/") + 1);
        // update only inner html and keep href until form submission
        linkElement.textContent = updatedLink.concat(currentSlug);

        document
            .getElementById("copy-slug-btn")
            .setAttribute("data-copy-to-clipboard", encodeURI(updatedLink.concat(currentSlug)));
    };

    document.querySelectorAll("#id_title").forEach((item) => {
        item.addEventListener("focusout", ({ target }) => {
            const submissionLock = new SubmissionPrevention(".no-premature-submission");
            const currentTitle = (target as HTMLInputElement).value;
            const nodeList: NodeListOf<HTMLInputElement> = document.querySelectorAll(
                '[for="id_title"],[for="id_slug"]'
            );
            for (const node of nodeList) {
                const datasetItem = node.dataset;
                slugify(datasetItem.slugifyUrl, { title: currentTitle, model_id: datasetItem.modelId })
                    .then((response) => {
                        /* on success write response to both slug field and permalink */
                        slugField.value = response.unique_slug;
                        updatePermalink(response.unique_slug);
                    })
                    .finally(() => submissionLock.release());
            }
        });
    });

    const toggleSlugMode = () => {
        // Toggle all permalink buttons (and the rendered link)
        linkContainer.querySelectorAll("a").forEach((link) => link.classList.toggle("hidden"));
        // Toggle slug field
        linkContainer.querySelector("div").classList.toggle("hidden");
    };

    document.getElementById("edit-slug-btn")?.addEventListener("click", (_) => {
        // buffer the current slug field and toggle to editable
        currentSlug = slugField.value;
        toggleSlugMode();
    });

    document.getElementById("save-slug-btn")?.addEventListener("click", (_) => {
        updatePermalink(slugField.value);
        toggleSlugMode();
    });

    document.getElementById("copy-slug-btn")?.addEventListener("click", (_) => {
        // copy whole permalink to clipboard
        copyToClipboard(encodeURI(document.getElementById("slug-link").textContent));
    });

    document.getElementById("restore-slug-btn")?.addEventListener("click", (_) => {
        // hide slug field and restore slug value
        slugField.value = currentSlug;
        toggleSlugMode();
    });
});