digitalfabrik/integreat-cms

View on GitHub
integreat_cms/static/src/js/media-management/component/edit-directory-sidebar.tsx

Summary

Maintainability
A
0 mins
Test Coverage
/* eslint react/button-has-type: 0 */
/*
 * This component renders a sidebar which shows information about the current directory
 * as well as provides the possibility to rename and delete the current directory
 */
import { Save, Sliders, Folder, Edit3, Trash2, Lock } from "lucide-preact";
import { useEffect, useState } from "preact/hooks";
import cn from "classnames";

import { route } from "preact-router";
import { showConfirmationPopupAjax } from "../../confirmation-popups";
import { Directory, MediaApiPaths } from "../index";

type Props = {
    directory: Directory;
    apiEndpoints: MediaApiPaths;
    mediaTranslations: any;
    globalEdit?: boolean;
    submitForm: (event: Event, successCallback?: (data: any) => void) => void;
    isLoading: boolean;
    canDeleteDirectory: boolean;
};
const EditDirectorySidebar = ({
    directory,
    apiEndpoints,
    mediaTranslations,
    globalEdit,
    submitForm,
    isLoading,
    canDeleteDirectory,
}: Props) => {
    // This state is a buffer for the currently changed directory
    const [changedDirectory, setChangedDirectory] = useState<Directory>(directory);
    // This state determines whether the directory name is currently being edited
    const [isDirectoryNameEditable, setDirectoryNameEditable] = useState<boolean>(false);
    // Editing is allowed if either global edit is enabled or the directory is not global
    const isEditingAllowed = globalEdit || !directory.isGlobal;

    useEffect(() => {
        console.debug("Opening sidebar for directory:", directory);
        // Reset changed directory buffer
        setChangedDirectory(directory);
        // Hide input field
        setDirectoryNameEditable(false);
    }, [directory]);

    const onIsHiddenCheckboxClick = () => {
        setChangedDirectory({
            ...changedDirectory,
            isHidden: !changedDirectory.isHidden,
        });
    };

    return (
        <div className="absolute w-full h-full flex flex-col rounded border border-blue-500 bg-white border-solid shadow-2xl">
            <div class="rounded w-full p-4 bg-water-500 font-bold">
                <Sliders class="mr-1 inline-block h-5" />
                {mediaTranslations.heading_directory_properties}
            </div>
            <div className="flex-1 overflow-auto">
                <div class="items-center align-middle w-full">
                    <div class="flex items-center">
                        <Folder className="w-full h-36 align-middle mt-4" />
                    </div>
                </div>
                <form onSubmit={submitForm} action={apiEndpoints.editDirectory} encType="multipart/form-data">
                    <input name="id" type="hidden" value={directory.id} />
                    <div class="flex flex-wrap justify-between gap-2 hover:bg-gray-50 p-4 border-t border-b">
                        <label
                            for="directory-name-input"
                            className={cn("secondary my-0", { "cursor-auto": !isEditingAllowed })}
                            onClick={() =>
                                isEditingAllowed && !isLoading && setDirectoryNameEditable(!isDirectoryNameEditable)
                            }
                            onKeyDown={() =>
                                isEditingAllowed && !isLoading && setDirectoryNameEditable(!isDirectoryNameEditable)
                            }>
                            {mediaTranslations.label_directory_name}
                        </label>
                        {!isDirectoryNameEditable && (
                            <p class="break-all">
                                {directory.name}
                                {isEditingAllowed && (
                                    <button
                                        class="hover:text-blue-500 ml-1 h-5"
                                        onClick={(e) => {
                                            e.preventDefault();
                                            setDirectoryNameEditable(true);
                                        }}
                                        disabled={isLoading}
                                        aria-label="Edit">
                                        <Edit3 class="inline-block" />
                                    </button>
                                )}
                            </p>
                        )}
                        <input
                            id="directory-name-input"
                            name="name"
                            type={isDirectoryNameEditable ? "text" : "hidden"}
                            value={changedDirectory.name}
                            onInput={({ target }) =>
                                setChangedDirectory({
                                    ...changedDirectory,
                                    name: (target as HTMLInputElement).value,
                                })
                            }
                            disabled={isLoading}
                            required
                        />
                    </div>
                    <div class="flex flex-wrap justify-between gap-2 hover:bg-gray-50 p-4 border-b">
                        <label class="secondary my-0">{mediaTranslations.label_directory_created}</label>
                        <p>{directory.CreatedDate}</p>
                    </div>
                    {directory.isGlobal && globalEdit && (
                        <div class="flex flex-wrap justify-between gap-2 p-4 border-b">
                            <label class="secondary my-0" for="directory-hide-input">
                                {mediaTranslations.label_directory_is_hidden}
                            </label>
                            <input
                                id="directory-hide-input"
                                name="is_hidden"
                                type="checkbox"
                                value={String(changedDirectory.isHidden)}
                                checked={changedDirectory.isHidden}
                                onClick={() => {
                                    onIsHiddenCheckboxClick();
                                }}
                            />
                        </div>
                    )}
                    <div class="p-4">
                        {isEditingAllowed ? (
                            <div class="flex flex-col gap-4">
                                {(isDirectoryNameEditable || changedDirectory.isHidden !== directory.isHidden) && (
                                    <button
                                        title={mediaTranslations.btn_change_directory}
                                        class="btn"
                                        type="submit"
                                        disabled={isLoading}>
                                        <Save class="mr-1 inline-block h-5" />
                                        {mediaTranslations.btn_change_directory}
                                    </button>
                                )}
                                {canDeleteDirectory && (
                                    <button
                                        title={
                                            directory.numberOfEntries === 0
                                                ? mediaTranslations.btn_delete_directory
                                                : mediaTranslations.btn_delete_empty_directory
                                        }
                                        className={cn("btn", {
                                            "btn-red": !isLoading && directory.numberOfEntries === 0,
                                        })}
                                        data-confirmation-title={mediaTranslations.text_dir_delete_confirm}
                                        data-confirmation-subject={directory.name}
                                        disabled={isLoading || directory.numberOfEntries !== 0}
                                        onClick={showConfirmationPopupAjax}
                                        onaction-confirmed={() => document.getElementById("delete-directory").click()}>
                                        <Trash2 class="mr-2 inline-block h-5" />
                                        {mediaTranslations.btn_delete_directory}
                                    </button>
                                )}
                            </div>
                        ) : (
                            <p class="italic">
                                <Lock class="mr-1 inline-block h-5" />
                                {mediaTranslations.text_dir_readonly}
                            </p>
                        )}
                    </div>
                </form>
                {/* Hidden form for directory deletion (on success, redirect to parent directory) */}
                <form
                    onSubmit={(event: Event) =>
                        submitForm(event, () => route(`${directory.parentId && "/"}${directory.parentId}/`))
                    }
                    action={apiEndpoints.deleteDirectory}
                    class="hidden">
                    <input name="id" type="hidden" value={directory.id} />
                    <button id="delete-directory" aria-label="delete directory" />
                </form>
            </div>
        </div>
    );
};
export default EditDirectorySidebar;