diff --git a/CHANGELOG.MD b/CHANGELOG.MD index c3c3042e8..c9f262219 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -1,3 +1,7 @@ +## August 21, 2024 + +- **Feature** Reusable widget component [🎟️ DESENG-675](https://citz-gdx.atlassian.net/browse/DESENG-675) + ## August 15, 2024 - **Feature** Add engagement configuration summary [🎟️ DESENG-667](https://citz-gdx.atlassian.net/browse/DESENG-667) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 74f18a5eb..d475f89cb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -95,3 +95,4 @@ Examples of when to Request Changes - `StatusIcon`: A simple component that displays a status icon based on the status string passed to it. - `FormStep`: A wrapper around a form component that accepts a completion criteria and displays the user's progress. Accepts a `step` prop that is a number (from 1 to 9) that represents the current step in the form. This will be rendered as an icon with a checkmark if the step is complete, and a number if it's the current step or if it's incomplete. - `SystemMessage`: An informational message that can be displayed to the user. Accepts a `type` prop that can be "error", "warning", "info", or "success", which affects the display of the message. + - `WidgetPicker`: A modular widget picker component that can be placed anywhere in the engagement editing area. In order to align widgets in the backend with the frontend, a "location" prop is required. Add new locations to the `WidgetLocation` enum. diff --git a/met-api/migrations/versions/c2a384ddfe6a_add_widget_location.py b/met-api/migrations/versions/c2a384ddfe6a_add_widget_location.py new file mode 100644 index 000000000..4cc74eb39 --- /dev/null +++ b/met-api/migrations/versions/c2a384ddfe6a_add_widget_location.py @@ -0,0 +1,24 @@ +"""Add locations to widgets + +Revision ID: c2a384ddfe6a +Revises: 901a6724bca2 +Create Date: 2024-08-21 16:04:25.726651 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'c2a384ddfe6a' +down_revision = '901a6724bca2' +branch_labels = None +depends_on = None + + +def upgrade(): + op.add_column('widget', sa.Column('location', sa.Integer(), nullable=True)) + + +def downgrade(): + op.drop_column('widget', 'location') diff --git a/met-api/src/met_api/models/widget.py b/met-api/src/met_api/models/widget.py index 9c55a0e63..7acd7edab 100644 --- a/met-api/src/met_api/models/widget.py +++ b/met-api/src/met_api/models/widget.py @@ -29,6 +29,7 @@ class Widget(BaseModel): # pylint: disable=too-few-public-methods title = db.Column(db.String(100), comment='Custom title for the widget.') items = db.relationship('WidgetItem', backref='widget', cascade='all, delete', order_by='WidgetItem.sort_index') sort_index = db.Column(db.Integer, nullable=False, default=1) + location = db.Column(db.Integer, nullable=False) @classmethod def get_widget_by_id(cls, widget_id): @@ -67,6 +68,7 @@ def __create_new_widget_entity(widget): created_by=widget.get('created_by', None), updated_by=widget.get('updated_by', None), title=widget.get('title', None), + location=widget.get('location', None), ) @classmethod diff --git a/met-api/src/met_api/schemas/widget.py b/met-api/src/met_api/schemas/widget.py index c2aec64d7..4c736d784 100644 --- a/met-api/src/met_api/schemas/widget.py +++ b/met-api/src/met_api/schemas/widget.py @@ -23,3 +23,4 @@ class Meta: # pylint: disable=too-few-public-methods updated_date = fields.Str(data_key='updated_date') sort_index = fields.Int(data_key='sort_index') items = fields.List(fields.Nested(WidgetItemSchema)) + location = fields.Int(data_key='location') diff --git a/met-web/src/components/engagement/admin/create/widgets/WidgetPickerButton.tsx b/met-web/src/components/engagement/admin/create/widgets/WidgetPickerButton.tsx new file mode 100644 index 000000000..b1c3e71ac --- /dev/null +++ b/met-web/src/components/engagement/admin/create/widgets/WidgetPickerButton.tsx @@ -0,0 +1,83 @@ +import React, { useContext, useEffect } from 'react'; +import { WidgetDrawerContext } from 'components/engagement/form/EngagementWidgets/WidgetDrawerContext'; +import { Grid, Skeleton } from '@mui/material'; +import { If, Else, Then } from 'react-if'; +import { useAppDispatch } from 'hooks'; +import { colors } from 'styles/Theme'; +import { WidgetCardSwitch } from 'components/engagement/form/EngagementWidgets/WidgetCardSwitch'; +import { openNotificationModal } from 'services/notificationModalService/notificationModalSlice'; +import { WidgetLocation } from 'models/widget'; + +export const WidgetPickerButton = ({ location }: { location: WidgetLocation }) => { + const { widgets, deleteWidget, handleWidgetDrawerOpen, isWidgetsLoading, setWidgetLocation } = + useContext(WidgetDrawerContext); + const dispatch = useAppDispatch(); + + useEffect(() => { + setWidgetLocation(location); + return () => setWidgetLocation(0); + }, []); + + const removeWidget = (widgetId: number) => { + dispatch( + openNotificationModal({ + open: true, + data: { + style: 'warning', + header: 'Remove Widget', + subText: [ + { text: 'You will be removing this widget from the engagement.' }, + { text: 'Do you want to remove this widget?' }, + ], + handleConfirm: () => { + deleteWidget(widgetId); + }, + }, + type: 'confirm', + }), + ); + }; + + return ( + + + + + + + + + + {/* Only ever render the first selected widget. This may change in the future. */} + {widgets.length > 0 ? ( + + ) : ( + + )} + + + + + ); +}; diff --git a/met-web/src/components/engagement/admin/create/widgets/index.tsx b/met-web/src/components/engagement/admin/create/widgets/index.tsx new file mode 100644 index 000000000..b498882b5 --- /dev/null +++ b/met-web/src/components/engagement/admin/create/widgets/index.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import WidgetDrawer from 'components/engagement/form/EngagementWidgets/WidgetDrawer'; +import { WidgetDrawerProvider } from 'components/engagement/form/EngagementWidgets/WidgetDrawerContext'; +import { WidgetPickerButton } from './WidgetPickerButton'; +import { WidgetLocation } from 'models/widget'; +import { ActionProvider } from 'components/engagement/form/ActionContext'; + +export const WidgetPicker = ({ location }: { location: WidgetLocation }) => { + return ( + + + + + + + ); +}; + +export default WidgetPicker; diff --git a/met-web/src/components/engagement/form/EngagementWidgets/Documents/AddFileDrawer.tsx b/met-web/src/components/engagement/form/EngagementWidgets/Documents/AddFileDrawer.tsx index 4e1a17659..553175ab1 100644 --- a/met-web/src/components/engagement/form/EngagementWidgets/Documents/AddFileDrawer.tsx +++ b/met-web/src/components/engagement/form/EngagementWidgets/Documents/AddFileDrawer.tsx @@ -15,6 +15,7 @@ import ControlledSelect from 'components/common/ControlledInputComponents/Contro import { postDocument, patchDocument, PatchDocumentRequest } from 'services/widgetService/DocumentService'; import { DOCUMENT_TYPE, DocumentItem } from 'models/document'; import { updatedDiff } from 'deep-object-diff'; +import { WidgetLocation } from 'models/widget'; const schema = yup .object({ @@ -91,6 +92,7 @@ const AddFileDrawer = () => { url: data.link, widget_id: widget.id, type: 'file', + location: widget.location in WidgetLocation ? widget.location : null, }); dispatch( openNotification({ diff --git a/met-web/src/components/engagement/form/EngagementWidgets/Documents/CreateFolderForm.tsx b/met-web/src/components/engagement/form/EngagementWidgets/Documents/CreateFolderForm.tsx index c5b8fcf7f..67d3e367c 100644 --- a/met-web/src/components/engagement/form/EngagementWidgets/Documents/CreateFolderForm.tsx +++ b/met-web/src/components/engagement/form/EngagementWidgets/Documents/CreateFolderForm.tsx @@ -7,7 +7,7 @@ import { useAppDispatch } from 'hooks'; import { openNotification } from 'services/notificationService/notificationSlice'; import { postDocument } from 'services/widgetService/DocumentService'; import { WidgetDrawerContext } from '../WidgetDrawerContext'; -import { WidgetType } from 'models/widget'; +import { WidgetType, WidgetLocation } from 'models/widget'; import { DOCUMENT_TYPE } from 'models/document'; const CreateFolderForm = () => { @@ -48,6 +48,7 @@ const CreateFolderForm = () => { title: folderName, widget_id: widget.id, type: DOCUMENT_TYPE.FOLDER, + location: widget.location in WidgetLocation ? widget.location : null, }); await loadDocuments(); setCreatingFolder(false); diff --git a/met-web/src/components/engagement/form/EngagementWidgets/Documents/UploadFileDrawer.tsx b/met-web/src/components/engagement/form/EngagementWidgets/Documents/UploadFileDrawer.tsx index 7ef37620c..31cf49531 100644 --- a/met-web/src/components/engagement/form/EngagementWidgets/Documents/UploadFileDrawer.tsx +++ b/met-web/src/components/engagement/form/EngagementWidgets/Documents/UploadFileDrawer.tsx @@ -24,6 +24,7 @@ import { DOCUMENT_TYPE, DocumentItem } from 'models/document'; import { saveObject } from 'services/objectStorageService'; import FileUpload from 'components/common/FileUpload'; import { If, Then, Else } from 'react-if'; +import { WidgetLocation } from 'models/widget'; const schema = yup .object({ @@ -94,6 +95,7 @@ const UploadFileDrawer = () => { widget_id: widget.id, type: 'file', is_uploaded: true, + location: widget.location in WidgetLocation ? widget.location : null, }); dispatch( openNotification({ diff --git a/met-web/src/components/engagement/form/EngagementWidgets/Events/InPersonEventFormDrawer.tsx b/met-web/src/components/engagement/form/EngagementWidgets/Events/InPersonEventFormDrawer.tsx index 9cace4de2..9a99d10e4 100644 --- a/met-web/src/components/engagement/form/EngagementWidgets/Events/InPersonEventFormDrawer.tsx +++ b/met-web/src/components/engagement/form/EngagementWidgets/Events/InPersonEventFormDrawer.tsx @@ -18,6 +18,7 @@ import { formEventDates } from './utils'; import dayjs from 'dayjs'; import tz from 'dayjs/plugin/timezone'; import { updatedDiff } from 'deep-object-diff'; +import { WidgetLocation } from 'models/widget'; dayjs.extend(tz); @@ -113,6 +114,7 @@ const InPersonEventFormDrawer = () => { end_date: formatToUTC(dateTo), }, ], + location: widget.location in WidgetLocation ? widget.location : null, }); setEvents((prevWidgetEvents: Event[]) => [...prevWidgetEvents, createdWidgetEvent]); diff --git a/met-web/src/components/engagement/form/EngagementWidgets/Events/VirtualSessionFormDrawer.tsx b/met-web/src/components/engagement/form/EngagementWidgets/Events/VirtualSessionFormDrawer.tsx index 4fb2ea086..9f7a41a0b 100644 --- a/met-web/src/components/engagement/form/EngagementWidgets/Events/VirtualSessionFormDrawer.tsx +++ b/met-web/src/components/engagement/form/EngagementWidgets/Events/VirtualSessionFormDrawer.tsx @@ -17,6 +17,7 @@ import { formatToUTC, formatDate } from 'components/common/dateHelper'; import { formEventDates } from './utils'; import dayjs from 'dayjs'; import tz from 'dayjs/plugin/timezone'; +import { WidgetLocation } from 'models/widget'; dayjs.extend(tz); @@ -108,6 +109,7 @@ const VirtualSessionFormDrawer = () => { end_date: formatToUTC(dateTo), }, ], + location: widget.location in WidgetLocation ? widget.location : null, }); setEvents((prevWidgetEvents: Event[]) => [...prevWidgetEvents, createdWidgetEvent]); diff --git a/met-web/src/components/engagement/form/EngagementWidgets/Map/Form.tsx b/met-web/src/components/engagement/form/EngagementWidgets/Map/Form.tsx index 93959318a..eff6221ce 100644 --- a/met-web/src/components/engagement/form/EngagementWidgets/Map/Form.tsx +++ b/met-web/src/components/engagement/form/EngagementWidgets/Map/Form.tsx @@ -27,6 +27,7 @@ import { faCircleXmark } from '@fortawesome/pro-regular-svg-icons/faCircleXmark' import { When } from 'react-if'; import * as turf from '@turf/turf'; import { WidgetTitle } from '../WidgetTitle'; +import { WidgetLocation } from 'models/widget'; const schema = yup .object({ @@ -98,6 +99,7 @@ const Form = () => { longitude: longitude, latitude: latitude, file: shapefile, + location: widget.location in WidgetLocation ? widget.location : null, }); dispatch(openNotification({ severity: 'success', text: 'A new map was successfully added' })); }; diff --git a/met-web/src/components/engagement/form/EngagementWidgets/Poll/Form.tsx b/met-web/src/components/engagement/form/EngagementWidgets/Poll/Form.tsx index b9d32d116..438ec1070 100644 --- a/met-web/src/components/engagement/form/EngagementWidgets/Poll/Form.tsx +++ b/met-web/src/components/engagement/form/EngagementWidgets/Poll/Form.tsx @@ -16,6 +16,7 @@ import { PollStatus } from 'constants/engagementStatus'; import Alert from '@mui/material/Alert'; import usePollWidgetState from './PollWidget.hook'; import PollAnswerForm from './PollAnswerForm'; +import { WidgetLocation } from 'models/widget'; interface DetailsForm { title: string; @@ -79,6 +80,7 @@ const Form = () => { description: description, answers: answers, status: status, + location: widget.location in WidgetLocation ? widget.location : null, }); dispatch(openNotification({ severity: 'success', text: 'A new Poll was successfully added' })); }; diff --git a/met-web/src/components/engagement/form/EngagementWidgets/Timeline/Form.tsx b/met-web/src/components/engagement/form/EngagementWidgets/Timeline/Form.tsx index fd098fca0..5aacb1155 100644 --- a/met-web/src/components/engagement/form/EngagementWidgets/Timeline/Form.tsx +++ b/met-web/src/components/engagement/form/EngagementWidgets/Timeline/Form.tsx @@ -10,6 +10,7 @@ import { TimelineContext } from './TimelineContext'; import { patchTimeline, postTimeline } from 'services/widgetService/TimelineService'; import { WidgetTitle } from '../WidgetTitle'; import { TimelineEvent } from 'models/timelineWidget'; +import { WidgetLocation } from 'models/widget'; interface DetailsForm { title: string; @@ -81,6 +82,7 @@ const Form = () => { title: title, description: description, events: events, + location: widget.location in WidgetLocation ? widget.location : null, }); dispatch(openNotification({ severity: 'success', text: 'A new timeline was successfully added' })); }; diff --git a/met-web/src/components/engagement/form/EngagementWidgets/Video/Form.tsx b/met-web/src/components/engagement/form/EngagementWidgets/Video/Form.tsx index e3df41268..20721b408 100644 --- a/met-web/src/components/engagement/form/EngagementWidgets/Video/Form.tsx +++ b/met-web/src/components/engagement/form/EngagementWidgets/Video/Form.tsx @@ -13,6 +13,7 @@ import { VideoContext } from './VideoContext'; import { patchVideo, postVideo } from 'services/widgetService/VideoService'; import { updatedDiff } from 'deep-object-diff'; import { WidgetTitle } from '../WidgetTitle'; +import { WidgetLocation } from 'models/widget'; const schema = yup .object({ @@ -61,6 +62,7 @@ const Form = () => { engagement_id: widget.engagement_id, video_url: videoUrl, description: description, + location: widget.location in WidgetLocation ? widget.location : null, }); dispatch(openNotification({ severity: 'success', text: 'A new video was successfully added' })); }; diff --git a/met-web/src/components/engagement/form/EngagementWidgets/WhoIsListening/WhoIsListeningForm.tsx b/met-web/src/components/engagement/form/EngagementWidgets/WhoIsListening/WhoIsListeningForm.tsx index 47f0269d3..3847d35b3 100644 --- a/met-web/src/components/engagement/form/EngagementWidgets/WhoIsListening/WhoIsListeningForm.tsx +++ b/met-web/src/components/engagement/form/EngagementWidgets/WhoIsListening/WhoIsListeningForm.tsx @@ -19,8 +19,8 @@ const WhoIsListeningForm = () => { const [selectedContact, setSelectedContact] = useState(null); const [savingWidgetItems, setSavingWidgetItems] = useState(false); const [createWidgetItems] = useCreateWidgetItemsMutation(); - const widget = widgets.filter((widget) => widget.widget_type_id === WidgetType.WhoIsListening)[0] || null; + useEffect(() => { const savedContacts = widget.items .map((widget_item) => { diff --git a/met-web/src/components/engagement/form/EngagementWidgets/WhoIsListening/WhoIsListeningOptionCard.tsx b/met-web/src/components/engagement/form/EngagementWidgets/WhoIsListening/WhoIsListeningOptionCard.tsx index 99c7fd47e..293652231 100644 --- a/met-web/src/components/engagement/form/EngagementWidgets/WhoIsListening/WhoIsListeningOptionCard.tsx +++ b/met-web/src/components/engagement/form/EngagementWidgets/WhoIsListening/WhoIsListeningOptionCard.tsx @@ -6,7 +6,7 @@ import { WidgetTabValues } from '../type'; import { ActionContext } from '../../ActionContext'; import { openNotification } from 'services/notificationService/notificationSlice'; import { useAppDispatch } from 'hooks'; -import { WidgetType } from 'models/widget'; +import { WidgetType, WidgetLocation } from 'models/widget'; import { Else, If, Then } from 'react-if'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faUserGroupSimple } from '@fortawesome/pro-regular-svg-icons/faUserGroupSimple'; @@ -16,7 +16,7 @@ import { optionCardStyle } from '../constants'; const Title = 'Who is Listening'; const WhoIsListeningOptionCard = () => { const { savedEngagement } = useContext(ActionContext); - const { widgets, loadWidgets, handleWidgetDrawerTabValueChange } = useContext(WidgetDrawerContext); + const { widgets, loadWidgets, handleWidgetDrawerTabValueChange, widgetLocation } = useContext(WidgetDrawerContext); const dispatch = useAppDispatch(); const [createWidget] = useCreateWidgetMutation(); const [isCreatingWidget, setIsCreatingWidget] = useState(false); @@ -34,6 +34,7 @@ const WhoIsListeningOptionCard = () => { widget_type_id: WidgetType.WhoIsListening, engagement_id: savedEngagement.id, title: Title, + location: widgetLocation in WidgetLocation ? widgetLocation : 0, }); await loadWidgets(); dispatch( diff --git a/met-web/src/components/engagement/form/EngagementWidgets/WidgetCardSwitch.tsx b/met-web/src/components/engagement/form/EngagementWidgets/WidgetCardSwitch.tsx index 4a4472a44..5ebb203f3 100644 --- a/met-web/src/components/engagement/form/EngagementWidgets/WidgetCardSwitch.tsx +++ b/met-web/src/components/engagement/form/EngagementWidgets/WidgetCardSwitch.tsx @@ -6,10 +6,11 @@ import { WidgetDrawerContext } from './WidgetDrawerContext'; import { WidgetTabValues } from './type'; interface WidgetCardSwitchProps { + singleSelection?: boolean; widget: Widget; removeWidget: (widgetId: number) => void; } -export const WidgetCardSwitch = ({ widget, removeWidget }: WidgetCardSwitchProps) => { +export const WidgetCardSwitch = ({ singleSelection = false, widget, removeWidget }: WidgetCardSwitchProps) => { const { handleWidgetDrawerOpen, handleWidgetDrawerTabValueChange } = useContext(WidgetDrawerContext); return ( @@ -17,6 +18,7 @@ export const WidgetCardSwitch = ({ widget, removeWidget }: WidgetCardSwitchProps { @@ -30,6 +32,7 @@ export const WidgetCardSwitch = ({ widget, removeWidget }: WidgetCardSwitchProps { @@ -43,6 +46,7 @@ export const WidgetCardSwitch = ({ widget, removeWidget }: WidgetCardSwitchProps { @@ -56,6 +60,7 @@ export const WidgetCardSwitch = ({ widget, removeWidget }: WidgetCardSwitchProps { @@ -69,6 +74,7 @@ export const WidgetCardSwitch = ({ widget, removeWidget }: WidgetCardSwitchProps { @@ -82,6 +88,7 @@ export const WidgetCardSwitch = ({ widget, removeWidget }: WidgetCardSwitchProps { @@ -95,6 +102,7 @@ export const WidgetCardSwitch = ({ widget, removeWidget }: WidgetCardSwitchProps { @@ -108,6 +116,7 @@ export const WidgetCardSwitch = ({ widget, removeWidget }: WidgetCardSwitchProps { diff --git a/met-web/src/components/engagement/form/EngagementWidgets/WidgetDrawerContext.tsx b/met-web/src/components/engagement/form/EngagementWidgets/WidgetDrawerContext.tsx index 249b5fe28..2d0d53280 100644 --- a/met-web/src/components/engagement/form/EngagementWidgets/WidgetDrawerContext.tsx +++ b/met-web/src/components/engagement/form/EngagementWidgets/WidgetDrawerContext.tsx @@ -18,6 +18,8 @@ export interface WidgetDrawerContextProps { loadWidgets: () => Promise; deleteWidget: (widgetIndex: number) => void; updateWidgetsSorting: (widgets: Widget[]) => void; + widgetLocation: number; + setWidgetLocation: (widgetLocation: number) => void; } export type EngagementParams = { @@ -45,6 +47,10 @@ export const WidgetDrawerContext = createContext({ updateWidgetsSorting: (widgets: Widget[]) => { /* empty default method */ }, + widgetLocation: 0, + setWidgetLocation: (widgetLocation: number) => { + /* empty default method */ + }, }); export const WidgetDrawerProvider = ({ children }: { children: JSX.Element | JSX.Element[] }) => { @@ -56,6 +62,7 @@ export const WidgetDrawerProvider = ({ children }: { children: JSX.Element | JSX const [widgetDrawerTabValue, setWidgetDrawerTabValue] = React.useState(WidgetTabValues.WIDGET_OPTIONS); const [removeWidget] = useDeleteWidgetMutation(); const [sortWidgets] = useSortWidgetsMutation(); + const [widgetLocation, setWidgetLocation] = useState(0); const deleteWidget = async (widgetId: number) => { try { @@ -116,6 +123,8 @@ export const WidgetDrawerProvider = ({ children }: { children: JSX.Element | JSX handleWidgetDrawerTabValueChange, isWidgetsLoading, loadWidgets, + widgetLocation, + setWidgetLocation, }} > {children} diff --git a/met-web/src/models/widget.tsx b/met-web/src/models/widget.tsx index 07043b0e3..a0bbff8b1 100644 --- a/met-web/src/models/widget.tsx +++ b/met-web/src/models/widget.tsx @@ -11,6 +11,7 @@ export interface Widget { engagement_id: number; items: WidgetItem[]; title: string; + location: WidgetLocation; } export enum WidgetType { @@ -24,3 +25,7 @@ export enum WidgetType { Timeline = 9, Poll = 10, } + +export enum WidgetLocation { + engagementAuthoring = 1, +} diff --git a/met-web/src/services/widgetService/DocumentService/index.tsx b/met-web/src/services/widgetService/DocumentService/index.tsx index 75e612772..a8dabf74a 100644 --- a/met-web/src/services/widgetService/DocumentService/index.tsx +++ b/met-web/src/services/widgetService/DocumentService/index.tsx @@ -2,6 +2,7 @@ import http from 'apiManager/httpRequestHandler'; import { DocumentItem, DocumentType } from 'models/document'; import Endpoints from 'apiManager/endpoints'; import { replaceAllInURL, replaceUrl } from 'helper'; +import { WidgetLocation } from 'models/widget'; export const fetchDocuments = async (widget_id: number): Promise => { try { @@ -20,6 +21,7 @@ interface PostDocumentRequest { url?: string; type: DocumentType; is_uploaded?: boolean; + location: WidgetLocation | null; } export const postDocument = async (widget_id: number, data: PostDocumentRequest): Promise => { try { diff --git a/met-web/src/services/widgetService/EventService/index.tsx b/met-web/src/services/widgetService/EventService/index.tsx index 4d9f963f2..6744c805f 100644 --- a/met-web/src/services/widgetService/EventService/index.tsx +++ b/met-web/src/services/widgetService/EventService/index.tsx @@ -2,6 +2,7 @@ import http from 'apiManager/httpRequestHandler'; import Endpoints from 'apiManager/endpoints'; import { replaceUrl, replaceAllInURL } from 'helper'; import { Event, EventTypeLabel } from 'models/event'; +import { WidgetLocation } from 'models/widget'; export const getEvents = async (widget_id: number): Promise => { try { @@ -26,6 +27,7 @@ interface PostEventProps { url?: string; url_label?: string; }[]; + location: WidgetLocation | null; } export const postEvent = async (widget_id: number, data: PostEventProps): Promise => { try { diff --git a/met-web/src/services/widgetService/MapService/index.tsx b/met-web/src/services/widgetService/MapService/index.tsx index afd2d1a1f..de1aa1edb 100644 --- a/met-web/src/services/widgetService/MapService/index.tsx +++ b/met-web/src/services/widgetService/MapService/index.tsx @@ -3,6 +3,7 @@ import { WidgetMap } from 'models/widgetMap'; import Endpoints from 'apiManager/endpoints'; import { replaceUrl } from 'helper'; import { GeoJSON } from 'geojson'; +import { WidgetLocation } from 'models/widget'; export const fetchMaps = async (widget_id: number): Promise => { try { @@ -21,6 +22,7 @@ interface PostMapRequest { latitude: number; marker_label?: string; file?: File; + location: WidgetLocation | null; } export const postMap = async (widget_id: number, data: PostMapRequest): Promise => { diff --git a/met-web/src/services/widgetService/PollService/index.tsx b/met-web/src/services/widgetService/PollService/index.tsx index 2cf5ee0ec..eb8f78abb 100644 --- a/met-web/src/services/widgetService/PollService/index.tsx +++ b/met-web/src/services/widgetService/PollService/index.tsx @@ -2,6 +2,7 @@ import http from 'apiManager/httpRequestHandler'; import Endpoints from 'apiManager/endpoints'; import { replaceAllInURL, replaceUrl } from 'helper'; import { PollWidget, PollAnswer, PollResponse, PollResultResponse } from 'models/pollWidget'; +import { WidgetLocation } from 'models/widget'; interface PostPollRequest { widget_id: number; @@ -10,6 +11,7 @@ interface PostPollRequest { description: string; answers: PollAnswer[]; status: string; + location: WidgetLocation | null; } interface PostPollResponse { diff --git a/met-web/src/services/widgetService/TimelineService/index.tsx b/met-web/src/services/widgetService/TimelineService/index.tsx index e90cd0b84..fcf1fc49b 100644 --- a/met-web/src/services/widgetService/TimelineService/index.tsx +++ b/met-web/src/services/widgetService/TimelineService/index.tsx @@ -2,6 +2,7 @@ import http from 'apiManager/httpRequestHandler'; import Endpoints from 'apiManager/endpoints'; import { replaceAllInURL, replaceUrl } from 'helper'; import { TimelineWidget, TimelineEvent } from 'models/timelineWidget'; +import { WidgetLocation } from 'models/widget'; interface PostTimelineRequest { widget_id: number; @@ -9,6 +10,7 @@ interface PostTimelineRequest { title: string; description: string; events: TimelineEvent[]; + location: WidgetLocation | null; } interface PatchTimelineRequest { diff --git a/met-web/src/services/widgetService/VideoService/index.tsx b/met-web/src/services/widgetService/VideoService/index.tsx index 4398527c8..07bfea460 100644 --- a/met-web/src/services/widgetService/VideoService/index.tsx +++ b/met-web/src/services/widgetService/VideoService/index.tsx @@ -2,6 +2,7 @@ import http from 'apiManager/httpRequestHandler'; import Endpoints from 'apiManager/endpoints'; import { replaceAllInURL, replaceUrl } from 'helper'; import { VideoWidget } from 'models/videoWidget'; +import { WidgetLocation } from 'models/widget'; export const fetchVideoWidgets = async (widget_id: number): Promise => { try { @@ -18,6 +19,7 @@ interface PostVideoRequest { engagement_id: number; video_url: string; description: string; + location: WidgetLocation | null; } export const postVideo = async (widget_id: number, data: PostVideoRequest): Promise => { diff --git a/met-web/tests/unit/components/engagement/old-engagement.test.tsx b/met-web/tests/unit/components/engagement/old-engagement.test.tsx index ff12f5048..f390fc3ef 100644 --- a/met-web/tests/unit/components/engagement/old-engagement.test.tsx +++ b/met-web/tests/unit/components/engagement/old-engagement.test.tsx @@ -47,6 +47,7 @@ const whoIsListeningWidget: Widget = { widget_type_id: WidgetType.WhoIsListening, engagement_id: 1, items: [widgetItem], + location: 1, }; const mockLocationData = { state: { open: true }, pathname: '', search: '', hash: '', key: '' }; diff --git a/met-web/tests/unit/components/factory.ts b/met-web/tests/unit/components/factory.ts index 410506f61..de12572ae 100644 --- a/met-web/tests/unit/components/factory.ts +++ b/met-web/tests/unit/components/factory.ts @@ -141,6 +141,7 @@ const eventWidget: Widget = { widget_type_id: WidgetType.Events, engagement_id: 1, items: [eventWidgetItem], + location: 1, }; const mapWidgetItem: WidgetItem = { @@ -156,6 +157,7 @@ const mapWidget: Widget = { widget_type_id: WidgetType.Map, engagement_id: 1, items: [mapWidgetItem], + location: 1, }; const mockMap: WidgetMap = { @@ -182,6 +184,7 @@ const pollWidget: Widget = { widget_type_id: WidgetType.Poll, engagement_id: 1, items: [], + location: 1, }; const videoWidget: Widget = { @@ -190,6 +193,7 @@ const videoWidget: Widget = { widget_type_id: WidgetType.Video, engagement_id: 1, items: [], + location: 1, }; const subscribeWidget: Widget = { @@ -198,6 +202,7 @@ const subscribeWidget: Widget = { widget_type_id: WidgetType.Subscribe, engagement_id: 1, items: [], + location: 1, }; const timeLineWidget: Widget = { @@ -206,6 +211,7 @@ const timeLineWidget: Widget = { widget_type_id: WidgetType.Timeline, engagement_id: 1, items: [], + location: 1, }; const mockPollAnswer1: PollAnswer = { diff --git a/met-web/tests/unit/components/widgets/DocumentWidget.test.tsx b/met-web/tests/unit/components/widgets/DocumentWidget.test.tsx index 3bf6c7ae0..ec85e4e34 100644 --- a/met-web/tests/unit/components/widgets/DocumentWidget.test.tsx +++ b/met-web/tests/unit/components/widgets/DocumentWidget.test.tsx @@ -68,6 +68,7 @@ const documentWidget: Widget = { widget_type_id: WidgetType.Document, engagement_id: 1, items: [], + location: 1, }; jest.mock('axios'); diff --git a/met-web/tests/unit/components/widgets/PollWidgetView.test.tsx b/met-web/tests/unit/components/widgets/PollWidgetView.test.tsx index 8f2f838e0..465582003 100644 --- a/met-web/tests/unit/components/widgets/PollWidgetView.test.tsx +++ b/met-web/tests/unit/components/widgets/PollWidgetView.test.tsx @@ -44,6 +44,7 @@ describe('PollWidgetView Component Tests', () => { widget_type_id: 10, engagement_id: 1, items: [], + location: 1, }; const mockPoll = { diff --git a/met-web/tests/unit/components/widgets/WhoIsListeningWidget.test.tsx b/met-web/tests/unit/components/widgets/WhoIsListeningWidget.test.tsx index 1cdb22e87..7c496b71b 100644 --- a/met-web/tests/unit/components/widgets/WhoIsListeningWidget.test.tsx +++ b/met-web/tests/unit/components/widgets/WhoIsListeningWidget.test.tsx @@ -53,6 +53,7 @@ const whoIsListeningWidget: Widget = { widget_type_id: WidgetType.WhoIsListening, engagement_id: 1, items: [contactWidgetItem], + location: 1, }; const mockEngagementSettings: EngagementSettings = { @@ -226,6 +227,7 @@ describe('Who is Listening widget tests', () => { widget_type_id: WidgetType.WhoIsListening, engagement_id: draftEngagement.id, title: whoIsListeningWidget.title, + location: 0, }); expect(getWidgetsMock).toHaveBeenCalled(); expect(screen.getByText('Add This Contact')).toBeVisible();