From 6fff662ed60a8bc48cf8d4a53e0ae0e7e213ece7 Mon Sep 17 00:00:00 2001 From: Gertjan van Oosten Date: Tue, 16 Jan 2024 16:43:01 +0100 Subject: [PATCH 1/7] AB#904 Merge two conditions --- client/src/pages/people/Form.js | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/client/src/pages/people/Form.js b/client/src/pages/people/Form.js index d7422b30bc..d8aa23d0be 100644 --- a/client/src/pages/people/Form.js +++ b/client/src/pages/people/Form.js @@ -219,7 +219,9 @@ const PersonForm = ({ // admins and superusers with edit permissions can change status to INACTIVE, // only admins can change back to ACTIVE (but nobody can change status of self!) const disableStatusChange = - (initialValues.status === Model.STATUS.INACTIVE && !isAdmin) || isSelf + (initialValues.status === Model.STATUS.INACTIVE && !isAdmin) || + isPendingVerification || + isSelf const currentAvatar = attachmentList?.find( a => a.uuid === currentAvatarUuid ) @@ -565,13 +567,6 @@ const PersonForm = ({ component={FieldHelper.ReadonlyField} humanValue={Person.humanNameOfStatus(values.status)} /> - ) : isPendingVerification ? ( - ) : ( Date: Tue, 16 Jan 2024 16:44:48 +0100 Subject: [PATCH 2/7] AB#904 Show the correct page title and button text when a user is pending verification --- client/src/pages/people/Edit.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/client/src/pages/people/Edit.js b/client/src/pages/people/Edit.js index 9abfe87f23..0ef203cbb2 100644 --- a/client/src/pages/people/Edit.js +++ b/client/src/pages/people/Edit.js @@ -1,6 +1,7 @@ import { gql } from "@apollo/client" import { DEFAULT_SEARCH_PROPS, PAGE_PROPS_NO_NAV } from "actions" import API from "api" +import AppContext from "components/AppContext" import { initInvisibleFields } from "components/CustomFields" import { DEFAULT_CUSTOM_FIELDS_PARENT, @@ -18,7 +19,7 @@ import RelatedObjectNotes, { } from "components/RelatedObjectNotes" import { Attachment, Person } from "models" import moment from "moment" -import React from "react" +import React, { useContext } from "react" import { connect } from "react-redux" import { useParams } from "react-router-dom" import Settings from "settings" @@ -67,6 +68,7 @@ const GQL_GET_PERSON = gql` ` const PersonEdit = ({ pageDispatchers }) => { + const { currentUser } = useContext(AppContext) const { uuid } = useParams() const { loading, error, data } = API.useApiQuery(GQL_GET_PERSON, { uuid @@ -103,12 +105,10 @@ const PersonEdit = ({ pageDispatchers }) => { } } const person = new Person(data ? data.person : {}) - const legendText = person.isPendingVerification() - ? "Create your account" - : `Edit ${person.name}` - const saveText = person.isPendingVerification() - ? "Update profile" - : "Save Person" + const isPending = + person.isPendingVerification() && Person.isEqual(currentUser, person) + const legendText = isPending ? "Create your account" : `Edit ${person.name}` + const saveText = isPending ? "Update profile" : "Save Person" // mutates the object initInvisibleFields(person, Settings.fields.person.customFields) From bbad1b4ba602a46e03bf5be5b6f1755b60a623b1 Mon Sep 17 00:00:00 2001 From: Gertjan van Oosten Date: Wed, 17 Jan 2024 10:07:15 +0100 Subject: [PATCH 3/7] Make sure the openIdSubject is cleared out when inactivating a person --- src/main/java/mil/dds/anet/resources/PersonResource.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/mil/dds/anet/resources/PersonResource.java b/src/main/java/mil/dds/anet/resources/PersonResource.java index 83e1eaebf6..af2cf9cba8 100644 --- a/src/main/java/mil/dds/anet/resources/PersonResource.java +++ b/src/main/java/mil/dds/anet/resources/PersonResource.java @@ -164,6 +164,7 @@ public Integer updatePerson(@GraphQLRootContext Map context, p, existing.getDomainUsername(), existing.getOpenIdSubject(), user); p.setDomainUsername(null); p.setOpenIdSubject(null); + dao.updateAuthenticationDetails(p); } // Automatically remove people from a position if they are inactive. From f51e5b5aeb80dacede9fab601e5c3f352cf98f81 Mon Sep 17 00:00:00 2001 From: Gertjan van Oosten Date: Wed, 17 Jan 2024 15:42:11 +0100 Subject: [PATCH 4/7] NCI-Agency/anet#1287 Show proper label for advanced search filter on organization profile --- client/src/components/SearchFilters.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/components/SearchFilters.js b/client/src/components/SearchFilters.js index 37b0d4e559..211f867652 100644 --- a/client/src/components/SearchFilters.js +++ b/client/src/components/SearchFilters.js @@ -444,7 +444,7 @@ export const searchFilters = function() { queryKey: "locationUuid" }) }, - [`Has ${Settings.fields.organization.profile}?`]: { + [`Has ${Settings.fields.organization.profile?.label}?`]: { component: RadioButtonFilter, deserializer: deserializeSelectFilter, props: { From 2e7b4290077e429d7d51e72cbaaaa1cdd2cd5a7a Mon Sep 17 00:00:00 2001 From: Gertjan van Oosten Date: Mon, 29 Jan 2024 09:56:10 +0100 Subject: [PATCH 5/7] AB#910 Fix 'select all' in the rich-text editor --- .../src/components/editor/LinkSourceAnet.js | 48 +++++++++---------- client/src/components/editor/Toolbar.js | 4 +- client/src/richTextUtils.js | 8 ++++ 3 files changed, 34 insertions(+), 26 deletions(-) create mode 100644 client/src/richTextUtils.js diff --git a/client/src/components/editor/LinkSourceAnet.js b/client/src/components/editor/LinkSourceAnet.js index c70a864366..59fc5cea39 100644 --- a/client/src/components/editor/LinkSourceAnet.js +++ b/client/src/components/editor/LinkSourceAnet.js @@ -4,7 +4,8 @@ import { FastField, Form, Formik } from "formik" import PropTypes from "prop-types" import React, { useCallback } from "react" import { Button, Form as FormBS, Modal } from "react-bootstrap" -import { Editor, Transforms } from "slate" +import { getSelectedParentNode } from "richTextUtils" +import { Transforms } from "slate" import { ReactEditor } from "slate-react" import { ANET_LINK, EXTERNAL_LINK, getEntityInfoFromUrl } from "utils_links" import * as yup from "yup" @@ -79,29 +80,6 @@ const LinkSourceAnet = ({ editor, showModal, setShowModal, external }) => { ) - - function getParentNodeProps(editor, external) { - const selectedParentNode = - editor.selection && Editor.parent(editor, editor.selection) - const selectedParent = selectedParentNode?.[0] - let value - if (external && selectedParent?.type === EXTERNAL_LINK) { - value = { - url: selectedParent.url, - text: selectedParent.children?.[0]?.text - } - } else if (!external && selectedParent?.type === ANET_LINK) { - value = { - objectType: selectedParent.entityType, - object: selectedParent.entityUuid - ? { uuid: selectedParent.entityUuid } - : null - } - } else { - value = null - } - return { replaceSelection: !!value, selectedParentNode, value } - } } LinkSourceAnet.propTypes = { @@ -193,4 +171,26 @@ function createExternalLinkNode(url, text) { } } +function getParentNodeProps(editor, external) { + const selectedParentNode = getSelectedParentNode(editor) + const selectedParent = selectedParentNode?.[0] + let value + if (external && selectedParent?.type === EXTERNAL_LINK) { + value = { + url: selectedParent.url, + text: selectedParent.children?.[0]?.text + } + } else if (!external && selectedParent?.type === ANET_LINK) { + value = { + objectType: selectedParent.entityType, + object: selectedParent.entityUuid + ? { uuid: selectedParent.entityUuid } + : null + } + } else { + value = null + } + return { replaceSelection: !!value, selectedParentNode, value } +} + export default LinkSourceAnet diff --git a/client/src/components/editor/Toolbar.js b/client/src/components/editor/Toolbar.js index be72f5647f..51f018ee3b 100644 --- a/client/src/components/editor/Toolbar.js +++ b/client/src/components/editor/Toolbar.js @@ -2,6 +2,7 @@ import { Icon } from "@blueprintjs/core" import { Tooltip2 } from "@blueprintjs/popover2" import PropTypes from "prop-types" import React from "react" +import { getSelectedParentNode } from "richTextUtils" import { Editor, Transforms } from "slate" import { useSlate } from "slate-react" import { ANET_LINK, EXTERNAL_LINK } from "utils_links" @@ -212,8 +213,7 @@ function isMarkActive(editor, format) { } function isModalActive(editor, format, showModal) { - const selectedParent = - editor.selection && Editor.parent(editor, editor.selection)?.[0] + const selectedParent = getSelectedParentNode(editor)?.[0] return showModal || selectedParent?.type === format } diff --git a/client/src/richTextUtils.js b/client/src/richTextUtils.js new file mode 100644 index 0000000000..8f22ccd8f1 --- /dev/null +++ b/client/src/richTextUtils.js @@ -0,0 +1,8 @@ +import { Editor } from "slate" + +export function getSelectedParentNode(editor) { + const path = Editor.path(editor, editor.selection) + return ( + path?.length && editor.selection && Editor.parent(editor, editor.selection) + ) +} From 03b547b7d1fec85fb91f6134322a31c0183375d5 Mon Sep 17 00:00:00 2001 From: Gertjan van Oosten Date: Wed, 31 Jan 2024 15:51:13 +0100 Subject: [PATCH 6/7] NCI-Agency/anet#1287 Make DictionaryField a normal component Instead of a HOC, which would re-render all fields on changes. --- client/src/HOC/DictionaryField.js | 25 ------ client/src/components/AdvancedSearch.js | 18 ++-- client/src/components/DictionaryField.js | 28 +++++++ .../EditAdministratingPositionsModal.js | 6 +- .../EditOrganizationsAdministratedModal.js | 6 +- client/src/components/SearchFilters.js | 10 +-- .../components/previews/AttachmentPreview.js | 9 +- .../components/previews/LocationPreview.js | 12 +-- .../previews/OrganizationPreview.js | 27 +++--- .../src/components/previews/PersonPreview.js | 33 +++++--- .../components/previews/PositionPreview.js | 21 +++-- .../src/components/previews/ReportPreview.js | 30 ++++--- client/src/components/previews/TaskPreview.js | 27 +++--- .../src/pages/admin/merge/MergeLocations.js | 28 ++++--- client/src/pages/admin/merge/MergePeople.js | 82 ++++++++++++------- .../src/pages/admin/merge/MergePositions.js | 46 +++++++---- client/src/pages/attachments/Form.js | 18 ++-- client/src/pages/attachments/Show.js | 12 +-- client/src/pages/locations/Form.js | 16 ++-- client/src/pages/locations/Show.js | 15 ++-- client/src/pages/onboarding/Show.js | 6 +- client/src/pages/organizations/Form.js | 53 +++++++----- client/src/pages/organizations/Show.js | 27 +++--- client/src/pages/people/Compact.js | 6 +- client/src/pages/people/Form.js | 48 ++++++----- client/src/pages/people/Show.js | 6 +- client/src/pages/positions/Form.js | 31 ++++--- client/src/pages/positions/Show.js | 21 +++-- client/src/pages/reports/Compact.js | 25 +++--- client/src/pages/reports/Form.js | 40 +++++---- client/src/pages/reports/Show.js | 30 ++++--- client/src/pages/tasks/Form.js | 35 ++++---- client/src/pages/tasks/Show.js | 27 +++--- 33 files changed, 497 insertions(+), 327 deletions(-) delete mode 100644 client/src/HOC/DictionaryField.js create mode 100644 client/src/components/DictionaryField.js diff --git a/client/src/HOC/DictionaryField.js b/client/src/HOC/DictionaryField.js deleted file mode 100644 index 7f31492f65..0000000000 --- a/client/src/HOC/DictionaryField.js +++ /dev/null @@ -1,25 +0,0 @@ -import _isEmpty from "lodash/isEmpty" -import PropTypes from "prop-types" -import React from "react" - -const DictionaryField = WrappedComponent => { - const Wrapper = ({ dictProps, ...otherProps }) => { - // Only display field if the dictProps are defined - if (_isEmpty(dictProps) || dictProps?.exclude) { - return null - } else { - return ( - - ) - } - } - Wrapper.propTypes = { - dictProps: PropTypes.object - } - return Wrapper -} - -export default DictionaryField diff --git a/client/src/components/AdvancedSearch.js b/client/src/components/AdvancedSearch.js index 08302ea3a0..e339b82b3c 100644 --- a/client/src/components/AdvancedSearch.js +++ b/client/src/components/AdvancedSearch.js @@ -3,6 +3,7 @@ import "@blueprintjs/popover2/lib/css/blueprint-popover2.css" import styled from "@emotion/styled" import { resetPagination, SEARCH_OBJECT_LABELS, setSearchQuery } from "actions" import ButtonToggleGroup from "components/ButtonToggleGroup" +import DictionaryField from "components/DictionaryField" import RemoveButton from "components/RemoveButton" import { findCommonFiltersForAllObjectTypes, @@ -10,7 +11,6 @@ import { SearchQueryPropType } from "components/SearchFilters" import { Form, Formik } from "formik" -import DictionaryField from "HOC/DictionaryField" import _cloneDeep from "lodash/cloneDeep" import { Organization, Position } from "models" import PropTypes from "prop-types" @@ -79,10 +79,10 @@ const AdvancedSearch = ({ {Object.entries(filterDefs).map(([filterKey, filterDef]) => { const dictProps = filterDef.dictProps const label = dictProps?.label || filterKey - const ChildComponent = dictProps - ? DictionaryField(Dropdown.Item) - : Dropdown.Item - const additionalProps = dictProps ? { dictProps } : {} + const ChildComponent = dictProps ? DictionaryField : Dropdown.Item + const additionalProps = dictProps + ? { wrappedComponent: Dropdown.Item, dictProps } + : {} return dictProps?.exclude ? null : ( { const dictProps = element.dictProps const label = dictProps?.label || filter.key - const ChildComponent = dictProps - ? DictionaryField(element.component) - : element.component - const additionalProps = dictProps ? { dictProps } : {} + const ChildComponent = dictProps ? DictionaryField : element.component + const additionalProps = dictProps + ? { wrappedComponent: element.component, dictProps } + : {} const { queryKey } = element.props || undefined return dictProps?.exclude ? null : ( diff --git a/client/src/components/DictionaryField.js b/client/src/components/DictionaryField.js new file mode 100644 index 0000000000..a58cbe786c --- /dev/null +++ b/client/src/components/DictionaryField.js @@ -0,0 +1,28 @@ +import _isEmpty from "lodash/isEmpty" +import PropTypes from "prop-types" +import React from "react" + +const DictionaryField = ({ + wrappedComponent: WrappedComponent, + dictProps, + ...otherProps +}) => { + // Only display field if the dictProps are defined + if (_isEmpty(dictProps) || dictProps?.exclude) { + return null + } else { + return ( + + ) + } +} + +DictionaryField.propTypes = { + wrappedComponent: PropTypes.any, + dictProps: PropTypes.object +} + +export default DictionaryField diff --git a/client/src/components/EditAdministratingPositionsModal.js b/client/src/components/EditAdministratingPositionsModal.js index 60f84eb932..ea21b51d35 100644 --- a/client/src/components/EditAdministratingPositionsModal.js +++ b/client/src/components/EditAdministratingPositionsModal.js @@ -3,12 +3,12 @@ import API from "api" import AdvancedMultiSelect from "components/advancedSelectWidget/AdvancedMultiSelect" import { PositionOverlayRow } from "components/advancedSelectWidget/AdvancedSelectOverlayRow" import { customFieldsJSONString } from "components/CustomFields" +import DictionaryField from "components/DictionaryField" import * as FieldHelper from "components/FieldHelper" import Messages from "components/Messages" import Model from "components/Model" import PositionTable from "components/PositionTable" import { FastField, Form, Formik } from "formik" -import DictionaryField from "HOC/DictionaryField" import Organization from "models/Organization" import Position from "models/Position" import PropTypes from "prop-types" @@ -37,7 +37,6 @@ const EditAdministratingPositionsModal = ({ ?.administratingPositions) ?? [] - const DictFastField = DictionaryField(FastField) const positionsFilters = { allAdvisorPositions: { label: "All advisor positions", @@ -74,7 +73,8 @@ const EditAdministratingPositionsModal = ({ - { const [error, setError] = useState(null) - const DictFastField = DictionaryField(FastField) const organizationsFilters = { allOrganizations: { label: "All organizations", @@ -65,7 +64,8 @@ const EditOrganizationsAdministratedModal = ({ - { const dictProps = element.dictProps const label = dictProps?.label || filter.key - const ChildComponent = dictProps - ? DictionaryField(element.component) - : element.component - const additionalProps = dictProps ? { dictProps } : {} + const ChildComponent = dictProps ? DictionaryField : element.component + const additionalProps = dictProps + ? { wrappedComponent: element.component, dictProps } + : {} const sep = showSeparator ? ", " : "" return dictProps?.exclude ? null : ( <> diff --git a/client/src/components/previews/AttachmentPreview.js b/client/src/components/previews/AttachmentPreview.js index 0e540f8b30..d19621c052 100644 --- a/client/src/components/previews/AttachmentPreview.js +++ b/client/src/components/previews/AttachmentPreview.js @@ -1,9 +1,9 @@ import { gql } from "@apollo/client" import API from "api" +import DictionaryField from "components/DictionaryField" import { PreviewField } from "components/FieldHelper" import LinkTo from "components/LinkTo" import RichTextEditor from "components/RichTextEditor" -import DictionaryField from "HOC/DictionaryField" import { Attachment } from "models" import PropTypes from "prop-types" import React from "react" @@ -40,7 +40,6 @@ const AttachmentPreview = ({ className, uuid }) => { const attachment = new Attachment(data.attachment ? data.attachment : {}) const { backgroundImage } = utils.getAttachmentIconDetails(attachment) - const DictPreviewField = DictionaryField(PreviewField) return (
@@ -57,7 +56,8 @@ const AttachmentPreview = ({ className, uuid }) => { style={{ width: "100%", borderRadius: "5px" }} /> - @@ -70,7 +70,8 @@ const AttachmentPreview = ({ className, uuid }) => { label="Content length" value={utils.humanReadableFileSize(attachment.contentLength)} /> - { const location = new Location(data.location ? data.location : {}) const label = Location.LOCATION_FORMAT_LABELS[Location.locationFormat] - const DictPreviewField = DictionaryField(PreviewField) const marker = { id: location.uuid || 0, @@ -59,7 +58,8 @@ const LocationPreview = ({ className, uuid }) => {

{`Location ${location.name}`}

- @@ -80,13 +80,15 @@ const LocationPreview = ({ className, uuid }) => { } /> - {location.description && ( - } /> diff --git a/client/src/components/previews/OrganizationPreview.js b/client/src/components/previews/OrganizationPreview.js index 5703a03e81..eb5e6119ce 100644 --- a/client/src/components/previews/OrganizationPreview.js +++ b/client/src/components/previews/OrganizationPreview.js @@ -1,10 +1,10 @@ import { gql } from "@apollo/client" import API from "api" +import DictionaryField from "components/DictionaryField" import { PreviewField } from "components/FieldHelper" import LinkTo from "components/LinkTo" import Model from "components/Model" import RichTextEditor from "components/RichTextEditor" -import DictionaryField from "HOC/DictionaryField" import _isEmpty from "lodash/isEmpty" import { Location, Organization } from "models" import { PositionRole } from "models/Position" @@ -122,7 +122,6 @@ const OrganizationPreview = ({ className, uuid }) => { const organization = new Organization( data.organization ? data.organization : {} ) - const DictPreviewField = DictionaryField(PreviewField) return (
@@ -130,18 +129,21 @@ const OrganizationPreview = ({ className, uuid }) => {

{`Organization ${organization.shortName}`}

- - {organization?.parentOrg?.uuid && ( - @@ -150,7 +152,8 @@ const OrganizationPreview = ({ className, uuid }) => { )} {organization?.childrenOrgs?.length > 0 && ( - @@ -176,12 +179,14 @@ const OrganizationPreview = ({ className, uuid }) => { pluralize(utils.titleCase(PositionRole.DEPUTY.humanNameOfRole())) )} - - { } /> - {organization.profile && ( - } /> diff --git a/client/src/components/previews/PersonPreview.js b/client/src/components/previews/PersonPreview.js index 0990feb340..7acc825e7b 100644 --- a/client/src/components/previews/PersonPreview.js +++ b/client/src/components/previews/PersonPreview.js @@ -2,12 +2,12 @@ import { gql } from "@apollo/client" import API from "api" import AppContext from "components/AppContext" import AvatarDisplayComponent from "components/AvatarDisplayComponent" +import DictionaryField from "components/DictionaryField" import { PreviewField } from "components/FieldHelper" import LinkTo from "components/LinkTo" import { DEFAULT_CUSTOM_FIELDS_PARENT } from "components/Model" import PreviousPositions from "components/PreviousPositions" import RichTextEditor from "components/RichTextEditor" -import DictionaryField from "HOC/DictionaryField" import { Person, Position } from "models" import moment from "moment" import PropTypes from "prop-types" @@ -97,7 +97,6 @@ const PersonPreview = ({ className, uuid }) => { ) const person = new Person(data.person ? data.person : {}) - const DictPreviewField = DictionaryField(PreviewField) // The position for this person's counterparts const position = person.position @@ -127,55 +126,65 @@ const PersonPreview = ({ className, uuid }) => { />
- - {isAdmin && ( - )} - - - - - - - { } const position = new Position(data.position ? data.position : {}) - const DictPreviewField = DictionaryField(PreviewField) const isPrincipal = position.type === Position.TYPE.PRINCIPAL const assignedRole = isPrincipal @@ -98,13 +97,15 @@ const PositionPreview = ({ className, uuid }) => {

{`Position ${position.name}`}

- {position.organization && ( - @@ -112,7 +113,8 @@ const PositionPreview = ({ className, uuid }) => { /> )} - { } /> - - - diff --git a/client/src/components/previews/ReportPreview.js b/client/src/components/previews/ReportPreview.js index c5e36cf5b9..62cfdcf313 100644 --- a/client/src/components/previews/ReportPreview.js +++ b/client/src/components/previews/ReportPreview.js @@ -1,11 +1,11 @@ import { gql } from "@apollo/client" import API from "api" +import DictionaryField from "components/DictionaryField" import { PreviewField } from "components/FieldHelper" import LinkTo from "components/LinkTo" import NoPaginationTaskTable from "components/NoPaginationTaskTable" import PlanningConflictForReport from "components/PlanningConflictForReport" import RichTextEditor from "components/RichTextEditor" -import DictionaryField from "HOC/DictionaryField" import { Person, Report, Task } from "models" import moment from "moment" import ReportPeople from "pages/reports/ReportPeople" @@ -123,7 +123,6 @@ const ReportPreview = ({ className, uuid }) => { report = new Report(data.report) const reportType = report.isFuture() ? "planned engagement" : "report" const tasksLabel = pluralize(Settings.fields.task.subLevel.shortLabel) - const DictPreviewField = DictionaryField(PreviewField) // Get initial tasks/people instant assessments values const hasAssessments = report.engagementDate && !report.isFuture() @@ -178,17 +177,20 @@ const ReportPreview = ({ className, uuid }) => { label="Summary" value={
- - - { } /> - { /> {Settings.engagementsIncludeTimeAndDuration && report.duration && ( - { } /> - { /> {report.cancelled && ( - { {!report.cancelled && ( <> - - { Model.populateCustomFields(data.task) } const task = new Task(data.task ? data.task : {}) - const DictPreviewField = DictionaryField(PreviewField) const fieldSettings = task.fieldSettings() return ( @@ -135,11 +134,13 @@ const TaskPreview = ({ className, uuid }) => {

{`${fieldSettings.shortLabel} ${task.shortName}`}

- - { /> {Settings.fields.task.parentTask && task.parentTask?.uuid && ( - { {Settings.fields.task.childrenTasks && task.childrenTasks?.length > 0 && ( - { )} {Settings.fields.task.plannedCompletion && ( - { )} {Settings.fields.task.projectedCompletion && ( - { /> )} - {task.description && ( - } /> diff --git a/client/src/pages/admin/merge/MergeLocations.js b/client/src/pages/admin/merge/MergeLocations.js index 3ac8cbc606..4239c0641b 100644 --- a/client/src/pages/admin/merge/MergeLocations.js +++ b/client/src/pages/admin/merge/MergeLocations.js @@ -7,6 +7,7 @@ import { LocationOverlayRow } from "components/advancedSelectWidget/AdvancedSele import AdvancedSingleSelect from "components/advancedSelectWidget/AdvancedSingleSelect" import ApprovalSteps from "components/ApprovalSteps" import { customFieldsJSONString } from "components/CustomFields" +import DictionaryField from "components/DictionaryField" import BaseGeoLocation from "components/GeoLocation" import MergeField from "components/MergeField" import Messages from "components/Messages" @@ -24,7 +25,6 @@ import { } from "components/Page" import RichTextEditor from "components/RichTextEditor" import { convertLatLngToMGRS } from "geoUtils" -import DictionaryField from "HOC/DictionaryField" import useMergeObjects, { ALIGN_OPTIONS, areAllSet, @@ -71,7 +71,6 @@ const MergeLocations = ({ pageDispatchers }) => { }) usePageTitle("Merge Locations") - const DictMergeField = DictionaryField(MergeField) const location1 = mergeState[MERGE_SIDES.LEFT] const location2 = mergeState[MERGE_SIDES.RIGHT] const mergedLocation = mergeState.merged @@ -140,7 +139,8 @@ const MergeLocations = ({ pageDispatchers }) => { )} {areAllSet(location1, location2, mergedLocation) && (
- { dispatchMergeActions={dispatchMergeActions} /> - { dispatchMergeActions={dispatchMergeActions} /> {getLeafletMap("merged-location-map", mergedLocation)} - { mergeState={mergeState} dispatchMergeActions={dispatchMergeActions} /> - @@ -370,7 +373,6 @@ const LocationColumn = ({ setLocationFormat, locationFormatLabel }) => { - const DictMergeField = DictionaryField(MergeField) const location = mergeState[align] const idForLocation = label.replace(/\s+/g, "") return ( @@ -408,7 +410,8 @@ const LocationColumn = ({ {areAllSet(location) && (
- - {getLeafletMap(`merge-location-map-${align}`, location)} - - } diff --git a/client/src/pages/admin/merge/MergePeople.js b/client/src/pages/admin/merge/MergePeople.js index d441f1d618..c2027c8616 100644 --- a/client/src/pages/admin/merge/MergePeople.js +++ b/client/src/pages/admin/merge/MergePeople.js @@ -7,6 +7,7 @@ import { PersonSimpleOverlayRow } from "components/advancedSelectWidget/Advanced import AdvancedSingleSelect from "components/advancedSelectWidget/AdvancedSingleSelect" import AvatarDisplayComponent from "components/AvatarDisplayComponent" import { customFieldsJSONString } from "components/CustomFields" +import DictionaryField from "components/DictionaryField" import EditHistory from "components/EditHistory" import LinkTo from "components/LinkTo" import MergeField from "components/MergeField" @@ -25,7 +26,6 @@ import { } from "components/Page" import PreviousPositions from "components/PreviousPositions" import RichTextEditor from "components/RichTextEditor" -import DictionaryField from "HOC/DictionaryField" import useMergeObjects, { ALIGN_OPTIONS, areAllSet, @@ -73,7 +73,6 @@ const MergePeople = ({ pageDispatchers }) => { }) usePageTitle("Merge People") - const DictMergeField = DictionaryField(MergeField) const person1 = mergeState[MERGE_SIDES.LEFT] const person2 = mergeState[MERGE_SIDES.RIGHT] const mergedPerson = mergeState.merged @@ -202,7 +201,8 @@ const MergePeople = ({ pageDispatchers }) => { mergeState={mergeState} dispatchMergeActions={dispatchMergeActions} /> - { mergeState={mergeState} dispatchMergeActions={dispatchMergeActions} /> - { mergeState={mergeState} dispatchMergeActions={dispatchMergeActions} /> - @@ -259,7 +261,8 @@ const MergePeople = ({ pageDispatchers }) => { mergeState={mergeState} dispatchMergeActions={dispatchMergeActions} /> - @@ -301,7 +304,8 @@ const MergePeople = ({ pageDispatchers }) => { mergeState={mergeState} dispatchMergeActions={dispatchMergeActions} /> - { mergeState={mergeState} dispatchMergeActions={dispatchMergeActions} /> - { mergeState={mergeState} dispatchMergeActions={dispatchMergeActions} /> - { mergeState={mergeState} dispatchMergeActions={dispatchMergeActions} /> - { mergeState={mergeState} dispatchMergeActions={dispatchMergeActions} /> - { mergeState={mergeState} dispatchMergeActions={dispatchMergeActions} /> - { mergeState={mergeState} dispatchMergeActions={dispatchMergeActions} /> - { mergeState={mergeState} dispatchMergeActions={dispatchMergeActions} /> - { mergeState={mergeState} dispatchMergeActions={dispatchMergeActions} /> - @@ -576,7 +588,6 @@ const PersonColumn = ({ dispatchMergeActions, actionButtons }) => { - const DictMergeField = DictionaryField(MergeField) const person = mergeState[align] const idForPerson = label.replace(/\s+/g, "") @@ -675,7 +686,8 @@ const PersonColumn = ({ mergeState={mergeState} dispatchMergeActions={dispatchMergeActions} /> - - - } @@ -767,7 +781,8 @@ const PersonColumn = ({ mergeState={mergeState} dispatchMergeActions={dispatchMergeActions} /> - } @@ -792,7 +807,8 @@ const PersonColumn = ({ mergeState={mergeState} dispatchMergeActions={dispatchMergeActions} /> - - - - - - - - - } diff --git a/client/src/pages/admin/merge/MergePositions.js b/client/src/pages/admin/merge/MergePositions.js index 583cb0061d..ed95c72626 100644 --- a/client/src/pages/admin/merge/MergePositions.js +++ b/client/src/pages/admin/merge/MergePositions.js @@ -7,6 +7,7 @@ import { PositionOverlayRow } from "components/advancedSelectWidget/AdvancedSele import AdvancedSingleSelect from "components/advancedSelectWidget/AdvancedSingleSelect" import AssociatedPositions from "components/AssociatedPositions" import { customFieldsJSONString } from "components/CustomFields" +import DictionaryField from "components/DictionaryField" import EditAssociatedPositions from "components/EditAssociatedPositions" import EditHistory from "components/EditHistory" import LinkTo from "components/LinkTo" @@ -24,7 +25,6 @@ import { useBoilerplate, usePageTitle } from "components/Page" -import DictionaryField from "HOC/DictionaryField" import useMergeObjects, { ALIGN_OPTIONS, areAllSet, @@ -73,7 +73,6 @@ const MergePositions = ({ pageDispatchers }) => { }) usePageTitle("Merge Positions") - const DictMergeField = DictionaryField(MergeField) const position1 = mergeState[MERGE_SIDES.LEFT] const position2 = mergeState[MERGE_SIDES.RIGHT] const mergedPosition = mergeState.merged @@ -138,7 +137,8 @@ const MergePositions = ({ pageDispatchers }) => { )} {areAllSet(position1, position2, mergedPosition) && (
- { mergeState={mergeState} dispatchMergeActions={dispatchMergeActions} /> - { mergeState={mergeState} dispatchMergeActions={dispatchMergeActions} /> - { mergeState={mergeState} dispatchMergeActions={dispatchMergeActions} /> - { mergeState={mergeState} dispatchMergeActions={dispatchMergeActions} /> - { mergeState={mergeState} dispatchMergeActions={dispatchMergeActions} /> - { ) } )} - { - const DictMergeField = DictionaryField(MergeField) const position = mergeState[align] const idForPosition = label.replace(/\s+/g, "") return ( @@ -497,7 +502,8 @@ const PositionColumn = ({ align, label, mergeState, dispatchMergeActions }) => { {areAllSet(position) && (
- { mergeState={mergeState} dispatchMergeActions={dispatchMergeActions} /> - { mergeState={mergeState} dispatchMergeActions={dispatchMergeActions} /> - { mergeState={mergeState} dispatchMergeActions={dispatchMergeActions} /> - { mergeState={mergeState} dispatchMergeActions={dispatchMergeActions} /> - { mergeState={mergeState} dispatchMergeActions={dispatchMergeActions} /> - { ) } )} - } diff --git a/client/src/pages/attachments/Form.js b/client/src/pages/attachments/Form.js index 3755c56df3..4db3a39982 100644 --- a/client/src/pages/attachments/Form.js +++ b/client/src/pages/attachments/Form.js @@ -3,6 +3,7 @@ import API from "api" import AppContext from "components/AppContext" import AttachmentRelatedObjectsTable from "components/Attachment/AttachmentRelatedObjectsTable" import ConfirmDestructive from "components/ConfirmDestructive" +import DictionaryField from "components/DictionaryField" import * as FieldHelper from "components/FieldHelper" import Fieldset from "components/Fieldset" import LinkTo from "components/LinkTo" @@ -11,7 +12,6 @@ import NavigationWarning from "components/NavigationWarning" import { jumpToTop } from "components/Page" import RichTextEditor from "components/RichTextEditor" import { FastField, Field, Form, Formik } from "formik" -import DictionaryField from "HOC/DictionaryField" import _isEqual from "lodash/isEqual" import { Attachment } from "models" import PropTypes from "prop-types" @@ -50,7 +50,6 @@ const AttachmentForm = ({ edit, title, initialValues }) => { value: key, label: classifications[key] })) - const DictFastField = DictionaryField(FastField) return ( { /> - - { /> {canEdit ? ( - { setFieldValue("classification", value)} /> ) : ( - { /> )} - { } const attachment = new Attachment(data ? data.attachment : {}) - const DictField = DictionaryField(Field) const stateSuccess = routerLocation.state && routerLocation.state.success const stateError = routerLocation.state && routerLocation.state.error @@ -195,7 +194,8 @@ const AttachmentShow = ({ pageDispatchers }) => { /> - { attachment.contentLength )} /> - { /> } /> - { } } - const DictFastField = DictionaryField(FastField) - return ( {
- { } /> - { setFieldTouched={setFieldTouched} /> - { onChange={value => setFieldValue("status", value)} /> - { const location = new Location(data ? data.location : {}) const canEdit = currentUser.isSuperuser() const attachmentsEnabled = !Settings.fields.attachment.featureDisabled - const DictField = DictionaryField(Field) return ( @@ -144,13 +143,15 @@ const LocationShow = ({ pageDispatchers }) => { action={action} />
- - { displayType={GEO_LOCATION_DISPLAY_TYPE.FORM_FIELD} /> - { /> {values.description && ( - { status: Person.humanNameOfStatus(person.status) } return person.getNormalFieldsOrdered().reduce((accum, key) => { - const DictField = DictionaryField(Field) accum[key] = ( - { } ] - const DictField = DictionaryField(Field) - const DictFastField = DictionaryField(FastField) - return ( {
{!canAdministrateOrg ? ( <> - - - - { ) } /> - - { ) } /> - - { ) : ( <> - - - { onChange={value => setFieldValue("type", value)} disabled={!isAdmin} /> - { /> } /> - - { /> } /> - setFieldValue("status", value)} /> - { ) } const organization = new Organization(data ? data.organization : {}) - const DictField = DictionaryField(Field) const canAdministrateOrg = currentUser && @@ -360,13 +359,15 @@ const OrganizationShow = ({ pageDispatchers }) => { action={action} />
- - { /> {organization.parentOrg && organization.parentOrg.uuid && ( - { {organization.childrenOrgs && organization.childrenOrgs.length > 0 && ( - { ) )} - {organization.location && ( - { /> )} - - { role: Person.humanNameOfRole(person.role), status: Person.humanNameOfStatus(person.status) } - const DictField = DictionaryField(Field) return person.getNormalFieldsOrdered().reduce((accum, key) => { accum[key] = ( - - , - {isAdmin && ( - ) : ( - )} - + )}
- - - } /> - } /> - } /> - - )} - - + { status: Person.humanNameOfStatus(person.status) } return person.getNormalFieldsOrdered().reduce((accum, key) => { - const DictField = DictionaryField(Field) accum[key] = ( - { } ]) - const DictField = DictionaryField(Field) - const DictFastField = DictionaryField(FastField) - // For advisor types of positions, add permissions property. // The permissions property allows selecting a // specific advisor type and is removed in the onSubmit method. @@ -207,7 +204,8 @@ const PositionForm = ({ edit, title, initialValues, notesComponent }) => {
- { /> {edit ? ( - ) : ( - { /> )} - { } /> - { } /> - - { )} - + - { } const position = new Position(data ? data.position : {}) - const DictField = DictionaryField(Field) const isPrincipal = position.type === Position.TYPE.PRINCIPAL const isSuperuser = position.type === Position.TYPE.SUPERUSER @@ -189,7 +188,8 @@ const PositionShow = ({ pageDispatchers }) => { action={action} />
- { /> {position.organization && ( - { /> )} - { } /> - - - { ) } - const DictCompactRow = DictionaryField(CompactRow) - // Get initial tasks/attendees instant assessments values report = Object.assign(report, report.getTasksEngagementAssessments()) report = Object.assign(report, report.getAttendeesEngagementAssessments()) @@ -326,31 +324,36 @@ const CompactReportView = ({ pageDispatchers }) => { label={getReportSubTitle()} className="reportField" /> - - {!report.cancelled && ( <> - - )} - { className="reportField" /> {report.cancelled && ( - { /> )} {report.reportText && ( - diff --git a/client/src/pages/reports/Form.js b/client/src/pages/reports/Form.js index 9714b324bd..77298b612d 100644 --- a/client/src/pages/reports/Form.js +++ b/client/src/pages/reports/Form.js @@ -19,6 +19,7 @@ import { CustomFieldsContainer, customFieldsJSONString } from "components/CustomFields" +import DictionaryField from "components/DictionaryField" import * as FieldHelper from "components/FieldHelper" import Fieldset from "components/Fieldset" import Messages from "components/Messages" @@ -37,7 +38,6 @@ import { import { EXCLUDED_ASSESSMENT_FIELDS } from "components/RelatedObjectNotes" import RichTextEditor from "components/RichTextEditor" import { FastField, Field, Form, Formik } from "formik" -import DictionaryField from "HOC/DictionaryField" import _cloneDeep from "lodash/cloneDeep" import _debounce from "lodash/debounce" import _isEmpty from "lodash/isEmpty" @@ -265,9 +265,6 @@ const ReportForm = ({ } } - const DictField = DictionaryField(Field) - const DictFastField = DictionaryField(FastField) - const isAuthor = initialValues.reportPeople?.some( a => a.author && Person.isEqual(currentUser, a) ) @@ -479,7 +476,8 @@ const ReportForm = ({
- - )} - + {Settings.engagementsIncludeTimeAndDuration && ( - )} - {!isFutureEngagement && ( - )} {!isFutureEngagement && values.cancelled && ( - { @@ -810,7 +813,8 @@ const ReportForm = ({
{!isFutureEngagement && !values.cancelled && ( <> - - )} - { Person.isEqual(currentUser, rp) ) const tasksLabel = pluralize(Settings.fields.task.subLevel.shortLabel) - const DictField = DictionaryField(Field) // User can approve when admin, // or if report is pending approval and user is one of the approvers in the current approval step @@ -560,19 +559,22 @@ const ReportShow = ({ setSearchQuery, pageDispatchers }) => { component={FieldHelper.SpecialField} widget={
- - - { } /> - { /> {Settings.engagementsIncludeTimeAndDuration && ( - { } /> - { /> {report.cancelled && ( - { {!report.cancelled && ( <> - - { } ] - const DictField = DictionaryField(Field) - const DictFastField = DictionaryField(FastField) - const taskedOrganizationsFilters = { allAdvisorOrganizations: { label: "All advisor organizations", @@ -165,20 +162,23 @@ const TaskForm = ({ edit, title, initialValues, notesComponent }) => {
- - - { /> {Settings.fields.task.parentTask && ( - { /> )} - { disabled={disabled} /> - { /> {disabled ? ( - ) : ( - { /> )} - {
- { : task.descendantTasks?.map(task => new Task(task)) const fieldSettings = task.fieldSettings() - const DictField = DictionaryField(Field) // Admins can edit tasks or users in positions related to the task const isAdmin = currentUser && currentUser.isAdmin() @@ -263,12 +262,14 @@ const TaskShow = ({ pageDispatchers }) => { }} >
- - { } /> {Settings.fields.task.parentTask && task.parentTask?.uuid && ( - { )} {Settings.fields.task.childrenTasks && task.childrenTasks?.length > 0 && ( - { /> )} {Settings.fields.task.plannedCompletion && ( - { /> )} {Settings.fields.task.projectedCompletion && ( - { } /> )} - - Date: Mon, 5 Feb 2024 09:48:37 +0100 Subject: [PATCH 7/7] Rename report save button to "Save Report" Also fix some typos in the HopscotchTour. --- client/src/pages/HopscotchTour.js | 6 +++--- client/src/pages/reports/Form.js | 4 +--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/client/src/pages/HopscotchTour.js b/client/src/pages/HopscotchTour.js index 7532dcfcf2..0a0180865a 100644 --- a/client/src/pages/HopscotchTour.js +++ b/client/src/pages/HopscotchTour.js @@ -212,7 +212,7 @@ const reportTour = (currentUser, navigate) => { placement: "right" }, { - title: "Preview and submit", + title: "Save Report", content: "Pressing this button will save the report as a draft and take you to the preview page. You will have a chance to review your report before you send it for approval and then to the SFAC.", target: "#formBottomSubmit", @@ -280,7 +280,7 @@ const orgTour = (currentUser, navigate) => { placement: "top" }, { - title: "Your orginization's reports", + title: "Your organization's reports", content: "Here, you'll find the complete list of all reports authored by your members of your organization.", target: "#reports h4", @@ -334,7 +334,7 @@ const positionTour = (currentUser, navigate) => { }, { title: `Assigned ${principalSingular} or ${advisorSingular}`, - content: `If you're looking at a ${advisorPositionSingular} position, you'll see the people this position is responisble for advising. If you're looking at a ${principalPositionSingular} position, you'll see the ${advisorPlural} advising that ${principalPositionSingular} here. You can update this information by clicking the "Change assigned ${advisorSingular}" or "Change assigned ${principalSingular}" button, depending on what type of position you're looking at.`, + content: `If you're looking at a ${advisorPositionSingular} position, you'll see the people this position is responsible for advising. If you're looking at a ${principalPositionSingular} position, you'll see the ${advisorPlural} advising that ${principalPositionSingular} here. You can update this information by clicking the "Change assigned ${advisorSingular}" or "Change assigned ${principalSingular}" button, depending on what type of position you're looking at.`, target: "#assigned-principal h4", placement: "top" }, diff --git a/client/src/pages/reports/Form.js b/client/src/pages/reports/Form.js index 77298b612d..c3b1af4944 100644 --- a/client/src/pages/reports/Form.js +++ b/client/src/pages/reports/Form.js @@ -239,9 +239,7 @@ const ReportForm = ({ if (done) { return result } - const submitText = currentUser.hasActivePosition() - ? "Preview and submit" - : "Save draft" + const submitText = "Save Report" const tasksLabel = pluralize(Settings.fields.task.subLevel.shortLabel) const showAssignedPositionWarning = !currentUser.hasAssignedPosition() const showActivePositionWarning =