Skip to content

Commit

Permalink
Merge pull request #2485 from NDLANO/refactor/revisions
Browse files Browse the repository at this point in the history
refactor: use primitives in revision field
  • Loading branch information
Jonas-C authored Oct 9, 2024
2 parents 89d6a24 + 34897ad commit 9645636
Show file tree
Hide file tree
Showing 9 changed files with 156 additions and 232 deletions.
4 changes: 2 additions & 2 deletions src/components/Accordion/FormAccordionsWithComments.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import OpenAllButton from "./OpenAllButton";
import { ARCHIVED, PUBLISHED, STORED_HIDE_COMMENTS, UNPUBLISHED } from "../../constants";
import CommentSection, { COMMENT_WIDTH, SPACING_COMMENT } from "../../containers/ArticlePage/components/CommentSection";
import { MainContent } from "../../containers/ArticlePage/styles";
import { RevisionMetaFormType } from "../../containers/FormikForm/AddRevisionDateField";
import { ArticleFormType } from "../../containers/FormikForm/articleFormHooks";
import { useLocalStorageBooleanState } from "../../containers/WelcomePage/hooks/storedFilterHooks";
import QualityEvaluation from "../QualityEvaluation/QualityEvaluation";
import { useWideArticle } from "../WideArticleEditorProvider";
Expand Down Expand Up @@ -77,7 +77,7 @@ const FormControls = styled(MainContent)`
const FormAccordionsWithComments = ({ defaultOpen, children, article, taxonomy, updateNotes }: Props) => {
const { t } = useTranslation();
const { toggleWideArticles, isWideArticle } = useWideArticle();
const [revisionMetaField, , revisionMetaHelpers] = useField<RevisionMetaFormType>("revisionMeta");
const [revisionMetaField, , revisionMetaHelpers] = useField<ArticleFormType["revisionMeta"]>("revisionMeta");

const [openAccordions, setOpenAccordions] = useState<string[]>(defaultOpen);
const [hideComments, setHideComments] = useLocalStorageBooleanState(STORED_HIDE_COMMENTS);
Expand Down
6 changes: 3 additions & 3 deletions src/components/QualityEvaluation/QualityEvaluation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { Node } from "@ndla/types-taxonomy";
import { Text } from "@ndla/typography";
import { gradeItemStyles, qualityEvaluationOptions } from "./QualityEvaluationForm";
import QualityEvaluationModal from "./QualityEvaluationModal";
import { RevisionMetaFormType } from "../../containers/FormikForm/AddRevisionDateField";
import { ArticleFormType } from "../../containers/FormikForm/articleFormHooks";
import SmallQualityEvaluationGrade from "../../containers/StructurePage/resourceComponents/QualityEvaluationGrade";

const FlexWrapper = styled.div`
Expand All @@ -40,8 +40,8 @@ interface Props {
article?: IArticle;
taxonomy?: Node[];
iconButtonColor?: "light" | "primary";
revisionMetaField?: FieldInputProps<RevisionMetaFormType>;
revisionMetaHelpers?: FieldHelperProps<RevisionMetaFormType>;
revisionMetaField?: FieldInputProps<ArticleFormType["revisionMeta"]>;
revisionMetaHelpers?: FieldHelperProps<ArticleFormType["revisionMeta"]>;
gradeVariant?: "small" | "large";
updateNotes?: (art: IUpdatedArticle) => Promise<IArticle>;
}
Expand Down
6 changes: 3 additions & 3 deletions src/components/QualityEvaluation/QualityEvaluationForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { colors, spacing, fonts, misc } from "@ndla/core";
import { FieldErrorMessage, Fieldset, InputV3, Label, Legend, RadioButtonGroup } from "@ndla/forms";
import { IArticle, IUpdatedArticle } from "@ndla/types-backend/draft-api";
import { Grade, Node } from "@ndla/types-taxonomy";
import { RevisionMetaFormType } from "../../containers/FormikForm/AddRevisionDateField";
import { ArticleFormType } from "../../containers/FormikForm/articleFormHooks";
import { useTaxonomyVersion } from "../../containers/StructureVersion/TaxonomyVersionProvider";
import { draftQueryKeys } from "../../modules/draft/draftQueries";
import { usePutNodeMutation } from "../../modules/nodes/nodeMutations";
Expand Down Expand Up @@ -101,8 +101,8 @@ const StyledFieldWarning = styled(FieldWarning)`
interface Props {
setOpen: (open: boolean) => void;
taxonomy: Node[];
revisionMetaField?: FieldInputProps<RevisionMetaFormType>;
revisionMetaHelpers?: FieldHelperProps<RevisionMetaFormType>;
revisionMetaField?: FieldInputProps<ArticleFormType["revisionMeta"]>;
revisionMetaHelpers?: FieldHelperProps<ArticleFormType["revisionMeta"]>;
updateNotes?: (art: IUpdatedArticle) => Promise<IArticle>;
article?: IArticle;
}
Expand Down
6 changes: 3 additions & 3 deletions src/components/QualityEvaluation/QualityEvaluationModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { IArticle, IUpdatedArticle } from "@ndla/types-backend/draft-api";
import { Node } from "@ndla/types-taxonomy";
import { Text } from "@ndla/typography";
import QualityEvaluationForm from "./QualityEvaluationForm";
import { RevisionMetaFormType } from "../../containers/FormikForm/AddRevisionDateField";
import { ArticleFormType } from "../../containers/FormikForm/articleFormHooks";

const StyledModalBody = styled(ModalBody)`
display: flex;
Expand All @@ -32,8 +32,8 @@ interface Props {
article?: IArticle;
taxonomy?: Node[];
iconButtonColor?: "light" | "primary";
revisionMetaField?: FieldInputProps<RevisionMetaFormType>;
revisionMetaHelpers?: FieldHelperProps<RevisionMetaFormType>;
revisionMetaField?: FieldInputProps<ArticleFormType["revisionMeta"]>;
revisionMetaHelpers?: FieldHelperProps<ArticleFormType["revisionMeta"]>;
updateNotes?: (art: IUpdatedArticle) => Promise<IArticle>;
}

Expand Down
169 changes: 142 additions & 27 deletions src/containers/ArticlePage/components/RevisionNotes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,41 +5,156 @@
* LICENSE file in the root directory of this source tree.
*
*/

import { addYears } from "date-fns";
import { FastField, FieldArray, FieldProps, useField } from "formik";
import { memo } from "react";
import { useTranslation } from "react-i18next";
import styled from "@emotion/styled";
import { colors } from "@ndla/core";
import FormikField from "../../../components/FormikField/FormikField";
import AddRevisionDateField from "../../FormikForm/AddRevisionDateField";
import { DeleteBinLine } from "@ndla/icons/action";
import {
Button,
FieldErrorMessage,
FieldInput,
FieldLabel,
FieldRoot,
FieldsetHelper,
FieldsetLegend,
FieldsetRoot,
IconButton,
SwitchControl,
SwitchHiddenInput,
SwitchLabel,
SwitchRoot,
SwitchThumb,
} from "@ndla/primitives";
import { styled } from "@ndla/styled-system/jsx";
import { Revision } from "../../../constants";
import { formatDateForBackend } from "../../../util/formatDate";
import { ArticleFormType } from "../../FormikForm/articleFormHooks";
import InlineDatePicker from "../../FormikForm/components/InlineDatePicker";
import { useMessages } from "../../Messages/MessagesProvider";

export type RevisionMetaFormType = ArticleFormType["revisionMeta"];

const FieldWrapper = styled(FieldsetRoot, {
base: {
display: "flex",
flexDirection: "row",
gap: "xsmall",
width: "100%",
alignItems: "center",
},
});

const ErrorField = styled.p`
color: ${colors.support.red};
`;
const StyledFieldRoot = styled(FieldRoot, {
base: {
flex: "1",
},
});

const RevisionNotes = () => {
const { t } = useTranslation();
const [_, { value }] = useField<RevisionMetaFormType>("revisionMeta");

const { createMessage } = useMessages();

return (
<FormikField
<FieldArray
name="revisionMeta"
label={t("form.name.revisions")}
description={t("form.revisions.description")}
showError={false}
>
{({ field, form: { errors } }) => {
return (
<>
<AddRevisionDateField
showError={!!errors[field.name]}
formikField={field}
name={field.name}
onChange={field.onChange}
value={field.value}
/>
<ErrorField> {errors.revisionError} </ErrorField>
</>
);
}}
</FormikField>
render={(arrayHelpers) => (
<FieldsetRoot>
<FieldsetLegend>{t("form.name.revisions")}</FieldsetLegend>
<FieldsetHelper>{t("form.revisions.description")}</FieldsetHelper>
{value.map((_, index) => (
<FieldsetRoot key={`revision-${index}`} name={`revision.${index}`}>
<FieldsetLegend srOnly>{t("form.revisions.revisionNumber", { number: index + 1 })}</FieldsetLegend>
<FieldWrapper>
<FastField name={`revisionMeta.${index}.note`}>
{({ field, meta }: FieldProps) => (
<StyledFieldRoot required invalid={!!meta.error}>
<FieldLabel srOnly>{t("form.name.note")}</FieldLabel>
<FieldErrorMessage>{meta.error}</FieldErrorMessage>
<FieldInput
{...field}
// eslint-disable-next-line jsx-a11y/no-autofocus
autoFocus
placeholder={t("form.revisions.inputPlaceholder")}
data-testid="revisionInput"
/>
</StyledFieldRoot>
)}
</FastField>
<FastField name={`revisionMeta.${index}.revisionDate`}>
{({ field, meta, form }: FieldProps) => (
<FieldRoot required invalid={!!meta.error}>
<FieldLabel srOnly>{t("form.name.date")}</FieldLabel>
<FieldErrorMessage>{meta.error}</FieldErrorMessage>
<InlineDatePicker
aria-label={t("form.revisions.datePickerTooltip")}
value={field.value}
name={`revision_date_${index}`}
onChange={(evt) => {
form.setFieldValue(field.name, evt.target.value, true);
}}
title={t("form.revisions.datePickerTooltip")}
/>
</FieldRoot>
)}
</FastField>
<FastField name={`revisionMeta.${index}.status`}>
{({ field, meta, form }: FieldProps) => (
<FieldRoot invalid={!!meta.error}>
<SwitchRoot
title={t("form.revisions.switchTooltip")}
checked={field.value === Revision.revised}
onCheckedChange={(details) => {
const status = details.checked ? Revision.revised : Revision.needsRevision;
form.setFieldValue(field.name, status);
if (status === Revision.revised) {
createMessage({
translationKey: "form.revisions.reminder",
severity: "info",
timeToLive: 0,
});
}
}}
>
<SwitchLabel srOnly>{t("form.revisions.switchTooltip")}</SwitchLabel>
<SwitchControl>
<SwitchThumb />
</SwitchControl>
<SwitchHiddenInput />
</SwitchRoot>
</FieldRoot>
)}
</FastField>
<IconButton
variant="danger"
aria-label={t("form.revisions.deleteTooltip")}
title={t("form.revisions.deleteTooltip")}
onClick={() => arrayHelpers.remove(index)}
>
<DeleteBinLine />
</IconButton>
</FieldWrapper>
</FieldsetRoot>
))}
<Button
variant="secondary"
onClick={() =>
arrayHelpers.push({
note: "",
revisionDate: formatDateForBackend(addYears(new Date(), 5)),
status: "needs-revision",
new: true,
})
}
>
{t("form.revisions.add")}
</Button>
</FieldsetRoot>
)}
/>
);
};

Expand Down
Loading

0 comments on commit 9645636

Please sign in to comment.