Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 31 additions & 4 deletions apps/app/components/issues/description-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const RemirrorRichTextEditor = dynamic(() => import("components/rich-text-editor
});
// types
import { IIssue } from "types";
import useToast from "hooks/use-toast";

export interface IssueDescriptionFormValues {
name: string;
Expand All @@ -31,7 +32,16 @@ export interface IssueDetailsProps {
}

export const IssueDescriptionForm: FC<IssueDetailsProps> = ({ issue, handleFormSubmit }) => {
const { handleSubmit, watch, setValue, reset } = useForm<IIssue>({
const { setToastAlert } = useToast();

const {
handleSubmit,
watch,
setValue,
reset,
formState: { errors },
setError,
} = useForm<IIssue>({
defaultValues: {
name: "",
description: "",
Expand All @@ -41,13 +51,31 @@ export const IssueDescriptionForm: FC<IssueDetailsProps> = ({ issue, handleFormS

const handleDescriptionFormSubmit = useCallback(
(formData: Partial<IIssue>) => {
if (!formData.name || formData.name === "") {
setToastAlert({
type: "error",
title: "Error in saving!",
message: "Title is required.",
});
return;
}

if (formData.name.length > 255) {
setToastAlert({
type: "error",
title: "Error in saving!",
message: "Title cannot have more than 255 characters.",
});
return;
}

handleFormSubmit({
name: formData.name ?? "",
description: formData.description,
description_html: formData.description_html,
});
},
[handleFormSubmit]
[handleFormSubmit, setToastAlert]
);

const debounceHandler = useMemo(
Expand Down Expand Up @@ -83,9 +111,8 @@ export const IssueDescriptionForm: FC<IssueDetailsProps> = ({ issue, handleFormS
}}
mode="transparent"
className="text-xl font-medium"
required={true}
/>

<span>{errors.name ? errors.name.message : null}</span>
<RemirrorRichTextEditor
value={watch("description")}
placeholder="Describe the issue..."
Expand Down
2 changes: 1 addition & 1 deletion apps/app/components/issues/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ export const IssueForm: FC<IssueFormProps> = ({
required: "Title is required",
maxLength: {
value: 255,
message: "Name should be less than 255 characters",
message: "Title should be less than 255 characters",
},
}}
/>
Expand Down
7 changes: 5 additions & 2 deletions apps/app/components/project/create-project-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,8 @@ export const CreateProjectModal: React.FC<Props> = (props) => {
const projectIdentifier = watch("identifier") ?? "";

useEffect(() => {
if (projectName && isChangeIdentifierRequired) {
if (projectName && isChangeIdentifierRequired)
setValue("identifier", projectName.replace(/ /g, "").toUpperCase().substring(0, 3));
}
}, [projectName, projectIdentifier, setValue, isChangeIdentifierRequired]);

useEffect(() => () => setIsChangeIdentifierRequired(true), [isOpen]);
Expand Down Expand Up @@ -215,6 +214,10 @@ export const CreateProjectModal: React.FC<Props> = (props) => {
register={register}
validations={{
required: "Name is required",
maxLength: {
value: 255,
message: "Name should be less than 255 characters",
},
}}
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,10 @@ const CreateUpdateCycleModal: React.FC<Props> = ({ isOpen, setIsOpen, data, proj
register={register}
validations={{
required: "Name is required",
maxLength: {
value: 255,
message: "Name should be less than 255 characters",
},
}}
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import stateService from "services/state.service";
// hooks
import useToast from "hooks/use-toast";
// ui
import { Button, Input, Select } from "components/ui";
import { Button, CustomSelect, Input, Select } from "components/ui";
// types
import type { IState } from "types";
// fetch-keys
Expand Down Expand Up @@ -183,18 +183,27 @@ export const CreateUpdateStateInline: React.FC<Props> = ({
autoComplete="off"
/>
{data && (
<Select
id="group"
<Controller
name="group"
error={errors.group}
register={register}
validations={{
required: true,
}}
options={Object.keys(GROUP_CHOICES).map((key) => ({
value: key,
label: GROUP_CHOICES[key as keyof typeof GROUP_CHOICES],
}))}
control={control}
render={({ field: { value, onChange } }) => (
<CustomSelect
value={value}
onChange={onChange}
label={
Object.keys(GROUP_CHOICES).find((k) => k === value.toString())
? GROUP_CHOICES[value.toString() as keyof typeof GROUP_CHOICES]
: "Select group"
}
input
>
{Object.keys(GROUP_CHOICES).map((key) => (
<CustomSelect.Option key={key} value={key}>
{GROUP_CHOICES[key as keyof typeof GROUP_CHOICES]}
</CustomSelect.Option>
))}
</CustomSelect>
)}
/>
)}
<Input
Expand All @@ -209,7 +218,7 @@ export const CreateUpdateStateInline: React.FC<Props> = ({
Cancel
</Button>
<Button theme="primary" disabled={isSubmitting} type="submit">
{isSubmitting ? "Loading..." : data ? "Update" : "Create"}
{isSubmitting ? (data ? "Updating..." : "Creating...") : data ? "Update" : "Create"}
</Button>
</form>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ const CreateUpdateModuleModal: React.FC<Props> = ({ isOpen, setIsOpen, data, pro
register={register}
validations={{
required: "Name is required",
maxLength: {
value: 255,
message: "Name should be less than 255 characters",
},
}}
/>
</div>
Expand Down
2 changes: 1 addition & 1 deletion apps/app/components/ui/datepicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const CustomDatePicker: React.FC<Props> = ({
renderAs === "input"
? "block bg-transparent text-sm focus:outline-none rounded-md border border-gray-300 px-3 py-2 w-full cursor-pointer"
: renderAs === "button"
? "w-full cursor-pointer rounded-md border px-2 py-1 text-xs shadow-sm duration-300 hover:bg-gray-100 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500"
? "w-full rounded-md border px-2 py-1 text-xs shadow-sm hover:bg-gray-100 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 duration-300 cursor-pointer"
: ""
} ${error ? "border-red-500 bg-red-200" : ""} bg-transparent caret-transparent`}
isClearable={isClearable}
Expand Down