Fixed issues relating to custom-inputs
* Don't duplicate custom input when editing before db persist * Remove correct custom input during delete pre db persist (id undefined) * Moved typings to prisma, keeping backwards compatibility with @map * Updated all usages of the enumpull/450/head
parent
3a5e7dd61c
commit
252a329f09
|
@ -1,13 +0,0 @@
|
|||
export enum EventTypeCustomInputType {
|
||||
Text = 'text',
|
||||
TextLong = 'textLong',
|
||||
Number = 'number',
|
||||
Bool = 'bool',
|
||||
}
|
||||
|
||||
export interface EventTypeCustomInput {
|
||||
id?: number;
|
||||
type: EventTypeCustomInputType;
|
||||
label: string;
|
||||
required: boolean;
|
||||
}
|
|
@ -3,6 +3,7 @@ import Link from "next/link";
|
|||
import { useRouter } from "next/router";
|
||||
import { CalendarIcon, ClockIcon, ExclamationIcon, LocationMarkerIcon } from "@heroicons/react/solid";
|
||||
import prisma, { whereAndSelect } from "../../lib/prisma";
|
||||
import { EventTypeCustomInputType } from "@prisma/client";
|
||||
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "../../lib/telemetry";
|
||||
import { useEffect, useState } from "react";
|
||||
import dayjs from "dayjs";
|
||||
|
@ -13,7 +14,6 @@ import PhoneInput from "react-phone-number-input";
|
|||
import { LocationType } from "../../lib/location";
|
||||
import Avatar from "../../components/Avatar";
|
||||
import Button from "../../components/ui/Button";
|
||||
import { EventTypeCustomInputType } from "../../lib/eventTypeInput";
|
||||
import Theme from "@components/Theme";
|
||||
import { ReactMultiEmail } from "react-multi-email";
|
||||
import "react-multi-email/style.css";
|
||||
|
@ -71,7 +71,7 @@ export default function Book(props: any): JSX.Element {
|
|||
.map((input) => {
|
||||
const data = event.target["custom_" + input.id];
|
||||
if (data) {
|
||||
if (input.type === EventTypeCustomInputType.Bool) {
|
||||
if (input.type === EventTypeCustomInputType.BOOL) {
|
||||
return input.label + "\n" + (data.checked ? "Yes" : "No");
|
||||
} else {
|
||||
return input.label + "\n" + data.value;
|
||||
|
@ -273,14 +273,14 @@ export default function Book(props: any): JSX.Element {
|
|||
.sort((a, b) => a.id - b.id)
|
||||
.map((input) => (
|
||||
<div className="mb-4" key={"input-" + input.label.toLowerCase}>
|
||||
{input.type !== EventTypeCustomInputType.Bool && (
|
||||
{input.type !== EventTypeCustomInputType.BOOL && (
|
||||
<label
|
||||
htmlFor={input.label}
|
||||
className="block text-sm font-medium text-gray-700 dark:text-white mb-1">
|
||||
{input.label}
|
||||
</label>
|
||||
)}
|
||||
{input.type === EventTypeCustomInputType.TextLong && (
|
||||
{input.type === EventTypeCustomInputType.TEXTLONG && (
|
||||
<textarea
|
||||
name={"custom_" + input.id}
|
||||
id={"custom_" + input.id}
|
||||
|
@ -290,7 +290,7 @@ export default function Book(props: any): JSX.Element {
|
|||
placeholder=""
|
||||
/>
|
||||
)}
|
||||
{input.type === EventTypeCustomInputType.Text && (
|
||||
{input.type === EventTypeCustomInputType.TEXT && (
|
||||
<input
|
||||
type="text"
|
||||
name={"custom_" + input.id}
|
||||
|
@ -300,7 +300,7 @@ export default function Book(props: any): JSX.Element {
|
|||
placeholder=""
|
||||
/>
|
||||
)}
|
||||
{input.type === EventTypeCustomInputType.Number && (
|
||||
{input.type === EventTypeCustomInputType.NUMBER && (
|
||||
<input
|
||||
type="number"
|
||||
name={"custom_" + input.id}
|
||||
|
@ -310,7 +310,7 @@ export default function Book(props: any): JSX.Element {
|
|||
placeholder=""
|
||||
/>
|
||||
)}
|
||||
{input.type === EventTypeCustomInputType.Bool && (
|
||||
{input.type === EventTypeCustomInputType.BOOL && (
|
||||
<div className="flex items-center h-5">
|
||||
<input
|
||||
type="checkbox"
|
||||
|
|
|
@ -5,13 +5,13 @@ import { useRouter } from "next/router";
|
|||
import React, { useEffect, useRef, useState } from "react";
|
||||
import Select, { OptionBase } from "react-select";
|
||||
import prisma from "@lib/prisma";
|
||||
import { EventTypeCustomInput, EventTypeCustomInputType } from "@prisma/client";
|
||||
import { LocationType } from "@lib/location";
|
||||
import Shell from "@components/Shell";
|
||||
import { getSession } from "next-auth/client";
|
||||
import { Scheduler } from "@components/ui/Scheduler";
|
||||
import { Disclosure, RadioGroup } from "@headlessui/react";
|
||||
import { PhoneIcon, XIcon } from "@heroicons/react/outline";
|
||||
import { EventTypeCustomInput, EventTypeCustomInputType } from "@lib/eventTypeInput";
|
||||
import {
|
||||
LocationMarkerIcon,
|
||||
LinkIcon,
|
||||
|
@ -106,10 +106,10 @@ export default function EventTypePage({
|
|||
const router = useRouter();
|
||||
|
||||
const inputOptions: OptionBase[] = [
|
||||
{ value: EventTypeCustomInputType.Text, label: "Text" },
|
||||
{ value: EventTypeCustomInputType.TextLong, label: "Multiline Text" },
|
||||
{ value: EventTypeCustomInputType.Number, label: "Number" },
|
||||
{ value: EventTypeCustomInputType.Bool, label: "Checkbox" },
|
||||
{ value: EventTypeCustomInputType.TEXT, label: "Text" },
|
||||
{ value: EventTypeCustomInputType.TEXTLONG, label: "Multiline Text" },
|
||||
{ value: EventTypeCustomInputType.NUMBER, label: "Number" },
|
||||
{ value: EventTypeCustomInputType.BOOL, label: "Checkbox" },
|
||||
];
|
||||
|
||||
const [DATE_PICKER_ORIENTATION, setDatePickerOrientation] = useState<OrientationShape>("horizontal");
|
||||
|
@ -342,28 +342,19 @@ export default function EventTypePage({
|
|||
type: e.target.type.value,
|
||||
};
|
||||
|
||||
if (e.target.id?.value) {
|
||||
const index = customInputs.findIndex((inp) => inp.id === +e.target.id?.value);
|
||||
if (index >= 0) {
|
||||
const input = customInputs[index];
|
||||
input.label = customInput.label;
|
||||
input.required = customInput.required;
|
||||
input.type = customInput.type;
|
||||
setCustomInputs(customInputs);
|
||||
}
|
||||
if (selectedCustomInput) {
|
||||
selectedCustomInput.label = customInput.label;
|
||||
selectedCustomInput.required = customInput.required;
|
||||
selectedCustomInput.type = customInput.type;
|
||||
} else {
|
||||
setCustomInputs(customInputs.concat(customInput));
|
||||
}
|
||||
closeAddCustomModal();
|
||||
};
|
||||
|
||||
const removeCustom = (customInput, e) => {
|
||||
e.preventDefault();
|
||||
const index = customInputs.findIndex((inp) => inp.id === customInput.id);
|
||||
if (index >= 0) {
|
||||
customInputs.splice(index, 1);
|
||||
setCustomInputs([...customInputs]);
|
||||
}
|
||||
const removeCustom = (index: number) => {
|
||||
customInputs.splice(index, 1);
|
||||
setCustomInputs([...customInputs]);
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -638,8 +629,8 @@ export default function EventTypePage({
|
|||
</div>
|
||||
<div className="w-full">
|
||||
<ul className="w-96 mt-1">
|
||||
{customInputs.map((customInput) => (
|
||||
<li key={customInput.label} className="bg-secondary-50 mb-2 p-2 border">
|
||||
{customInputs.map((customInput: EventTypeCustomInput, idx: number) => (
|
||||
<li key={idx} className="bg-secondary-50 mb-2 p-2 border">
|
||||
<div className="flex justify-between">
|
||||
<div>
|
||||
<div>
|
||||
|
@ -661,7 +652,7 @@ export default function EventTypePage({
|
|||
className="mr-2 text-sm text-primary-600">
|
||||
Edit
|
||||
</button>
|
||||
<button onClick={(e) => removeCustom(customInput, e)}>
|
||||
<button type="button" onClick={() => removeCustom(idx)}>
|
||||
<XIcon className="h-6 w-6 border-l-2 pl-1 hover:text-red-500 " />
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -162,12 +162,19 @@ model SelectedCalendar {
|
|||
@@id([userId,integration,externalId])
|
||||
}
|
||||
|
||||
enum EventTypeCustomInputType {
|
||||
TEXT @map("text")
|
||||
TEXTLONG @map("textLong")
|
||||
NUMBER @map("number")
|
||||
BOOL @map("bool")
|
||||
}
|
||||
|
||||
model EventTypeCustomInput {
|
||||
id Int @id @default(autoincrement())
|
||||
eventTypeId Int
|
||||
eventType EventType @relation(fields: [eventTypeId], references: [id])
|
||||
label String
|
||||
type String
|
||||
type EventTypeCustomInputType
|
||||
required Boolean
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue