From 6b2a5a97ac028a6d2aad4b26167d4aed91d7eedf Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal Date: Tue, 19 Sep 2023 17:09:50 +0530 Subject: [PATCH] chore: separate description fields in the create issue modal --- .../attribute-display/date-time.tsx | 6 +- .../attribute-display/email.tsx | 4 +- .../attribute-display/file.tsx | 10 +- .../attribute-display/number.tsx | 4 +- .../attribute-display/select.tsx | 50 ++- .../attribute-forms/attribute-form.tsx | 4 +- .../issue-modal-attributes-list.tsx | 197 ++++++----- .../peek-overview-custom-attributes-list.tsx | 334 ++++++++++-------- .../sidebar-custom-attributes-list.tsx | 4 +- web/components/issues/form.tsx | 13 +- web/components/issues/modal.tsx | 56 ++- .../issues/peek-overview/issue-properties.tsx | 4 +- .../projects/[projectId]/issues/[issueId].tsx | 2 +- web/store/custom-attribute-values.ts | 4 + 14 files changed, 414 insertions(+), 278 deletions(-) diff --git a/web/components/custom-attributes/attribute-display/date-time.tsx b/web/components/custom-attributes/attribute-display/date-time.tsx index b7ea1eaf6..eae92e663 100644 --- a/web/components/custom-attributes/attribute-display/date-time.tsx +++ b/web/components/custom-attributes/attribute-display/date-time.tsx @@ -33,14 +33,14 @@ export const CustomDateTimeAttribute: React.FC = ({ attributeDetails, onC attributeDetails.extra_settings.hide_date ? "" : DATE_FORMATS[attributeDetails.extra_settings.date_format] ?? "dd-MM-yyyy" - }${ + } ${ attributeDetails.extra_settings.hide_time ? "" - : ", " + (TIME_FORMATS[attributeDetails.extra_settings.time_format] ?? "HH:mm") + : TIME_FORMATS[attributeDetails.extra_settings.time_format] ?? "HH:mm" }`} showTimeInput={!attributeDetails.extra_settings.hide_time} isClearable={!attributeDetails.is_required} - placeholderText={`Enter ${attributeDetails.display_name}`} + placeholderText={`Select ${attributeDetails.display_name}`} /> ); diff --git a/web/components/custom-attributes/attribute-display/email.tsx b/web/components/custom-attributes/attribute-display/email.tsx index 3fc56920b..ff1fba055 100644 --- a/web/components/custom-attributes/attribute-display/email.tsx +++ b/web/components/custom-attributes/attribute-display/email.tsx @@ -25,9 +25,7 @@ export const CustomEmailAttribute: React.FC = ({ attributeDetails, onChan }; useEffect(() => { - if (isEditing) { - setFocus("email"); - } + if (isEditing) setFocus("email"); }, [isEditing, setFocus]); useEffect(() => { diff --git a/web/components/custom-attributes/attribute-display/file.tsx b/web/components/custom-attributes/attribute-display/file.tsx index dd43afc95..4b808f2d2 100644 --- a/web/components/custom-attributes/attribute-display/file.tsx +++ b/web/components/custom-attributes/attribute-display/file.tsx @@ -111,19 +111,21 @@ export const CustomFileAttribute: React.FC = (props) => { return (
{value && value !== "" && ( -
+
- {getFileIcon(getFileExtension(value))} - {getFileName(value)} + {getFileIcon(getFileExtension(value))} + + {value.split("/")[value.split("/").length - 1].split("-")[1]} +
) : ( - {value} + + {value} + )} ) : ( diff --git a/web/components/custom-attributes/attribute-display/select.tsx b/web/components/custom-attributes/attribute-display/select.tsx index 1e6644706..3c58afd94 100644 --- a/web/components/custom-attributes/attribute-display/select.tsx +++ b/web/components/custom-attributes/attribute-display/select.tsx @@ -5,21 +5,21 @@ import { Combobox, Transition } from "@headlessui/react"; // hooks import useOutsideClickDetector from "hooks/use-outside-click-detector"; // icons -import { Check, Search } from "lucide-react"; +import { Check, Search, XIcon } from "lucide-react"; // types import { ICustomAttribute } from "types"; type Props = { attributeDetails: ICustomAttribute; issueId: string; + onChange: (val: string | string[] | undefined) => void; projectId: string; } & ( | { multiple?: false; - onChange: (val: string | undefined) => void; value: string | undefined; } - | { multiple?: true; onChange: (val: string[] | undefined) => void; value: string[] | undefined } + | { multiple?: true; value: string[] | undefined } ); export const CustomSelectAttribute: React.FC = (props) => { @@ -87,18 +87,33 @@ export const CustomSelectAttribute: React.FC = (props) => { Array.isArray(value) ? ( value.length > 0 ? (
- {value.map((v) => { - const optionDetails = options.find((o) => o.id === v); + {value.map((val) => { + const optionDetails = options.find((o) => o.id === val); return ( - {optionDetails?.display_name} - + {((attributeDetails.is_required && value.length > 1) || + !attributeDetails.is_required) && ( + + )} +
); })}
@@ -109,14 +124,27 @@ export const CustomSelectAttribute: React.FC = (props) => { ) ) : (
- o.id === value)?.color}40`, }} > {options.find((o) => o.id === value)?.display_name} - + {!attributeDetails.is_required && ( + + )} +
) ) : ( diff --git a/web/components/custom-attributes/attribute-forms/attribute-form.tsx b/web/components/custom-attributes/attribute-forms/attribute-form.tsx index ba1bd4bd0..f6f810ecd 100644 --- a/web/components/custom-attributes/attribute-forms/attribute-form.tsx +++ b/web/components/custom-attributes/attribute-forms/attribute-form.tsx @@ -76,6 +76,8 @@ const RenderForm: React.FC<{ type: TCustomAttributeTypes } & FormComponentProps> return FormToRender; }; +const OPTIONAL_FIELDS = ["checkbox", "file"]; + export const AttributeForm: React.FC = observer(({ attributeDetails, objectId, type }) => { const [isRemoving, setIsRemoving] = useState(false); @@ -148,7 +150,7 @@ export const AttributeForm: React.FC = observer(({ attributeDetails, obje )}
- {attributeDetails.type !== "checkbox" && ( + {!OPTIONAL_FIELDS.includes(attributeDetails.type ?? "") && ( <> void; + onChange: (attributeId: string, val: string | string[] | undefined) => void; projectId: string; values: { [key: string]: string[] }; }; -export const IssueModalCustomAttributesList: React.FC = observer( - ({ entityId, issueId, onChange, projectId, values }) => { - const router = useRouter(); - const { workspaceSlug } = router.query; +const DESCRIPTION_FIELDS: TCustomAttributeTypes[] = ["email", "number", "text", "url"]; - const { customAttributes: customAttributesStore } = useMobxStore(); - const { entityAttributes, fetchEntityDetails, fetchEntityDetailsLoader } = - customAttributesStore; +export const IssueModalCustomAttributesList: React.FC = observer((props) => { + const { entityId, issueId, onChange, projectId, values } = props; - const attributes = entityAttributes[entityId] ?? {}; + const [hideOptionalFields, setHideOptionalFields] = useState(false); - useEffect(() => { - if (!entityAttributes[entityId]) { - if (!workspaceSlug) return; + const router = useRouter(); + const { workspaceSlug } = router.query; - fetchEntityDetails(workspaceSlug.toString(), entityId); - } - }, [entityAttributes, entityId, fetchEntityDetails, workspaceSlug]); + const { customAttributes: customAttributesStore } = useMobxStore(); + const { entityAttributes, fetchEntityDetails, fetchEntityDetailsLoader } = customAttributesStore; - return ( - <> - {fetchEntityDetailsLoader ? ( - - - - - - ) : ( - <> - {Object.entries(attributes).map(([attributeId, attribute]) => ( + const attributes = entityAttributes[entityId] ?? {}; + + // fetch entity details + useEffect(() => { + if (!entityAttributes[entityId]) { + if (!workspaceSlug) return; + + fetchEntityDetails(workspaceSlug.toString(), entityId); + } + }, [entityAttributes, entityId, fetchEntityDetails, workspaceSlug]); + + const descriptionFields = Object.values(attributes).filter((a) => + DESCRIPTION_FIELDS.includes(a.type) + ); + const nonDescriptionFields = Object.values(attributes).filter( + (a) => !DESCRIPTION_FIELDS.includes(a.type) + ); + + return ( + <> + {fetchEntityDetailsLoader ? ( + + + + + + ) : ( + <> + + {({ open }) => ( + <> +
+ + + Description Fields + +
+ Hide optional fields + setHideOptionalFields((prev) => !prev)} + /> +
+
+ + {Object.entries(descriptionFields).map(([attributeId, attribute]) => ( +
+ onChange(attribute.id, e.target.value)} + required={attribute.is_required} + /> + {attribute.type === "number" && + attribute.extra_settings?.representation !== "numerical" && ( + + Maximum value: {attribute.extra_settings?.divided_by} + + )} +
+ ))} +
+ + )} +
+
+ {Object.entries(nonDescriptionFields).map(([attributeId, attribute]) => (
{attribute.type === "checkbox" && ( = observer( onChange(attribute.id, [val?.toISOString() ?? ""])} + onChange={(val) => + onChange(attribute.id, val ? [val.toISOString()] : undefined) + } projectId={projectId} value={ values[attribute.id]?.[0] ? new Date(values[attribute.id]?.[0]) : undefined } /> )} - {attribute.type === "email" && ( - onChange(attribute.id, [val])} - projectId={projectId} - value={values[attribute.id]?.[0]} - /> - )} {attribute.type === "file" && ( onChange(attribute.id, [val])} + onChange={(val) => onChange(attribute.id, val)} projectId={projectId} value={undefined} /> @@ -101,34 +157,17 @@ export const IssueModalCustomAttributesList: React.FC = observer( { - if (val) onChange(attribute.id, val); - }} + onChange={(val) => onChange(attribute.id, val)} projectId={projectId} value={values[attribute.id] ?? []} multiple /> )} - {attribute.type === "number" && ( - { - if (val) onChange(attribute.id, [val.toString()]); - }} - projectId={projectId} - value={ - values[attribute.id]?.[0] ? parseInt(values[attribute.id]?.[0]) : undefined - } - /> - )} {attribute.type === "relation" && ( { - if (val) onChange(attribute.id, [val]); - }} + onChange={(val) => onChange(attribute.id, val)} projectId={projectId} value={values[attribute.id]?.[0]} /> @@ -137,37 +176,17 @@ export const IssueModalCustomAttributesList: React.FC = observer( { - if (val) onChange(attribute.id, [val]); - }} + onChange={(val) => onChange(attribute.id, val)} projectId={projectId} value={attribute.default_value !== "" ? attribute.default_value : undefined} multiple={false} /> )} - {attribute.type === "text" && ( - onChange(attribute.id, [val])} - projectId={projectId} - value={attribute.default_value} - /> - )} - {attribute.type === "url" && ( - onChange(attribute.id, [val])} - projectId={projectId} - value={values[attribute.id]?.[0]} - /> - )}
))} - - )} - - ); - } -); +
+ + )} + + ); +}); diff --git a/web/components/custom-attributes/attributes-list/peek-overview-custom-attributes-list.tsx b/web/components/custom-attributes/attributes-list/peek-overview-custom-attributes-list.tsx index bf9028581..6515e6a47 100644 --- a/web/components/custom-attributes/attributes-list/peek-overview-custom-attributes-list.tsx +++ b/web/components/custom-attributes/attributes-list/peek-overview-custom-attributes-list.tsx @@ -10,6 +10,7 @@ import { CustomCheckboxAttribute, CustomDateTimeAttribute, CustomEmailAttribute, + CustomFileAttribute, CustomNumberAttribute, CustomRelationAttribute, CustomSelectAttribute, @@ -25,165 +26,208 @@ import { CUSTOM_ATTRIBUTES_LIST } from "constants/custom-attributes"; type Props = { issue: IIssue | undefined; + projectId: string; }; -export const PeekOverviewCustomAttributesList: React.FC = observer(({ issue }) => { - const router = useRouter(); - const { workspaceSlug } = router.query; +export const PeekOverviewCustomAttributesList: React.FC = observer( + ({ issue, projectId }) => { + const router = useRouter(); + const { workspaceSlug } = router.query; - const { - customAttributes: customAttributesStore, - customAttributeValues: customAttributeValuesStore, - } = useMobxStore(); - const { entityAttributes, fetchEntityDetails } = customAttributesStore; - const { issueAttributeValues, fetchIssueAttributeValues } = customAttributeValuesStore; + const { + customAttributes: customAttributesStore, + customAttributeValues: customAttributeValuesStore, + } = useMobxStore(); + const { entityAttributes, fetchEntityDetails } = customAttributesStore; + const { issueAttributeValues, fetchIssueAttributeValues, deleteAttributeValue } = + customAttributeValuesStore; - const handleAttributeUpdate = (attributeId: string, value: string) => { - if (!issue || !workspaceSlug) return; + const handleAttributeUpdate = (attributeId: string, value: string | string[] | undefined) => { + if (!issue || !workspaceSlug) return; - const payload: ICustomAttributeValueFormData = { - issue_properties: { - [attributeId]: value, - }, + if (!value) { + deleteAttributeValue(workspaceSlug.toString(), projectId, issue.id, attributeId); + return; + } + + const payload: ICustomAttributeValueFormData = { + issue_properties: { + [attributeId]: Array.isArray(value) ? value : [value], + }, + }; + + customAttributeValuesStore.createAttributeValue( + workspaceSlug.toString(), + issue.project, + issue.id, + payload + ); }; - customAttributeValuesStore.createAttributeValue( - workspaceSlug.toString(), - issue.project, - issue.id, - payload - ); - }; + // fetch the object details if object state has id + useEffect(() => { + if (!issue?.entity) return; - // fetch the object details if object state has id - useEffect(() => { - if (!issue?.entity) return; + if (!entityAttributes[issue.entity]) { + if (!workspaceSlug) return; - if (!entityAttributes[issue.entity]) { - if (!workspaceSlug) return; + fetchEntityDetails(workspaceSlug.toString(), issue.entity); + } + }, [issue?.entity, entityAttributes, fetchEntityDetails, workspaceSlug]); - fetchEntityDetails(workspaceSlug.toString(), issue.entity); - } - }, [issue?.entity, entityAttributes, fetchEntityDetails, workspaceSlug]); + // fetch issue attribute values + useEffect(() => { + if (!issue) return; - // fetch issue attribute values - useEffect(() => { - if (!issue) return; + if (!issueAttributeValues || !issueAttributeValues[issue.id]) { + if (!workspaceSlug) return; - if (!issueAttributeValues || !issueAttributeValues[issue.id]) { - if (!workspaceSlug) return; + fetchIssueAttributeValues(workspaceSlug.toString(), issue.project, issue.id); + } + }, [fetchIssueAttributeValues, issue, issueAttributeValues, workspaceSlug]); - fetchIssueAttributeValues(workspaceSlug.toString(), issue.project, issue.id); - } - }, [fetchIssueAttributeValues, issue, issueAttributeValues, workspaceSlug]); + if (!issue || !issue?.entity) return null; - if (!issue || !issue?.entity) return null; + if (!entityAttributes[issue.entity] || !issueAttributeValues?.[issue.id]) + return ( + + + + + + + ); - if (!entityAttributes[issue.entity] || !issueAttributeValues?.[issue.id]) return ( - - - - - - + <> + {Object.values(entityAttributes?.[issue.entity] ?? {}).map((attribute) => { + const typeMetaData = CUSTOM_ATTRIBUTES_LIST[attribute.type]; + const attributeValue = issueAttributeValues?.[issue.id].find( + (a) => a.id === attribute.id + )?.prop_value; + + return ( +
+
+ +

{attribute.display_name}

+
+
+ {attribute.type === "checkbox" && ( + handleAttributeUpdate(attribute.id, [`${val}`])} + projectId={issue.project} + value={ + attributeValue + ? attributeValue?.[0]?.value === "true" + ? true + : false + : false + } + /> + )} + {attribute.type === "datetime" && ( + { + handleAttributeUpdate(attribute.id, val ? [val.toISOString()] : undefined); + }} + projectId={issue.project} + value={attributeValue ? new Date(attributeValue?.[0]?.value ?? "") : undefined} + /> + )} + {attribute.type === "email" && ( + { + handleAttributeUpdate(attribute.id, val && val !== "" ? [val] : undefined); + }} + projectId={issue.project} + value={attributeValue ? attributeValue?.[0]?.value : undefined} + /> + )} + {attribute.type === "file" && ( + handleAttributeUpdate(attribute.id, val)} + projectId={issue.project} + value={attributeValue ? attributeValue?.[0]?.value : undefined} + /> + )} + {attribute.type === "multi_select" && ( + handleAttributeUpdate(attribute.id, val)} + projectId={issue.project} + value={Array.isArray(attributeValue) ? attributeValue.map((v) => v.value) : []} + multiple + /> + )} + {attribute.type === "number" && ( + { + handleAttributeUpdate(attribute.id, val ? [val.toString()] : undefined); + }} + projectId={issue.project} + value={ + attributeValue ? parseInt(attributeValue?.[0]?.value ?? "0", 10) : undefined + } + /> + )} + {attribute.type === "relation" && ( + handleAttributeUpdate(attribute.id, val)} + projectId={issue.project} + value={attributeValue ? attributeValue?.[0]?.value : undefined} + /> + )} + {attribute.type === "select" && ( + handleAttributeUpdate(attribute.id, val)} + projectId={issue.project} + value={attributeValue ? attributeValue?.[0]?.value : undefined} + multiple={false} + /> + )} + {attribute.type === "text" && ( + + handleAttributeUpdate(attribute.id, val && val !== "" ? [val] : undefined) + } + projectId={issue.project} + value={attributeValue ? attributeValue?.[0].value : undefined} + /> + )} + {attribute.type === "url" && ( + + handleAttributeUpdate(attribute.id, val && val !== "" ? [val] : undefined) + } + projectId={issue.project} + value={attributeValue ? attributeValue?.[0]?.value : undefined} + /> + )} +
+
+ ); + })} + ); - - return ( - <> - {Object.values(entityAttributes?.[issue.entity] ?? {}).map((attribute) => { - const typeMetaData = CUSTOM_ATTRIBUTES_LIST[attribute.type]; - const attributeValue = issueAttributeValues?.[issue.id].find( - (a) => a.id === attribute.id - )?.prop_value; - - return ( -
-
- -

{attribute.display_name}

-
-
- {attribute.type === "checkbox" && ( - handleAttributeUpdate(attribute.id, val)} - projectId={issue.project} - value={ - attributeValue ? (attributeValue?.[0]?.value === "true" ? true : false) : false - } - /> - )} - {attribute.type === "datetime" && ( - handleAttributeUpdate(attribute.id, val)} - projectId={issue.project} - value={attributeValue ? new Date(attributeValue?.[0]?.value ?? "") : undefined} - /> - )} - {attribute.type === "email" && ( - handleAttributeUpdate(attribute.id, val)} - projectId={issue.project} - value={attributeValue ? attributeValue?.[0]?.value : undefined} - /> - )} - {attribute.type === "number" && ( - handleAttributeUpdate(attribute.id, val)} - projectId={issue.project} - value={ - attributeValue ? parseInt(attributeValue?.[0]?.value ?? "0", 10) : undefined - } - /> - )} - {attribute.type === "relation" && ( - handleAttributeUpdate(attribute.id, val)} - projectId={issue.project} - value={attributeValue ? attributeValue?.[0]?.value : undefined} - /> - )} - {attribute.type === "select" && ( - handleAttributeUpdate(attribute.id, val)} - projectId={issue.project} - value={attributeValue ? attributeValue?.[0]?.value : undefined} - /> - )} - {attribute.type === "text" && ( - handleAttributeUpdate(attribute.id, val)} - projectId={issue.project} - value={attributeValue ? attributeValue?.[0].value : undefined} - /> - )} - {attribute.type === "url" && ( - handleAttributeUpdate(attribute.id, val)} - projectId={issue.project} - value={attributeValue ? attributeValue?.[0]?.value : undefined} - /> - )} -
-
- ); - })} - - ); -}); + } +); diff --git a/web/components/custom-attributes/attributes-list/sidebar-custom-attributes-list.tsx b/web/components/custom-attributes/attributes-list/sidebar-custom-attributes-list.tsx index c038621af..a27139ba6 100644 --- a/web/components/custom-attributes/attributes-list/sidebar-custom-attributes-list.tsx +++ b/web/components/custom-attributes/attributes-list/sidebar-custom-attributes-list.tsx @@ -127,7 +127,7 @@ export const SidebarCustomAttributesList: React.FC = observer(({ issue, p { + onChange={(val) => { handleAttributeUpdate(attribute.id, val ? [val.toISOString()] : undefined); }} projectId={issue.project} @@ -169,7 +169,7 @@ export const SidebarCustomAttributesList: React.FC = observer(({ issue, p attributeDetails={attribute} issueId={issue.id} onChange={(val) => { - handleAttributeUpdate(attribute.id, val ? val.toString() : undefined); + handleAttributeUpdate(attribute.id, val ? [val.toString()] : undefined); }} projectId={issue.project} value={ diff --git a/web/components/issues/form.tsx b/web/components/issues/form.tsx index 4ad7ef258..401f9c83e 100644 --- a/web/components/issues/form.tsx +++ b/web/components/issues/form.tsx @@ -66,7 +66,7 @@ export interface IssueFormProps { setIsConfirmDiscardOpen: React.Dispatch>; handleFormDirty: (payload: Partial | null) => void; customAttributesList: { [key: string]: string[] }; - handleCustomAttributesChange: (attributeId: string, val: string[]) => void; + handleCustomAttributesChange: (attributeId: string, val: string | string[] | undefined) => void; fieldsToShow: TIssueFormAttributes[]; } @@ -429,7 +429,7 @@ export const IssueForm: FC = observer((props) => { /> )} {/* default object properties */} - {watch("entity") === null ? ( + {watch("entity") === null && ( <> {(fieldsToShow.includes("all") || fieldsToShow.includes("priority")) && ( = observer((props) => { )} - ) : ( + )} +
+ {watch("entity") !== null && ( +
= observer((props) => { projectId={projectId} values={customAttributesList} /> - )} -
+
+ )} diff --git a/web/components/issues/modal.tsx b/web/components/issues/modal.tsx index 0a3834f59..6a394bdae 100644 --- a/web/components/issues/modal.tsx +++ b/web/components/issues/modal.tsx @@ -128,6 +128,7 @@ export const CreateUpdateIssueModal: React.FC = observer( const onDiscardClose = () => { handleClose(); setActiveProject(null); + setCustomAttributesList({}); }; const handleFormDirty = (data: any) => { @@ -395,20 +396,35 @@ export const CreateUpdateIssueModal: React.FC = observer( const handleFormSubmit = async (formData: Partial) => { if (!workspaceSlug || !activeProject) return; - const payload: Partial = { - ...formData, - assignees_list: formData.assignees ?? [], - labels_list: formData.labels ?? [], - description: formData.description ?? "", + // set the fixed issue properties for the payload + let payload: Partial = { description_html: formData.description_html ?? "

", + entity: formData.entity, + name: formData.name, + state: formData.state, }; + // if entity is null, set the default object entity properties for the payload + if (formData.entity === null) + payload = { + ...payload, + ...formData, + assignees_list: formData.assignees ?? [], + labels_list: formData.labels ?? [], + }; + let issueResponse: Partial | undefined = {}; if (!data) issueResponse = await createIssue(payload); else issueResponse = await updateIssue(payload); - if (issueResponse && issueResponse.id && Object.keys(customAttributesList).length > 0) + // create custom attribute values, if any + if ( + payload.entity !== null && + issueResponse && + issueResponse.id && + Object.keys(customAttributesList).length > 0 + ) await createAttributeValue(workspaceSlug.toString(), activeProject, issueResponse.id, { issue_properties: customAttributesList, }); @@ -416,6 +432,27 @@ export const CreateUpdateIssueModal: React.FC = observer( if (onSubmit) await onSubmit(payload); }; + const handleCustomAttributesChange = ( + attributeId: string, + val: string | string[] | undefined + ) => { + if (!val) { + setCustomAttributesList((prev) => { + const newCustomAttributesList = { ...prev }; + delete newCustomAttributesList[attributeId]; + + return newCustomAttributesList; + }); + + return; + } + + setCustomAttributesList((prev) => ({ + ...prev, + [attributeId]: Array.isArray(val) ? val : [val], + })); + }; + if (!projects || projects.length === 0) return null; return ( @@ -471,12 +508,7 @@ export const CreateUpdateIssueModal: React.FC = observer( status={data ? true : false} user={user} customAttributesList={customAttributesList} - handleCustomAttributesChange={(attributeId: string, val: string[]) => { - setCustomAttributesList((prev) => ({ - ...prev, - [attributeId]: val, - })); - }} + handleCustomAttributesChange={handleCustomAttributesChange} fieldsToShow={fieldsToShow} handleFormDirty={handleFormDirty} /> diff --git a/web/components/issues/peek-overview/issue-properties.tsx b/web/components/issues/peek-overview/issue-properties.tsx index f17579247..0d5ba4cb7 100644 --- a/web/components/issues/peek-overview/issue-properties.tsx +++ b/web/components/issues/peek-overview/issue-properties.tsx @@ -165,7 +165,9 @@ export const PeekOverviewIssueProperties: React.FC = ({ )} - {issue.entity !== null && } + {issue.entity !== null && ( + + )} {/*
diff --git a/web/pages/[workspaceSlug]/projects/[projectId]/issues/[issueId].tsx b/web/pages/[workspaceSlug]/projects/[projectId]/issues/[issueId].tsx index 5fd754a30..5abd20088 100644 --- a/web/pages/[workspaceSlug]/projects/[projectId]/issues/[issueId].tsx +++ b/web/pages/[workspaceSlug]/projects/[projectId]/issues/[issueId].tsx @@ -148,7 +148,7 @@ const IssueDetailsPage: NextPage = () => {
-
+
{ this.error = error; }); + + this.fetchIssueAttributeValues(workspaceSlug, projectId, issueId); } }; @@ -130,6 +132,8 @@ class CustomAttributeValuesStore { runInAction(() => { this.error = error; }); + + this.fetchIssueAttributeValues(workspaceSlug, projectId, issueId); } }; }