UNPKG

strapi-plugin-cookie-manager

Version:
535 lines (500 loc) 19 kB
// React import React, { useState } from "react" import { useIntl } from "react-intl" // Strapi import { Dialog, DialogBody, DialogFooter } from "@strapi/design-system/Dialog" import { Combobox, ComboboxOption } from "@strapi/design-system/Combobox" import { NumberInput } from "@strapi/design-system/NumberInput" import { Stack } from "@strapi/design-system/Stack" import { Switch } from "@strapi/design-system/Switch" import Trash from "@strapi/icons/Trash" import { Flex } from "@strapi/design-system/Flex" import ExclamationMarkCircle from "@strapi/icons/ExclamationMarkCircle" import { ModalLayout, ModalHeader, ModalBody, ModalFooter, Typography, Button, TextInput, Textarea, Box } from "@strapi/design-system" // Lodash import { isNull, omit, first } from "lodash" // Utils import { getTrad } from "../../utils" // Validation Schema import validationSchema from "./validation" const Modal = ({ setShowModal, crudAction, categories, isMultiLocale, locale = null, preservedCategory = null, cookie = {} }) => { const { formatMessage } = useIntl() const hasPreservedCategory = (preservedCategory !== null) const isUpdate = (cookie["id"] !== undefined) const isDuplicate = ((cookie["id"] === undefined) && (Object.keys(cookie).length > 0)) const [id] = useState(cookie.id || null) const [name, setName] = useState(cookie.name || "") const [description, setDescription] = useState(cookie.description || "") const [host, setHost] = useState(cookie.host || "") const [party, setParty] = useState(cookie.party || "") const [isVisible, setIsVisible] = useState(cookie.isVisible ?? true) const [category, setCategory] = useState(cookie.category || (hasPreservedCategory ? preservedCategory : {})) const [duration, setDuration] = useState(cookie.duration || { days: 0, hours: 0, minutes: 0 }) const [key, setKey] = useState(cookie.key || "") const [nameValidation, setNameValidation] = useState([]) const [descriptionValidation, setDescriptionValidation] = useState([]) const [hostValidation, setHostValidation] = useState([]) const [partyValidation, setPartyValidation] = useState([]) const [categoryValidation, setCategoryValidation] = useState([]) const [durationDaysValidation, setDurationDaysValidation] = useState(false) const [durationHoursValidation, setDurationHoursValidation] = useState(false) const [durationMinutesValidation, setDurationMinutesValidation] = useState(false) const [keyValidation, setKeyValidation] = useState([]) const handleSubmit = async (e) => { e.preventDefault() e.stopPropagation() if (await validateFields()) { const fields = { name: name, description: description, host: host, category: category, party: party, isVisible: isVisible, duration: duration, key: key, locale: locale } try { await crudAction((id) ? { id: id, ...fields } : { ...fields }) setShowModal(false) } catch (e) { console.log("error", e) } } }; const handleValidation = async (field, setValueValidation) => { const key = Object.keys(field)[0] const result = await validateField(field, key) const isValid = isNull(result) ? [""] : result setValueValidation(isValid) } const validateField = async (field, key) => { return await validationSchema(formatMessage) .validateAt(key, field) .then(() => null) .catch((err) => err.errors) } const validateFields = async () => { const fields = { name: name, description: description, host: host, category: category.name, party: party, isVisible: isVisible, durationDays: duration.days, durationHours: duration.hours, durationMinutes: duration.minutes, key: key, } const validationSuccess = await validationSchema(formatMessage).isValid(fields).then((valid) => valid) if (!validationSuccess) { setNameValidation(await validateField({ name: fields.name }, "name")) setDescriptionValidation(await validateField({ description: fields.description }, "description")) setHostValidation(await validateField({ host: fields.host }, "host")) setCategoryValidation(await validateField({ category: fields.category }, "category")) setPartyValidation(await validateField({ party: fields.party }, "party")) setDurationDaysValidation(await validateField({ durationDays: fields.durationDays }, "durationDays")) setDurationHoursValidation(await validateField({ durationHours: fields.durationHours }, "durationHours")) setDurationMinutesValidation(await validateField({ durationMinutes: fields.durationMinutes }, "durationMinutes")) setKeyValidation(await validateField({ key: fields.key }, "key")) } return validationSuccess } const handleCategoryChange = (val) => { let category = { name: "" } if (!isNull(val)) { const newCategory = categories.filter(category => category.name === val) if (newCategory.length > 0) category = newCategory[0] } setCategory(category) } const handlePartyChange = (val) => { setParty(isNull(val) ? "" : val) } const handleDurationChange = (value, timeType) => { if (value === undefined) value = null switch (timeType) { case "d": setDuration({ ...duration, days: value }); break case "h": setDuration({ ...duration, hours: value }); break case "m": setDuration({ ...duration, minutes: value }); break default: break } } return ( <ModalLayout onClose={() => setShowModal(false)} labelledBy="title" as="form" onSubmit={handleSubmit} > <ModalHeader> <Typography fontWeight="bold" textColor="neutral800" as="h2" id="title"> {(isDuplicate) ? ( formatMessage({ id: getTrad("modal.cookie.form.header.title.duplicate"), defaultMessage: "Duplicate Cookie" }) ) : ( (isUpdate) ? formatMessage({ id: getTrad("modal.cookie.form.header.title.update"), defaultMessage: "Update Cookie" }) : formatMessage({ id: getTrad("modal.cookie.form.header.title.create"), defaultMessage: "Create new Cookie" }) )} </Typography> </ModalHeader> <ModalBody> <Box> <TextInput label={formatMessage({ id: getTrad("modal.cookie.form.field.name.label"), defaultMessage: "Name" })} name="name" error={first(nameValidation)} onChange={e => { handleValidation({ name: e.target.value }, setNameValidation) setName(e.target.value) }} value={name} /> </Box> <Box paddingTop={4}> <Textarea label={formatMessage({ id: getTrad("modal.cookie.form.field.description.label"), defaultMessage: "Description" })} name="description" error={first(descriptionValidation)} onChange={e => { handleValidation({ description: e.target.value }, setDescriptionValidation) setDescription(e.target.value) }} value={description} /> </Box> <Box paddingTop={4}> <TextInput label={formatMessage({ id: getTrad("modal.cookie.form.field.host.label"), defaultMessage: "Host" })} name="host" hint={formatMessage({ id: getTrad("modal.cookie.form.field.host.hint"), defaultMessage: "e.G domain.com" })} error={first(hostValidation)} onChange={e => { handleValidation({ host: e.target.value }, setHostValidation) setHost(e.target.value) }} value={host} /> </Box> <Box paddingTop={4}> <Combobox label={formatMessage({ id: getTrad("modal.cookie.form.field.category.label"), defaultMessage: "Category" })} name="category" error={first(categoryValidation)} onChange={(value) => { handleValidation({ category: value }, setCategoryValidation) handleCategoryChange(value) }} placeholder={formatMessage({ id: getTrad("modal.cookie.form.field.category.placeholder"), defaultMessage: "Select or enter a value" })} value={category.name} > {categories.map((category, index) => { return <ComboboxOption key={index} value={category.name}>{category.name}</ComboboxOption> })} </Combobox> </Box> <Box paddingTop={4}> <Combobox label={formatMessage({ id: getTrad("modal.cookie.form.field.party.label"), defaultMessage: "Party" })} name="party" error={first(partyValidation)} onChange={value => { handleValidation({ party: value }, setPartyValidation) handlePartyChange(value) }} placeholder={formatMessage({ id: getTrad("modal.cookie.form.field.party.placeholder"), defaultMessage: "Select or enter a value" })} value={party} > <ComboboxOption value="First-party">1st-party</ComboboxOption> <ComboboxOption value="Second-party">2nd-party</ComboboxOption> <ComboboxOption value="Third-party">3rd-party</ComboboxOption> </Combobox> </Box> <Box paddingTop={4}> <Flex direction="column" alignItems="flex-start"> <Typography variant="pi" fontWeight="bold"> {formatMessage({ id: getTrad("modal.cookie.form.field.isVisible.label"), defaultMessage: "Is Visible" })} </Typography> <Box paddingTop={1}> <Typography variant="pi" style={{ color: "#666687" }}> {formatMessage({ id: getTrad("modal.cookie.form.field.isVisible.hint"), defaultMessage: "Manage visibility" })} </Typography> </Box> <Box paddingTop={1}> <Switch label={formatMessage({ id: getTrad("modal.cookie.form.field.isVisible.label"), defaultMessage: "Is Visible" })} name="is-visible" selected={isVisible} onChange={() => setIsVisible(s => !s)} /> </Box> </Flex> </Box> <Box paddingTop={4}> <Typography variant="pi" fontWeight="bold"> {formatMessage({ id: getTrad("modal.cookie.form.field.duration.label"), defaultMessage: "Duration" })} </Typography> <Box paddingTop={1}> <Flex gap={4}> <NumberInput aria-label={formatMessage({ id: getTrad("modal.cookie.form.field.duration.days.placeholder"), defaultMessage: "Days" })} hint={formatMessage({ id: getTrad("modal.cookie.form.field.duration.days.placeholder"), defaultMessage: "Days" })} name="days" error={first(durationDaysValidation)} onValueChange={value => { handleValidation({ durationDays: value }, setDurationDaysValidation) handleDurationChange(value, "d") }} value={duration.days} /> <NumberInput aria-label={formatMessage({ id: getTrad("modal.cookie.form.field.duration.hours.placeholder"), defaultMessage: "Hours" })} hint={formatMessage({ id: getTrad("modal.cookie.form.field.duration.hours.placeholder"), defaultMessage: "Hours" })} name="hours" error={first(durationHoursValidation)} onValueChange={value => { handleValidation({ durationHours: value }, setDurationHoursValidation) handleDurationChange(value, "h") }} value={duration.hours} /> <NumberInput aria-label={formatMessage({ id: getTrad("modal.cookie.form.field.duration.minutes.placeholder"), defaultMessage: "Minutes" })} hint={formatMessage({ id: getTrad("modal.cookie.form.field.duration.minutes.placeholder"), defaultMessage: "Minutes" })} name="minutes" error={first(durationMinutesValidation)} onValueChange={value => { handleValidation({ durationMinutes: value }, setDurationMinutesValidation) handleDurationChange(value, "m") }} value={duration.minutes} /> </Flex> </Box> </Box> {isMultiLocale && ( <Box paddingTop={4}> <TextInput label={formatMessage({ id: getTrad("modal.cookie.form.field.key.label"), defaultMessage: "Key" })} name="key" error={first(keyValidation)} onChange={e => { handleValidation({ key: e.target.value }, setKeyValidation) setKey(e.target.value) }} value={key} /> </Box> )} </ModalBody> <ModalFooter startActions={ <Button onClick={() => setShowModal(false)} variant="tertiary"> Cancel </Button> } endActions={ (isDuplicate) ? ( <Button type="submit"> {formatMessage({ id: getTrad("modal.cookie.form.cta.duplicate"), defaultMessage: "Duplicate Cookie" })} </Button> ) : ( (isUpdate) ? <Button type="submit"> {formatMessage({ id: getTrad("modal.cookie.form.cta.update"), defaultMessage: "Update Cookie" })} </Button> : <Button type="submit"> {formatMessage({ id: getTrad("modal.cookie.form.cta.create"), defaultMessage: "Add new Cookie" })} </Button> ) } /> </ModalLayout> ) } const CreateCookieModal = ({ setShowModal, createCookie, categories, locale, isMultiLocale, preservedCategory }) => <Modal setShowModal={setShowModal} crudAction={createCookie} categories={categories} locale={locale} isMultiLocale={isMultiLocale} preservedCategory={preservedCategory} /> const UpdateCookieModal = ({ setShowModal, updateCookie, cookie, categories, isMultiLocale }) => <Modal setShowModal={setShowModal} crudAction={updateCookie} categories={categories} cookie={cookie} isMultiLocale={isMultiLocale} /> const DuplicateCookieModal = ({ setShowModal, createCookie, cookie, categories, locale, isMultiLocale }) => <Modal setShowModal={setShowModal} crudAction={createCookie} categories={categories} cookie={omit(cookie, "id")} locale={locale} isMultiLocale={isMultiLocale} /> const DeleteCookieModal = ({ setShowModal, deleteCookie, cookie, showModal = false }) => { const { formatMessage } = useIntl() return ( <Dialog onClose={() => setShowModal(false)} title={formatMessage({ id: getTrad("modal.cookie.form.header.title.delete"), defaultMessage: "Delete Cookie" })} isOpen={showModal} > <DialogBody icon={<ExclamationMarkCircle />}> <Stack spacing={2}> <Flex justifyContent="center"> <Typography id="confirm-description"> {formatMessage({ id: getTrad("modal.cookie.form.info.delete"), defaultMessage: "Are you sure you want to delete this?" })} </Typography> </Flex> </Stack> </DialogBody> <DialogFooter startAction={ <Button onClick={() => setShowModal(false)} variant="tertiary"> {formatMessage({ id: getTrad("modal.cookie.form.cta.cancel"), defaultMessage: "Cancel" })} </Button> } endAction={ <Button onClick={() => { deleteCookie(cookie) setShowModal(false) }} variant="danger-light" startIcon={<Trash />} > {formatMessage({ id: getTrad("modal.cookie.form.cta.delete"), defaultMessage: "Delete Cookie" })} </Button> } /> </Dialog> ) } const DeleteAllCookieModal = ({ setShowModal, deleteAllCookie, cookies, showModal = false }) => { const { formatMessage } = useIntl() return ( <Dialog onClose={() => setShowModal(false)} title="Confirmation" isOpen={showModal}> <DialogBody icon={<ExclamationMarkCircle />}> <Stack spacing={2}> <Flex justifyContent="center"> <Typography id="confirm-description"> {formatMessage({ id: getTrad("modal.cookie.form.info.delete"), defaultMessage: "Are you sure you want to delete this?" })} </Typography> </Flex> </Stack> </DialogBody> <DialogFooter startAction={ <Button onClick={() => setShowModal(false)} variant="tertiary"> {formatMessage({ id: getTrad("modal.cookie.form.cta.cancel"), defaultMessage: "Cancel" })} </Button> } endAction={ <Button onClick={() => { deleteAllCookie(cookies) setShowModal(false) }} variant="danger-light" startIcon={<Trash />} > {formatMessage({ id: getTrad("modal.cookie.form.cta.deleteAll"), defaultMessage: "Delete Cookie" })} </Button> } /> </Dialog> ) } export { CreateCookieModal, UpdateCookieModal, DeleteCookieModal, DeleteAllCookieModal, DuplicateCookieModal }