Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -192,20 +192,24 @@ const EventDetailsSchedulingTab = ({
values.scheduleEndHour,
values.scheduleEndMinute,
);
dispatch(checkConflicts({ eventId, startDate, endDate, deviceId: values.captureAgent })).then(
r => {
if (r) {
const notifyNotUpdated = () => {
dispatch(addNotification({
type: "error",
key: "EVENTS_NOT_UPDATED",
duration: -1,
context: NOTIFICATION_CONTEXT,
}));
};

dispatch(checkConflicts({ eventId, startDate, endDate, deviceId: values.captureAgent })).unwrap()
.then(({ hasSchedulingConflicts }) => {
if (!hasSchedulingConflicts) {
dispatch(saveSchedulingInfo({ eventId, values, startDate, endDate })).then();
} else {
dispatch(addNotification({
type: "error",
key: "EVENTS_NOT_UPDATED",
duration: -1,
context: NOTIFICATION_CONTEXT,
}));
notifyNotUpdated();
}
},
);
})
.catch(notifyNotUpdated);
};

// initial values of the formik form
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ const SchedulingTime = ({
handleChange={element => {
if (element) {
callbackHour(element.value);
// TODO: Allow for ChangeMultiple for NewSourcePage
}
}}
placeholder={t(hourPlaceholder)}
Expand Down
26 changes: 19 additions & 7 deletions src/components/shared/Field.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
import { FastField as FormikFastField } from "formik";
import { FastField as FormikFastField, FastFieldConfig } from "formik";

/**
* Wrapper for the Formik Fields
* Wrapper for the Formik Fields.
*
* `FormikFastField` itself is typed as `React.FC<any>`, so
* `React.ComponentProps<typeof FormikFastField>` would just resolve to `any`.
* We derive from Formik's own `FastFieldConfig` instead (rather than hand-
* copying its shape), so this stays correct if Formik's config props change.
* `component`/`as` are re-typed more loosely than Formik declares them: this
* app passes app-specific extra props (e.g. `metadataField`) into custom
* components via sibling attributes on `<Field>`, which isn't something
* Formik's own types can verify either - it types its `Field` the same way.
*/
// TODO: Add strong typing
// The line below is currently just a fancy way of saying "any"
// Find a way to properly type this wrapper
type FieldProps = React.ComponentProps<typeof FormikFastField>;
export const Field = (props: FieldProps) => {
type FieldProps<V> = Omit<FastFieldConfig<V>, "component" | "as"> & {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
component?: string | React.ComponentType<any>,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
as?: string | React.ComponentType<any>,
} & Record<string, unknown>;

export const Field = <V = string>(props: FieldProps<V>) => {
return (
<FormikFastField
{...props}
Expand Down
7 changes: 3 additions & 4 deletions src/components/shared/MainNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,9 @@ const MainNav = ({
const arrToSort = linkMapItem.links;
if (arrToSort != undefined && arrToSort.length > 1) {
arrToSort.sort((a, b) => {
const aPriority = a.path === pathname ? 0 : 1;
const bPriority = b.path === pathname ? 0 : 1;

return aPriority - bPriority;
const aIndex = a.path === pathname ? 0 : 1;
const bIndex = b.path === pathname ? 0 : 1;
return aIndex - bIndex;
});
}
}
Expand Down
46 changes: 20 additions & 26 deletions src/components/shared/wizard/RenderField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,28 +32,22 @@ const RenderField = ({
}) => {
const { t } = useTranslation();

// TODO: Figure out how to type a ref that could have multiple types
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const editableRef = useRef<any>(null);
// Only one of the following is ever mounted at once, chosen by metadataField.type below.
const inputRef = useRef<HTMLInputElement>(null);
const textareaRef = useRef<HTMLTextAreaElement>(null);
const datePickerRef = useRef<DatePicker>(null);
const selectRef = useRef<SelectInstance<DropDownOption<string>, boolean, GroupBase<DropDownOption<string>>>>(null);
const [focused, setFocused] = useState(false);
const onFocus = () => setFocused(true);
const onBlur = () => setFocused(false);

return (
<div
onClick={() => {
if (editableRef.current) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (editableRef.current.focus) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
editableRef.current.focus();
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (editableRef.current.setFocus) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
editableRef.current.setFocus(); // For DatePicker
}
}
inputRef.current?.focus();
textareaRef.current?.focus();
selectRef.current?.focus();
datePickerRef.current?.setFocus();
}}
onFocus={onFocus}
onBlur={onBlur}
Expand All @@ -64,7 +58,7 @@ const RenderField = ({
field={field}
form={form}
isFirstField={isFirstField}
ref={editableRef}
ref={datePickerRef}
/>
)}
{metadataField.type === "text" &&
Expand All @@ -78,7 +72,7 @@ const RenderField = ({
isFirstField={isFirstField}
focused={focused}
setFocused={setFocused}
ref={editableRef}
ref={selectRef}
/>
)}
{metadataField.type === "ordered_text" && (
Expand All @@ -90,7 +84,7 @@ const RenderField = ({
isFirstField={isFirstField}
focused={focused}
setFocused={setFocused}
ref={editableRef}
ref={selectRef}
/>
)}
{metadataField.type === "text" &&
Expand All @@ -100,29 +94,29 @@ const RenderField = ({
<EditableSingleValue
field={field}
isFirstField={isFirstField}
ref={editableRef}
ref={inputRef}
/>
)}
{metadataField.type === "text_long" && (
<EditableSingleValueTextArea
field={field}
isFirstField={isFirstField}
ref={editableRef}
ref={textareaRef}
/>
)}
{metadataField.type === "date" && (
<EditableDateValue
field={field}
form={form}
isFirstField={isFirstField}
ref={editableRef}
ref={datePickerRef}
/>
)}
{metadataField.type === "boolean" && (
<EditableBooleanValue
field={field}
isFirstField={isFirstField}
ref={editableRef}
ref={inputRef}
/>
)}
<div className="single-value-right">
Expand All @@ -148,7 +142,7 @@ const EditableBooleanValue = ({
}: {
field: FieldProps["field"]
isFirstField?: boolean,
ref: React.RefObject<HTMLInputElement>
ref: React.RefObject<HTMLInputElement | null>
}) => {
return (
<input
Expand All @@ -171,7 +165,7 @@ const EditableDateValue = ({
field: FieldProps["field"]
form: FieldProps["form"]
isFirstField?: boolean,
ref: React.RefObject<DatePicker>
ref: React.RefObject<DatePicker | null>
}) => {
return (
// For some reason onclick events are bubbling up from the datepicker which we do not want.
Expand Down Expand Up @@ -254,7 +248,7 @@ const EditableSingleValueTextArea = ({
}: {
field: FieldProps["field"]
isFirstField?: boolean,
ref: React.RefObject<HTMLTextAreaElement>
ref: React.RefObject<HTMLTextAreaElement | null>
}) => {
return (
// Maybe replace TextareaAutosize with css "field-sizing: content" once all
Expand Down Expand Up @@ -304,7 +298,7 @@ const EditableSingleValueTime = ({
field: FieldProps["field"]
form: FieldProps["form"]
isFirstField?: boolean,
ref: React.RefObject<DatePicker>
ref: React.RefObject<DatePicker | null>
}) => {
return (
// For some reason onclick events are bubbling up from the datepicker which we do not want.
Expand Down
10 changes: 3 additions & 7 deletions src/slices/eventDetailsSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1190,8 +1190,6 @@ export const saveSchedulingInfo = createAppAsyncThunk("eventDetails/saveScheduli
return source;
});

// TODO: This does not return a boolean anymore. Fix this in usage, make users
// get their info from the state
export const checkConflicts = createAppAsyncThunk("eventDetails/checkConflicts", async (params: {
eventId: Event["id"],
startDate: Date,
Expand Down Expand Up @@ -1530,7 +1528,6 @@ export const fetchWorkflowErrorDetails = createAppAsyncThunk("eventDetails/fetch
return data.data;
});

// TODO: Fix this after the modernization of statisticsThunks happened
export const fetchEventStatistics = createAppAsyncThunk("eventDetails/fetchEventStatistics", async (eventId: Event["id"], { getState }) => {
// get prior statistics
const state = getState();
Expand All @@ -1545,7 +1542,6 @@ export const fetchEventStatistics = createAppAsyncThunk("eventDetails/fetchEvent
);
});

// TODO: Fix this after the modernization of statisticsThunks happened
export const fetchEventStatisticsValueUpdate = createAppAsyncThunk("eventDetails/fetchEventStatisticsValueUpdate", async (params: {
id: Event["id"],
providerId: string,
Expand Down Expand Up @@ -2367,9 +2363,9 @@ const eventDetailsSlice = createSlice({
})
.addCase(fetchWorkflowDetails.rejected, (state, action) => {
state.statusWorkflowDetails = "failed";
// This is the empty workflow data from the original reducer
// TODO: Figure out why it is so vastly different from our initial state
// and maybe fix our initial state if this is actually correct
// Falls back to the same placeholder as our initial state (workflowId/description
// only, not the full workflow-details shape); consumers already narrow on
// `"status" in workflow` before reading details-only fields, so this degrades safely.
const emptyWorkflowData = {
workflowId: "",
description: "",
Expand Down
Loading