\r\n
\r\n
\r\n
\r\n \r\n \r\n {indlaeg.personNavn && (\r\n {`${indlaeg.personNavn} - `} \r\n )}\r\n {name}\r\n \r\n
\r\n
\r\n {formatDateString(indlaeg?.dato)}\r\n \r\n
\r\n \r\n {formatDateString(new Date(indlaeg?.dato).toString(), \"dd-MM-yyyy\")}\r\n {\" \"}\r\n klokken{\" \"}\r\n {formatDateString(new Date(indlaeg?.dato).toString(), \"HH:mm\")}\r\n \r\n
\r\n\r\n
\r\n {indlaeg.geometriId && geometri.drawing && sagsAktType === \"Geometri\" && (\r\n -1}\r\n geometri={geometri}\r\n hideEditOptions={!isMe || hideEdit}\r\n hideDeleteOption={\r\n !isMe ||\r\n hideEdit ||\r\n (isStednavn &&\r\n currentUser.rolleId === RessourceRolleIdEnum.indberetter)\r\n }\r\n hideOptions={hideOptions}\r\n downloadLink={getDownloadGeometryLink(indberetning.id, indlaeg.id)}\r\n setHoveredFeatures={setHoveredFeatures}\r\n zoomToDrawing={() => {\r\n if (map) {\r\n zoomToFeature(map, geometri.drawing);\r\n }\r\n }}\r\n onEditGeometryClick={() => onEditGeometry(currentFeature)}\r\n onEditClick={() => {\r\n setChatState(\"LOADING\");\r\n cancelDrawingAndUploadFile();\r\n showModal({\r\n title: \"Rediger indtegning\",\r\n content: (\r\n ,\r\n featureTypeId: number,\r\n featureType: string,\r\n beskrivelse: string\r\n ) => {\r\n if (fromBehandler) {\r\n redigerSagsakt(\r\n currentUser,\r\n indlaeg.id,\r\n beskrivelse,\r\n \"\"\r\n ).then((e) => {\r\n getIndberetning(\r\n indberetning.id,\r\n currentUser.personId\r\n ).then((nyIndberetning) => {\r\n setIndberetning(nyIndberetning);\r\n setChatState(\"IDLE\");\r\n });\r\n });\r\n } else {\r\n redigerAendringsforslag(\r\n currentUser,\r\n aendringTypeId,\r\n aendringType,\r\n indlaeg.id,\r\n beskrivelse,\r\n featureType,\r\n featureTypeId,\r\n convertFeatureToWkt(drawing),\r\n `Openlayers.Geometry.${drawing\r\n .getGeometry()\r\n .getType()}`,\r\n \"\"\r\n ).then((e) => {\r\n getIndberetning(\r\n indberetning.id,\r\n currentUser.personId\r\n ).then((nyIndberetning) => {\r\n setIndberetning(nyIndberetning);\r\n setChatState(\"IDLE\");\r\n });\r\n });\r\n }\r\n }}\r\n objektTyper={objektTyper}\r\n ændringsTyper={ændringsTyper}\r\n />\r\n ),\r\n closeModalCallback: () => {\r\n setChatState(\"IDLE\");\r\n },\r\n });\r\n }}\r\n onDeleteClick={() => {\r\n cancelDrawingAndUploadFile();\r\n showModal({\r\n title: \"Slet opdatering\",\r\n content: (\r\n {\r\n setChatState(\"LOADING\");\r\n if (fromBehandler) {\r\n deleteSagsakt(currentUser, indlaeg.id).then(() => {\r\n getIndberetning(\r\n indberetning.id,\r\n currentUser.personId\r\n ).then((nyIndberetning) => {\r\n setIndberetning(nyIndberetning);\r\n setChatState(\"IDLE\");\r\n });\r\n });\r\n } else {\r\n deleteAendringsforslag(currentUser, indlaeg.id).then(\r\n () => {\r\n getIndberetning(\r\n indberetning.id,\r\n currentUser.personId\r\n ).then((nyIndberetning) => {\r\n setIndberetning(nyIndberetning);\r\n setChatState(\"IDLE\");\r\n });\r\n }\r\n );\r\n }\r\n }}\r\n closeModal={closeModal}\r\n />\r\n ),\r\n });\r\n }}\r\n />\r\n )}\r\n {indlaeg.filId !== undefined &&\r\n geometri.drawing &&\r\n sagsAktType === \"Fil\" && (\r\n {\r\n if (map) {\r\n zoomToFeature(map, currentFeature);\r\n }\r\n }}\r\n onMouseEnter={() => {\r\n if (indlaeg.id) {\r\n setHoveredFeatures([indlaeg.id]);\r\n }\r\n }}\r\n onMouseLeave={() => {\r\n setHoveredFeatures([]);\r\n }}\r\n removeFil={() => {\r\n setChatState(\"LOADING\");\r\n deleteSagsakt(currentUser, indlaeg.id).then(() => {\r\n getIndberetning(indberetning.id, currentUser.personId).then(\r\n (nyIndberetning) => {\r\n setIndberetning(nyIndberetning);\r\n setChatState(\"IDLE\");\r\n }\r\n );\r\n });\r\n }}\r\n onEditGeometryClick={() => onEditGeometry(currentFeature)}\r\n onEditClick={() => {\r\n console.log(\"not implemented\");\r\n }}\r\n showModal={showModal}\r\n closeModal={closeModal}\r\n />\r\n )}\r\n
\r\n
\r\n );\r\n}\r\n","import {\r\n Hoeringsmappe,\r\n Hoeringssag,\r\n Indberetningsmappe,\r\n Indlaeg,\r\n IndlaegTypeIdEnum,\r\n RessourceRolleIdEnum,\r\n Sagsbehandlermappe,\r\n} from \"interfaces/IIndberetning\";\r\nimport Section from \"components/common/Section\";\r\nimport {\r\n Fragment,\r\n useCallback,\r\n useContext,\r\n useEffect,\r\n useLayoutEffect,\r\n useRef,\r\n useState,\r\n} from \"react\";\r\nimport { Bruger } from \"context/AuthProvider\";\r\nimport { ToastContext } from \"context/ToastProvider\";\r\nimport { ModalContext } from \"components/common/Modal/Modal\";\r\nimport SkrivBeskedModal from \"./SkrivBeskedModal\";\r\nimport {\r\n isIndberetningAfsluttet,\r\n isIndberetningMine,\r\n} from \"routes/Fip/FipIndberetning\";\r\nimport { MapContext, setEditFeatureCallback } from \"context/MapProvider\";\r\nimport { finishedDrawingSource, setDrawingCallback } from \"config/interactions\";\r\nimport { convertFeatureToWkt } from \"util/ol\";\r\nimport { Feature } from \"ol\";\r\nimport Geometry from \"ol/geom/Geometry\";\r\nimport PlusCircleFill from \"components/icons/PlusCircleFill\";\r\nimport { AddFileModal } from \"components/common/Indberet/AddFileModal\";\r\nimport AddDrawingModal from \"components/common/Indberet/AddDrawingModal\";\r\nimport FileInput from \"components/common/FormElements/FileInput\";\r\nimport { NewFileState } from \"routes/Fip/FipIndberet\";\r\nimport ChatMessage from \"./ChatMessage\";\r\nimport Sagsagt from \"./Sagsagt\";\r\nimport { SagsbehandlingApi } from \"api/interfaces\";\r\nimport { usePrevious } from \"hooks/usePrevious\";\r\nimport { formatDateString } from \"util/date\";\r\n\r\ninterface ViewElement {\r\n date: number;\r\n component: JSX.Element;\r\n}\r\ninterface IChatProps {\r\n currentUser: Bruger;\r\n indberetning: Hoeringssag;\r\n setIndberetning: Function;\r\n isHoeringssagChat: boolean;\r\n isStednavn: boolean;\r\n newFile: NewFileState;\r\n setNewFile: React.Dispatch
>;\r\n cancelDrawingAndUploadFile: () => void;\r\n scrollPos: number | undefined;\r\n setScrollPos: React.Dispatch>;\r\n sagsbehandlingApi: SagsbehandlingApi;\r\n}\r\n// Chooses what messages to show to who\r\nconst whitelistSagsbehandling = [\r\n IndlaegTypeIdEnum.afslutningsKommentar,\r\n IndlaegTypeIdEnum.fraIndberetter,\r\n IndlaegTypeIdEnum.tilIndberetter,\r\n IndlaegTypeIdEnum.fraSagsbehandler,\r\n IndlaegTypeIdEnum.tilSagsbehandler,\r\n IndlaegTypeIdEnum.intern,\r\n IndlaegTypeIdEnum.overdragelseskommentar,\r\n IndlaegTypeIdEnum.afslutningsKommentar,\r\n];\r\n\r\nconst whitelistHoeringssag = [\r\n IndlaegTypeIdEnum.beskedFraHoeringsAnsvarlig,\r\n IndlaegTypeIdEnum.beskedFraHoeringspart,\r\n IndlaegTypeIdEnum.beskedTiLHoeringsAnsvarlig,\r\n IndlaegTypeIdEnum.beskedTilHoeringspart,\r\n IndlaegTypeIdEnum.overdragelseskommentar,\r\n IndlaegTypeIdEnum.afslutningsKommentar,\r\n];\r\n\r\nconst rolleTypeToIndlaegType = (\r\n rolleId: RessourceRolleIdEnum,\r\n context: \"sagsbehandling\" | \"horingssag\",\r\n isStednavn: boolean\r\n) => {\r\n // #281\r\n if (isStednavn) {\r\n switch (rolleId) {\r\n case RessourceRolleIdEnum.indberetter:\r\n return 3;\r\n case RessourceRolleIdEnum.sagsbehandler:\r\n return 4;\r\n default:\r\n return 4;\r\n }\r\n }\r\n //\r\n if (context === \"sagsbehandling\") {\r\n switch (rolleId) {\r\n case RessourceRolleIdEnum.indberetter:\r\n return IndlaegTypeIdEnum.fraIndberetter;\r\n case RessourceRolleIdEnum.sagsbehandler:\r\n return IndlaegTypeIdEnum.fraSagsbehandler;\r\n default:\r\n return IndlaegTypeIdEnum.fraSagsbehandler;\r\n }\r\n } else if (context === \"horingssag\") {\r\n switch (rolleId) {\r\n case RessourceRolleIdEnum.sagsbehandler:\r\n return IndlaegTypeIdEnum.beskedFraHoeringsAnsvarlig;\r\n case RessourceRolleIdEnum.høringsansvarlig:\r\n return IndlaegTypeIdEnum.beskedFraHoeringsAnsvarlig;\r\n case RessourceRolleIdEnum.høringspart:\r\n return IndlaegTypeIdEnum.beskedFraHoeringspart;\r\n default:\r\n return IndlaegTypeIdEnum.beskedFraHoeringsAnsvarlig;\r\n }\r\n } else {\r\n return IndlaegTypeIdEnum.intern;\r\n }\r\n};\r\n\r\n//TODO: Unhardcode plz\r\nconst ændringsTyper = [\r\n { value: 1, text: \"Mangler i kortet (Ny)\" },\r\n { value: 2, text: \"Har ændret sig (Rettes)\" },\r\n { value: 3, text: \"Er for meget i kortet (Slettes)\" },\r\n];\r\n\r\nexport default function Chat(props: IChatProps) {\r\n const [chatState, setChatState] = useState(\"IDLE\");\r\n const {\r\n currentUser,\r\n indberetning,\r\n setIndberetning,\r\n isHoeringssagChat,\r\n isStednavn,\r\n newFile,\r\n setNewFile,\r\n cancelDrawingAndUploadFile,\r\n scrollPos,\r\n setScrollPos,\r\n sagsbehandlingApi,\r\n } = props;\r\n const {\r\n getIndberetning,\r\n getObjekttyper,\r\n redigerAendringsforslag,\r\n redigerSagsaktGeometri,\r\n skrivChatBesked,\r\n uploadAendringsforslagGeometri,\r\n uploadFile,\r\n uploadSagsaktFil,\r\n uploadSagsaktGeometri,\r\n } = sagsbehandlingApi;\r\n const context = isHoeringssagChat ? \"horingssag\" : \"sagsbehandling\";\r\n\r\n const { showModal } = useContext(ModalContext);\r\n const toast = useContext(ToastContext);\r\n const chatRef = useRef(null);\r\n const bottomOfChat = useRef(null);\r\n const scrollToBottom = () => {\r\n chatRef.current?.scrollTo({ top: bottomOfChat.current?.offsetTop });\r\n };\r\n const { dispatchToMap, mapState } = useContext(MapContext);\r\n const cancelEditGeometry = useCallback(() => {\r\n dispatchToMap({ type: \"CANCEL_EDIT_GEOMETRY\" });\r\n }, [dispatchToMap]);\r\n\r\n const { activeDrawTool, editGeometryState } = mapState;\r\n const [messages, setMessages] = useState();\r\n const [objekttyper, setObjekttyper] = useState<\r\n { value: number; text: string }[]\r\n >([]);\r\n const fileInputRef = useRef(null);\r\n\r\n const addFile = (fileInfo: {\r\n beskrivelse: string;\r\n filId: number;\r\n geometri: Feature;\r\n originalFilNavn: string;\r\n }) => {\r\n setChatState(\"IDLE\");\r\n dispatchToMap({ type: \"SET_DRAWTOOL\", drawTool: undefined });\r\n let mappeid;\r\n\r\n if (!isHoeringssagChat) {\r\n if (currentUser.rolleId === RessourceRolleIdEnum.sagsbehandler) {\r\n mappeid = indberetning.sagsbehandlermappe[0].id;\r\n } else if (currentUser.rolleId === RessourceRolleIdEnum.indberetter) {\r\n mappeid = indberetning.indberetningsmappe[0].id;\r\n } else {\r\n console.error(\r\n \"Non-supported role trying to add a drawing in sagsbehandling!\"\r\n );\r\n }\r\n } else {\r\n if (\r\n currentUser.rolleId === RessourceRolleIdEnum.sagsbehandler &&\r\n indberetning.hoeringsansvarligmappe\r\n ) {\r\n mappeid = indberetning.hoeringsansvarligmappe[0].id;\r\n } else if (\r\n currentUser.rolleId === RessourceRolleIdEnum.høringspart &&\r\n indberetning.hoeringspartmappe\r\n ) {\r\n mappeid = indberetning.hoeringspartmappe[0].id;\r\n } else {\r\n console.error(\r\n \"Non-supported role trying to add a drawing in sagsbehandling!\"\r\n );\r\n }\r\n }\r\n\r\n uploadSagsaktFil(\r\n currentUser,\r\n fileInfo.beskrivelse,\r\n fileInfo.filId,\r\n convertFeatureToWkt(fileInfo.geometri),\r\n fileInfo.originalFilNavn,\r\n fileInfo.geometri.get(\"id\"),\r\n `Openlayers.Geometry.${fileInfo.geometri.getGeometry().getType()}`,\r\n false,\r\n mappeid\r\n ).then(() => {\r\n getIndberetning(indberetning.id, currentUser.personId).then(\r\n (nyIndberetning) => {\r\n setIndberetning(nyIndberetning);\r\n setChatState(\"IDLE\");\r\n }\r\n );\r\n });\r\n };\r\n const addDrawing = useCallback(\r\n (drawingInfo: {\r\n aendringTypeId: number;\r\n aendringType: string;\r\n drawing: Feature;\r\n featureTypeId: number;\r\n featureType: string;\r\n beskrivelse: string;\r\n }) => {\r\n setChatState(\"IDLE\");\r\n dispatchToMap({ type: \"SET_DRAWTOOL\", drawTool: undefined });\r\n let mappeid;\r\n\r\n if (!isHoeringssagChat) {\r\n if (currentUser.rolleId === RessourceRolleIdEnum.sagsbehandler) {\r\n mappeid = indberetning.sagsbehandlermappe[0].id;\r\n } else if (currentUser.rolleId === RessourceRolleIdEnum.indberetter) {\r\n mappeid = indberetning.indberetningsmappe[0].id;\r\n } else {\r\n console.error(\r\n \"Non-supported role trying to add a drawing in sagsbehandling!\"\r\n );\r\n }\r\n } else {\r\n if (\r\n currentUser.rolleId === RessourceRolleIdEnum.sagsbehandler &&\r\n indberetning.hoeringsansvarligmappe\r\n ) {\r\n mappeid = indberetning.hoeringsansvarligmappe[0].id;\r\n } else if (\r\n currentUser.rolleId === RessourceRolleIdEnum.høringspart &&\r\n indberetning.hoeringspartmappe\r\n ) {\r\n mappeid = indberetning.hoeringspartmappe[0].id;\r\n } else {\r\n console.error(\r\n \"Non-supported role trying to add a drawing in sagsbehandling!\"\r\n );\r\n }\r\n }\r\n\r\n if (\r\n currentUser.rolleId === RessourceRolleIdEnum.sagsbehandler &&\r\n !isHoeringssagChat\r\n ) {\r\n uploadSagsaktGeometri(\r\n currentUser,\r\n 0,\r\n drawingInfo.beskrivelse,\r\n drawingInfo.drawing.get(\"id\"),\r\n convertFeatureToWkt(drawingInfo.drawing),\r\n `Openlayers.Geometry.${drawingInfo.drawing.getGeometry().getType()}`,\r\n false,\r\n mappeid\r\n ).then(() => {\r\n getIndberetning(indberetning.id, currentUser.personId).then(\r\n (nyIndberetning) => {\r\n setIndberetning(nyIndberetning);\r\n setChatState(\"IDLE\");\r\n }\r\n );\r\n });\r\n } else {\r\n uploadAendringsforslagGeometri(\r\n currentUser,\r\n drawingInfo.aendringTypeId,\r\n drawingInfo.aendringType,\r\n drawingInfo.beskrivelse,\r\n drawingInfo.featureType,\r\n drawingInfo.featureTypeId,\r\n convertFeatureToWkt(drawingInfo.drawing),\r\n `Openlayers.Geometry.${drawingInfo.drawing.getGeometry().getType()}`,\r\n drawingInfo.drawing.get(\"id\"),\r\n mappeid\r\n ).then(() => {\r\n getIndberetning(indberetning.id, currentUser.personId).then(\r\n (nyIndberetning) => {\r\n setIndberetning(nyIndberetning);\r\n setChatState(\"IDLE\");\r\n }\r\n );\r\n });\r\n }\r\n\r\n //setIndberetning({\r\n // type: \"ADD_DRAWING\",\r\n // drawingInfo,\r\n //});\r\n },\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [dispatchToMap]\r\n );\r\n // TODO: dette er det fuldstændig samme der sker i FipIndberet, så måske det skal laves mere generel (måske ikke)\r\n useEffect(() => {\r\n setDrawingCallback((drawing, isValid) => {\r\n if (!isValid) {\r\n finishedDrawingSource.removeFeature(drawing);\r\n toast({\r\n type: \"danger\",\r\n content: {\r\n header: \"Ugyldig geometri\",\r\n message: `Den angivne geometri er ugyldig, hvilket kan skyldes, at geometrien \"krydser\" sig selv.\\n\\nTegn venligst en ny geometri.`,\r\n },\r\n });\r\n } else {\r\n if (newFile.state === \"UPLOADED\" && newFile.file) {\r\n showModal({\r\n title: \"Beskriv filindhold\",\r\n content: (\r\n ,\r\n originalFilNavn: string\r\n ) => {\r\n addFile({\r\n beskrivelse,\r\n filId,\r\n geometri,\r\n originalFilNavn,\r\n });\r\n dispatchToMap({ type: \"SET_DRAWTOOL\", drawTool: undefined });\r\n }}\r\n />\r\n ),\r\n closeModalCallback: () => {\r\n finishedDrawingSource.removeFeature(drawing);\r\n },\r\n });\r\n } else {\r\n showModal({\r\n title: \"Beskriv indtegning\",\r\n content: (\r\n ,\r\n featureTypeId: number,\r\n featureType: string,\r\n beskrivelse: string\r\n ) => {\r\n addDrawing({\r\n aendringTypeId,\r\n aendringType,\r\n drawing,\r\n featureTypeId,\r\n featureType,\r\n beskrivelse,\r\n });\r\n }}\r\n objektTyper={objekttyper}\r\n ændringsTyper={ændringsTyper}\r\n />\r\n ),\r\n closeModalCallback: () => {\r\n finishedDrawingSource.removeFeature(drawing);\r\n },\r\n });\r\n }\r\n }\r\n });\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [\r\n dispatchToMap,\r\n indberetning,\r\n newFile.file,\r\n newFile.state,\r\n objekttyper,\r\n isHoeringssagChat,\r\n showModal,\r\n addDrawing,\r\n toast,\r\n ]);\r\n\r\n const editFeatureCallback = useCallback((feature: Feature) => {\r\n // Handle errors (toast maybe)\r\n\r\n // find the sagsakt in the correct \"folder\"\r\n if (feature.get(\"type\").toLowerCase() === \"geometri\") {\r\n if (\r\n currentUser.rolleId === RessourceRolleIdEnum.sagsbehandler &&\r\n !isHoeringssagChat\r\n ) {\r\n redigerSagsaktGeometri(\r\n currentUser,\r\n feature.get(\"id\"),\r\n feature.get(\"beskrivelse\"),\r\n convertFeatureToWkt(feature)\r\n ).then(() => {\r\n getIndberetning(indberetning.id, currentUser.personId).then(\r\n (nyIndberetning) => {\r\n setIndberetning(nyIndberetning);\r\n setChatState(\"IDLE\");\r\n }\r\n );\r\n });\r\n } else {\r\n redigerAendringsforslag(\r\n currentUser,\r\n feature.get(\"aendringTypeId\"),\r\n feature.get(\"aendringType\"),\r\n feature.get(\"id\"),\r\n feature.get(\"beskrivelse\"),\r\n feature.get(\"featureType\"),\r\n feature.get(\"featureTypeId\"),\r\n convertFeatureToWkt(feature),\r\n feature.getGeometry().getType(),\r\n `Openlayers.Geometry.${feature.getGeometry().getType()}`\r\n ).then(() => {\r\n getIndberetning(indberetning.id, currentUser.personId).then(\r\n (nyIndberetning) => {\r\n setIndberetning(nyIndberetning);\r\n setChatState(\"IDLE\");\r\n }\r\n );\r\n });\r\n }\r\n } else {\r\n console.error(\"Feature type not recognized\");\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, []);\r\n useEffect(() => {\r\n setEditFeatureCallback(editFeatureCallback);\r\n }, [editFeatureCallback]);\r\n\r\n useEffect(() => {\r\n setMessages(renderMessages(indberetning, currentUser));\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [indberetning, currentUser, objekttyper]);\r\n\r\n useEffect(() => {\r\n if (editGeometryState.active || activeDrawTool) {\r\n setChatState(\"LOADING\");\r\n } else if (!editGeometryState.active && !activeDrawTool) {\r\n setChatState(\"IDLE\");\r\n cancelDrawingAndUploadFile();\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [editGeometryState.active, activeDrawTool]);\r\n\r\n const prevNumMessages = usePrevious(messages)?.length ?? 0;\r\n useLayoutEffect(() => {\r\n const currNumMessages = messages?.length ?? 0;\r\n if (currNumMessages - prevNumMessages === 1 || !scrollPos) {\r\n scrollToBottom();\r\n } else {\r\n chatRef.current?.scrollTo({ top: scrollPos });\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [messages]);\r\n useEffect(() => {\r\n const getObjekttyperForTema = async () => {\r\n const ot = await getObjekttyper(indberetning.domaeneTypeId);\r\n setObjekttyper(ot);\r\n };\r\n getObjekttyperForTema();\r\n }, [indberetning.domaeneTypeId, getObjekttyper]);\r\n\r\n const renderMessages = (\r\n indberetning: Hoeringssag,\r\n currentUser: Bruger\r\n ): ViewElement[] => {\r\n let viewElements: ViewElement[] = [];\r\n if (indberetning.korrespondance) {\r\n indberetning.korrespondance.forEach((k: Indlaeg) => {\r\n const { typeId } = k;\r\n const whitelist = isHoeringssagChat\r\n ? whitelistHoeringssag\r\n : whitelistSagsbehandling;\r\n if (whitelist.includes(typeId)) {\r\n viewElements.push({\r\n date: Date.parse(k.ts),\r\n component: (\r\n \r\n ),\r\n });\r\n }\r\n });\r\n }\r\n if (isHoeringssagChat) {\r\n if (indberetning.hoeringsansvarligmappe) {\r\n indberetning.hoeringsansvarligmappe.forEach((k: Hoeringsmappe) => {\r\n const isMe =\r\n currentUser.rolleId === RessourceRolleIdEnum.sagsbehandler &&\r\n indberetning.ressource !== null; // If the ressource is null, it's not supposed to be viewed\r\n // const isMeToo = isIndberetningMine(\r\n // currentUser,\r\n // indberetning,\r\n // isHoeringssagChat\r\n // );\r\n if (k.geometri) {\r\n k.geometri.forEach((g) => {\r\n viewElements.push({\r\n date: Date.parse(g.dato),\r\n component: (\r\n {\r\n setChatState(\"LOADING\");\r\n cancelDrawingAndUploadFile();\r\n dispatchToMap({\r\n type: \"EDIT_GEOMETRY\",\r\n geometryToEdit: feature,\r\n });\r\n }}\r\n objektTyper={objekttyper}\r\n ændringsTyper={ændringsTyper}\r\n sagsbehandlingApi={sagsbehandlingApi}\r\n />\r\n ),\r\n });\r\n });\r\n }\r\n if (k.fil) {\r\n k.fil.forEach((g: any) => {\r\n viewElements.push({\r\n date: Date.parse(g.dato),\r\n component: (\r\n {\r\n setChatState(\"LOADING\");\r\n cancelDrawingAndUploadFile();\r\n dispatchToMap({\r\n type: \"EDIT_GEOMETRY\",\r\n geometryToEdit: feature,\r\n });\r\n }}\r\n objektTyper={objekttyper}\r\n ændringsTyper={ændringsTyper}\r\n sagsbehandlingApi={sagsbehandlingApi}\r\n />\r\n ),\r\n });\r\n });\r\n }\r\n });\r\n }\r\n\r\n // Høringspartmappen\r\n if (indberetning.hoeringspartmappe) {\r\n indberetning.hoeringspartmappe.forEach((k: Hoeringsmappe) => {\r\n const isMe =\r\n currentUser.rolleId === RessourceRolleIdEnum.høringspart &&\r\n indberetning.ressource !== null; // If the ressource is null, it's not supposed to be viewed\r\n if (k.geometri) {\r\n k.geometri.forEach((g) => {\r\n viewElements.push({\r\n date: Date.parse(g.dato),\r\n component: (\r\n {\r\n setChatState(\"LOADING\");\r\n cancelDrawingAndUploadFile();\r\n dispatchToMap({\r\n type: \"EDIT_GEOMETRY\",\r\n geometryToEdit: feature,\r\n });\r\n }}\r\n objektTyper={objekttyper}\r\n ændringsTyper={ændringsTyper}\r\n sagsbehandlingApi={sagsbehandlingApi}\r\n />\r\n ),\r\n });\r\n });\r\n }\r\n if (k.fil) {\r\n k.fil.forEach((g: any) => {\r\n viewElements.push({\r\n date: Date.parse(g.dato),\r\n component: (\r\n {\r\n setChatState(\"LOADING\");\r\n cancelDrawingAndUploadFile();\r\n dispatchToMap({\r\n type: \"EDIT_GEOMETRY\",\r\n geometryToEdit: feature,\r\n });\r\n }}\r\n objektTyper={objekttyper}\r\n ændringsTyper={ændringsTyper}\r\n sagsbehandlingApi={sagsbehandlingApi}\r\n />\r\n ),\r\n });\r\n });\r\n }\r\n });\r\n }\r\n } else {\r\n // Løb igennem indberetningsmappen\r\n if (indberetning.indberetningsmappe) {\r\n indberetning.indberetningsmappe.forEach((k: Indberetningsmappe) => {\r\n const isMe =\r\n currentUser.rolleId === RessourceRolleIdEnum.indberetter &&\r\n indberetning.ressource !== null; // If ressource is null, the indberetter is not the owner\r\n if (k.geometri) {\r\n k.geometri.forEach((g) => {\r\n viewElements.push({\r\n date: Date.parse(g.dato),\r\n component: (\r\n // TODO: #280: Disable delete for indberetter geometri stednavn\r\n {\r\n setChatState(\"LOADING\");\r\n cancelDrawingAndUploadFile();\r\n dispatchToMap({\r\n type: \"EDIT_GEOMETRY\",\r\n geometryToEdit: feature,\r\n });\r\n }}\r\n objektTyper={objekttyper}\r\n ændringsTyper={ændringsTyper}\r\n sagsbehandlingApi={sagsbehandlingApi}\r\n />\r\n ),\r\n });\r\n });\r\n }\r\n if (k.fil) {\r\n k.fil.forEach((g: any) => {\r\n viewElements.push({\r\n date: Date.parse(g.dato),\r\n component: (\r\n {\r\n setChatState(\"LOADING\");\r\n cancelDrawingAndUploadFile();\r\n dispatchToMap({\r\n type: \"EDIT_GEOMETRY\",\r\n geometryToEdit: feature,\r\n });\r\n }}\r\n objektTyper={objekttyper}\r\n ændringsTyper={ændringsTyper}\r\n sagsbehandlingApi={sagsbehandlingApi}\r\n />\r\n ),\r\n });\r\n });\r\n }\r\n });\r\n }\r\n // Løb igennem sagsbehandlermappen\r\n if (indberetning.sagsbehandlermappe) {\r\n indberetning.sagsbehandlermappe.forEach((k: Sagsbehandlermappe) => {\r\n const isMe =\r\n currentUser.rolleId === RessourceRolleIdEnum.sagsbehandler &&\r\n indberetning.ressource !== null; // If ressource is null, the indberetter is not the owner;\r\n k.geometri.forEach((g) => {\r\n viewElements.push({\r\n date: Date.parse(g.dato),\r\n component: (\r\n {\r\n setChatState(\"LOADING\");\r\n cancelDrawingAndUploadFile();\r\n dispatchToMap({\r\n type: \"EDIT_GEOMETRY\",\r\n geometryToEdit: feature,\r\n });\r\n }}\r\n objektTyper={objekttyper}\r\n ændringsTyper={ændringsTyper}\r\n sagsbehandlingApi={sagsbehandlingApi}\r\n />\r\n ),\r\n });\r\n });\r\n k.fil.forEach((g: any) => {\r\n viewElements.push({\r\n date: Date.parse(g.dato),\r\n component: (\r\n {\r\n setChatState(\"LOADING\");\r\n cancelDrawingAndUploadFile();\r\n dispatchToMap({\r\n type: \"EDIT_GEOMETRY\",\r\n geometryToEdit: feature,\r\n });\r\n }}\r\n objektTyper={objekttyper}\r\n ændringsTyper={ændringsTyper}\r\n sagsbehandlingApi={sagsbehandlingApi}\r\n />\r\n ),\r\n });\r\n });\r\n });\r\n }\r\n }\r\n\r\n // Sorter listen\r\n viewElements.sort(function (a, b) {\r\n return a.date - b.date;\r\n });\r\n return viewElements;\r\n };\r\n\r\n useEffect(() => {\r\n return () => {\r\n dispatchToMap({ type: \"CANCEL_EDIT_GEOMETRY\" });\r\n dispatchToMap({\r\n type: \"SET_DRAWTOOL\",\r\n drawTool: undefined,\r\n });\r\n };\r\n }, [dispatchToMap]);\r\n const skrivBesked = (\r\n currentUser: Bruger,\r\n besked: string,\r\n typeId: IndlaegTypeIdEnum,\r\n sagsId: number\r\n ) => {\r\n let indlaeg: Indlaeg = {\r\n id: 0,\r\n indhold: besked,\r\n organisationNavn: \"\",\r\n personId: currentUser.personId,\r\n personNavn: currentUser.navn,\r\n typeId: typeId,\r\n typeNavn: \"\",\r\n organisationId: 0,\r\n organisationForkortelse: \"\",\r\n ts: \"\",\r\n };\r\n\r\n const nytIndlaeg = skrivChatBesked(currentUser.personId, sagsId, indlaeg);\r\n\r\n return nytIndlaeg;\r\n };\r\n const senestOpdateret =\r\n messages && messages.length > 0\r\n ? formatDateString(\r\n new Date(messages[messages.length - 1].date).toString()\r\n )\r\n : \"\";\r\n const senestOpdateretVoiceOver =\r\n messages && messages.length > 0 ? (\r\n \r\n Senest opdateret:{\" \"}\r\n \r\n {formatDateString(\r\n new Date(messages[messages.length - 1].date).toString(),\r\n \"dd-MM-yyyy\"\r\n )}\r\n {\" \"}\r\n klokken{\" \"}\r\n {formatDateString(\r\n new Date(messages[messages.length - 1].date).toString(),\r\n \"HH:mm\"\r\n )}\r\n \r\n ) : (\r\n \"\"\r\n );\r\n\r\n // #296, #274, #324 (hvornår skal knapper under chat vises)\r\n const showButtons =\r\n isIndberetningMine(currentUser, indberetning, isHoeringssagChat) &&\r\n !isIndberetningAfsluttet(indberetning) &&\r\n !(\r\n !isHoeringssagChat &&\r\n currentUser.rolleId === RessourceRolleIdEnum.høringspart\r\n );\r\n\r\n return (\r\n \r\n
\r\n {/* {isHoeringssagChat && (\r\n \r\n
\r\n \r\n
\r\n
\r\n
\r\n Høringssag ses kun af sagsbehandler og høringsparter\r\n \r\n\r\n
\r\n Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed\r\n diam nonumy eirmod tempor invidunt ut labore et dolore magna\r\n aliquyam erat.\r\n
\r\n
\r\n Ønsker du mere information \r\n
\r\n
\r\n Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed\r\n diam nonumy eirmod tempor invidunt ut labore et dolore magna\r\n aliquyam erat.Lorem ipsum dolor sit amet, consetetur sadipscing\r\n elitr, sed diam nonumy eirmod tempor invidunt ut labore et\r\n dolore magna aliquyam erat.\r\n
\r\n
\r\n
\r\n )} */}\r\n {isHoeringssagChat && (\r\n <>\r\n Høringssag \r\n Oversigt over høringssag.
\r\n >\r\n )}\r\n {!isHoeringssagChat && (\r\n <>\r\n Sagsbehandlings journal \r\n Oversigt over sagsbehandlingen.
\r\n >\r\n )}\r\n\r\n {(indberetning.korrespondance ||\r\n indberetning.indberetningsmappe ||\r\n indberetning.sagsbehandlermappe) && (\r\n \r\n
\r\n {chatState === \"LOADING\" && (\r\n
\r\n \r\n Opdaterer journal\r\n \r\n \r\n \r\n )}\r\n {messages && messages.length > 0 && chatState === \"IDLE\" && (\r\n <>\r\n
\r\n \r\n Senest opdateret:\r\n \r\n {senestOpdateret}\r\n \r\n {senestOpdateretVoiceOver}\r\n >\r\n )}\r\n {messages && messages.length === 0 && (\r\n
\r\n
\r\n Ingen beskeder endnu\r\n \r\n
Her vises journalisering for sagen
\r\n
\r\n )}\r\n
\r\n
\r\n
{\r\n setScrollPos((e.target as any).scrollTop);\r\n }}\r\n >\r\n
\r\n {messages\r\n ?.slice()\r\n .reverse()\r\n .map((m, i) => {\r\n return
{m.component} ;\r\n })}\r\n
\r\n
\r\n {showButtons && (\r\n
\r\n
{\r\n let type;\r\n if (isHoeringssagChat) {\r\n currentUser.rolleId === RessourceRolleIdEnum.sagsbehandler // This is a høringssanvarlig apparently\r\n ? (type = IndlaegTypeIdEnum.beskedFraHoeringsAnsvarlig)\r\n : (type = IndlaegTypeIdEnum.beskedFraHoeringspart);\r\n } else {\r\n currentUser.rolleId === RessourceRolleIdEnum.sagsbehandler\r\n ? (type = IndlaegTypeIdEnum.fraSagsbehandler)\r\n : (type = IndlaegTypeIdEnum.tilIndberetter);\r\n }\r\n setChatState(\"LOADING\");\r\n cancelDrawingAndUploadFile();\r\n showModal({\r\n content: (\r\n {\r\n skrivBesked(\r\n currentUser,\r\n besked,\r\n rolleTypeToIndlaegType(\r\n currentUser.rolleId,\r\n context,\r\n isStednavn\r\n ),\r\n indberetning.id\r\n ).then((nytIndlaeg) => {\r\n setIndberetning({\r\n ...indberetning,\r\n korrespondance: [\r\n ...indberetning.korrespondance,\r\n nytIndlaeg,\r\n ],\r\n });\r\n setChatState(\"IDLE\");\r\n });\r\n }}\r\n />\r\n ),\r\n title: \"Ny besked\",\r\n closeModalCallback: () => {\r\n setChatState(\"IDLE\");\r\n },\r\n });\r\n }}\r\n >\r\n Skriv besked\r\n \r\n {currentUser.rolleId !== RessourceRolleIdEnum.indberetter &&\r\n !isHoeringssagChat && (\r\n
{\r\n setChatState(\"LOADING\");\r\n cancelDrawingAndUploadFile();\r\n showModal({\r\n title: \"Intern note\",\r\n content: (\r\n {\r\n skrivBesked(\r\n currentUser,\r\n besked,\r\n IndlaegTypeIdEnum.intern,\r\n indberetning.id\r\n ).then((nytIndlaeg) => {\r\n setIndberetning({\r\n ...indberetning,\r\n korrespondance: [\r\n ...indberetning.korrespondance,\r\n nytIndlaeg,\r\n ],\r\n });\r\n setChatState(\"IDLE\");\r\n });\r\n }}\r\n />\r\n ),\r\n closeModalCallback: () => {\r\n setChatState(\"IDLE\");\r\n },\r\n });\r\n }}\r\n >\r\n Intern note\r\n \r\n )}\r\n {!(\r\n isStednavn &&\r\n currentUser.rolleId === RessourceRolleIdEnum.sagsbehandler\r\n ) && (\r\n
\r\n {newFile.state !== \"UPLOADED\" && (\r\n
{\r\n cancelEditGeometry();\r\n setNewFile({ state: \"UPLOADING\", file: undefined });\r\n const { files } = e.target;\r\n if (files && files.length) {\r\n const file = files[0];\r\n let formData = new FormData();\r\n formData.append(\"file\", file);\r\n uploadFile(formData).then((resp) => {\r\n setNewFile({\r\n state: \"UPLOADED\",\r\n file: {\r\n id: resp.id,\r\n originalFilNavn: resp.originalFilNavn,\r\n },\r\n });\r\n });\r\n\r\n dispatchToMap({\r\n type: \"SET_DRAWTOOL\",\r\n drawTool: \"point\",\r\n });\r\n } else {\r\n // Fortryd tegning\r\n cancelDrawingAndUploadFile();\r\n }\r\n }}\r\n />\r\n )}\r\n {newFile.state === \"UPLOADED\" && (\r\n {\r\n cancelDrawingAndUploadFile();\r\n }}\r\n >\r\n \r\n Fortryd upload\r\n \r\n )}\r\n \r\n )}\r\n\r\n {!(\r\n isStednavn &&\r\n currentUser.rolleId === RessourceRolleIdEnum.indberetter\r\n ) && (\r\n
{\r\n if (!activeDrawTool || newFile.state === \"UPLOADED\") {\r\n // Aktiver tegning\r\n setChatState(\"LOADING\");\r\n cancelEditGeometry();\r\n setNewFile({ state: \"IDLE\", file: undefined });\r\n dispatchToMap({\r\n type: \"SET_DRAWTOOL\",\r\n drawTool: \"point\",\r\n });\r\n } else {\r\n // Fortryd tegning\r\n cancelDrawingAndUploadFile();\r\n }\r\n }}\r\n >\r\n {(!activeDrawTool || newFile.file) && (\r\n <>\r\n \r\n Tegn opdatering\r\n >\r\n )}\r\n {activeDrawTool && !newFile.file && (\r\n <>\r\n \r\n Fortryd tegning\r\n >\r\n )}\r\n \r\n )}\r\n
\r\n )}\r\n
\r\n )}\r\n \r\n
\r\n );\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n}\r\n","import {\r\n useContext,\r\n useEffect,\r\n useLayoutEffect,\r\n useRef,\r\n useState,\r\n} from \"react\";\r\nimport { getIndberetning, sagsbehandlingApi } from \"api/fip\";\r\nimport {\r\n Hoeringssag,\r\n IndberetningState,\r\n RessourceRolleIdEnum,\r\n statusIdEnum,\r\n} from \"interfaces/IIndberetning\";\r\nimport ChevronLeft from \"components/icons/ChevronLeftSmall\";\r\nimport Section from \"components/common/Section\";\r\nimport { Link, useParams } from \"react-router-dom\";\r\nimport { AuthContext, Bruger } from \"context/AuthProvider\";\r\nimport { MapContext } from \"context/MapProvider\";\r\nimport { paths } from \"routes/routesConfig\";\r\nimport { convertWktToFeature, zoomToFeature } from \"util/ol\";\r\nimport { statusStore, tema } from \"config/FipConfig\";\r\nimport { finishedDrawingSource } from \"config/interactions\";\r\nimport { getSagsaktFeaturesFromHoeringssag } from \"./fipUtil\";\r\nimport IndberetningNav from \"components/common/Indberetning/IndberetningNav\";\r\nimport Detaljevisning from \"components/common/Indberetning/Detaljevisning\";\r\nimport Sagsbehandlerfunktioner from \"components/common/Indberetning/Fip/Sagsbehandlerfunktioner\";\r\nimport Hoeringspartfunktioner from \"components/common/Indberetning/Fip/Hoeringspartfunktioner\";\r\nimport { useErrorHandler } from \"react-error-boundary\";\r\nimport Chat from \"components/common/Indberetning/Chat/Chat\";\r\nimport { NewFileState } from \"./FipIndberet\";\r\nimport { SessionTimerContext } from \"context/SessionTimerProvider\";\r\n\r\nexport const isIndberetningMine = (\r\n bruger: Bruger,\r\n indberetning: Hoeringssag,\r\n isHoeringssag: boolean\r\n) => {\r\n let isMine = false;\r\n const ressource = indberetning.ressource;\r\n if (ressource) {\r\n ressource.forEach((r) => {\r\n if (\r\n r.rolleId === RessourceRolleIdEnum.sagsbehandler &&\r\n r.personId === bruger.personId\r\n ) {\r\n isMine = true;\r\n } else if (\r\n bruger.rolleId === RessourceRolleIdEnum.indberetter &&\r\n r.rolleId === RessourceRolleIdEnum.indberetter\r\n ) {\r\n isMine = true;\r\n } else if (\r\n bruger.rolleId === RessourceRolleIdEnum.høringspart &&\r\n r.rolleId === RessourceRolleIdEnum.høringspart &&\r\n r.personId === bruger.personId\r\n ) {\r\n isMine = true;\r\n }\r\n });\r\n }\r\n if (!isHoeringssag && bruger.rolleId === RessourceRolleIdEnum.høringspart) {\r\n isMine = false;\r\n }\r\n\r\n return isMine;\r\n};\r\n\r\nexport const isIndberetningAfsluttet = (indberetning: Hoeringssag) => {\r\n return (\r\n [statusIdEnum.afsluttet, statusIdEnum.afsluttetGST].indexOf(\r\n indberetning.statusId\r\n ) > -1\r\n );\r\n};\r\n\r\nexport type PaneState = \"sagsdetaljer\" | \"sagsbehandling\" | \"hoeringssag\";\r\n\r\nexport default function FipIndberetning() {\r\n let { id } = useParams();\r\n const { authState } = useContext(AuthContext);\r\n const { resetSessionTimer } = useContext(SessionTimerContext);\r\n const { dispatchToMap, mapState } = useContext(MapContext);\r\n const { map } = mapState;\r\n const handleError = useErrorHandler();\r\n const { currentUser } = authState;\r\n const [indberetningState, setIndberetningState] = useState(\r\n {\r\n state: \"LOADING\",\r\n indberetning: undefined,\r\n }\r\n );\r\n const [newFile, setNewFile] = useState({\r\n state: \"IDLE\",\r\n file: undefined,\r\n });\r\n const cancelDrawingAndUploadFile = () => {\r\n setNewFile({ state: \"IDLE\", file: undefined });\r\n dispatchToMap({ type: \"CANCEL_EDIT_GEOMETRY\" });\r\n dispatchToMap({\r\n type: \"SET_DRAWTOOL\",\r\n drawTool: undefined,\r\n });\r\n };\r\n const indberetningStateHandler = (indberetning: Hoeringssag) => {\r\n setIndberetningState({\r\n ...indberetningState,\r\n indberetning: indberetning,\r\n });\r\n };\r\n\r\n const hash = window.location.hash.replace(\"#\", \"\");\r\n const [activePaneState, setActivePaneState] = useState<\r\n \"sagsdetaljer\" | \"sagsbehandling\" | \"hoeringssag\"\r\n >(\r\n hash === \"sagsbehandling\" || hash === \"hoeringssag\" ? hash : \"sagsdetaljer\"\r\n );\r\n\r\n useLayoutEffect(() => {\r\n window.location.hash = activePaneState;\r\n }, [activePaneState]);\r\n\r\n const [sagsbehandlingChatScrollPos, setSagsbehandlingChatScrollPos] =\r\n useState(undefined);\r\n const [høringsChatScrollPos, setHøringsChatScrollPos] = useState<\r\n number | undefined\r\n >(undefined);\r\n useEffect(() => {\r\n setIndberetningState({ indberetning: undefined, state: \"LOADING\" });\r\n const hentIndberetning = async () => {\r\n getIndberetning(id, currentUser.personId)\r\n .then((response) => {\r\n const features = getSagsaktFeaturesFromHoeringssag(response);\r\n\r\n features.forEach((feature) => {\r\n finishedDrawingSource.addFeature(feature);\r\n });\r\n\r\n setIndberetningState({\r\n indberetning: response,\r\n state: \"IDLE\",\r\n });\r\n resetSessionTimer();\r\n })\r\n .catch((e) => {\r\n e.response.status = 404;\r\n e.message = \"Kunne ikke finde indberetning\";\r\n handleError(e);\r\n });\r\n };\r\n hentIndberetning();\r\n }, [setIndberetningState, id, currentUser, handleError, resetSessionTimer]);\r\n\r\n const didZoomAlready = useRef(false);\r\n useEffect(() => {\r\n const { indberetning } = indberetningState;\r\n if (map && indberetning && indberetning.bbox && !didZoomAlready.current) {\r\n zoomToFeature(map, convertWktToFeature(indberetning.bbox));\r\n didZoomAlready.current = true;\r\n }\r\n }, [indberetningState, map, activePaneState]);\r\n useEffect(() => {\r\n const { indberetning } = indberetningState;\r\n\r\n if (map && indberetningState.state === \"IDLE\" && indberetning) {\r\n const indberetningsmappe = indberetning.indberetningsmappe.length\r\n ? indberetning.indberetningsmappe[0]\r\n : undefined;\r\n if (indberetningsmappe) {\r\n const indberetningTema = tema.find(\r\n (t) => t.id === indberetningsmappe.korttemaId\r\n );\r\n if (indberetningTema) {\r\n dispatchToMap({ type: \"SET_TEMA\", tema: indberetningTema });\r\n dispatchToMap({\r\n type: \"SET_LAYERS\",\r\n baselayers: indberetningTema.baseLayers,\r\n layers: indberetningTema.layers,\r\n });\r\n }\r\n }\r\n\r\n finishedDrawingSource.clear();\r\n const features = getSagsaktFeaturesFromHoeringssag(indberetning);\r\n features.forEach((feature) => {\r\n finishedDrawingSource.addFeature(feature);\r\n });\r\n }\r\n return () => {\r\n finishedDrawingSource.clear();\r\n dispatchToMap({ type: \"SET_TEMA\", tema: undefined });\r\n };\r\n }, [map, indberetningState, dispatchToMap]);\r\n const titelRef = useRef(null);\r\n const loadingRef = useRef(null);\r\n useLayoutEffect(() => {\r\n if (indberetningState.state === \"IDLE\") titelRef.current?.focus();\r\n if (indberetningState.state === \"LOADING\") loadingRef.current?.focus();\r\n }, [indberetningState.state]);\r\n if (indberetningState.state === \"LOADING\")\r\n return (\r\n \r\n
\r\n
\r\n {/* Loading... */}\r\n
\r\n
\r\n
\r\n Henter sag ...\r\n \r\n
\r\n );\r\n if (indberetningState.state === \"IDLE\" && indberetningState.indberetning) {\r\n const { indberetning } = indberetningState;\r\n const {\r\n ressource,\r\n hoeringsansvarligmappe: hoeringsansvarligmappeListe,\r\n hoeringspartmappe: hoeringspartmappeListe,\r\n indberetningsmappe: indberetningsmappeListe,\r\n sagsbehandlermappe: sagsbehandlermappeListe,\r\n } = indberetning;\r\n\r\n const indberettere = ressource?.filter((r) => r.rolleId === 1);\r\n const indberetter = indberettere?.length > 0 ? indberettere[0] : undefined;\r\n\r\n const sagsbehandlere = ressource?.filter((r) => r.rolleId === 2);\r\n const sagsbehandler =\r\n sagsbehandlere?.length > 0 ? sagsbehandlere[0] : undefined;\r\n\r\n return (\r\n \r\n
\r\n
\r\n
\r\n Tilbage til indberetninger\r\n \r\n
\r\n {indberetning.emne}\r\n \r\n
\r\n Status: \r\n {isIndberetningMine(currentUser, indberetning, false) && (\r\n \r\n {currentUser.rolleId === RessourceRolleIdEnum.indberetter\r\n ? \"Indberettet af dig\"\r\n : \"Din indberetning\"}\r\n , \r\n \r\n )}\r\n s.id === indberetning.statusId)\r\n ?.className\r\n }`}\r\n >\r\n {statusStore.find((s) => s.id === indberetning.statusId)?.name}\r\n \r\n {/*I høring \r\n Afventer sagsbehandling */}\r\n
\r\n
\r\n {/* Fane Nav */}\r\n
\r\n {/* Fane indhold */}\r\n
\r\n {/* Detaljevisning */}\r\n {activePaneState === \"sagsdetaljer\" &&\r\n indberetningsmappeListe &&\r\n indberetningsmappeListe.length > 0 && (\r\n
{\r\n if (map) {\r\n zoomToFeature(map, convertWktToFeature(indberetning.bbox));\r\n }\r\n }}\r\n />\r\n )}\r\n {/* Sagsbehandling / Chat mellem sagsbehandler og indberetter */}\r\n {activePaneState === \"sagsbehandling\" &&\r\n ((sagsbehandlermappeListe && sagsbehandlermappeListe.length > 0) ||\r\n (indberetningsmappeListe &&\r\n indberetningsmappeListe.length > 0)) && (\r\n \r\n )}\r\n {activePaneState === \"hoeringssag\" &&\r\n hoeringsansvarligmappeListe &&\r\n hoeringsansvarligmappeListe.length > 0 &&\r\n ![\r\n RessourceRolleIdEnum.indberetter,\r\n RessourceRolleIdEnum.gæst,\r\n ].includes(currentUser.rolleId) && (\r\n /* */\r\n\r\n \r\n )}\r\n {hoeringspartmappeListe && hoeringspartmappeListe.length > 0 && (\r\n \r\n
\r\n Høringspartmappe \r\n asd
\r\n \r\n
\r\n )}\r\n {/* {sagsbehandler && ( */}\r\n {/* Skal KUN ses af sagsbehandler */}\r\n {/* <> */}\r\n {sagsbehandlermappeListe &&\r\n sagsbehandlermappeListe.length > 0 &&\r\n ![\r\n RessourceRolleIdEnum.indberetter,\r\n RessourceRolleIdEnum.høringspart,\r\n ].includes(currentUser.rolleId) && (\r\n \r\n )}\r\n\r\n {/* Skal KUN ses af Høringspart */}\r\n {/* <> */}\r\n {hoeringspartmappeListe &&\r\n hoeringspartmappeListe.length > 0 &&\r\n currentUser.rolleId === RessourceRolleIdEnum.høringspart && (\r\n \r\n )}\r\n {/* > */}\r\n {/* )} */}\r\n \r\n
\r\n );\r\n }\r\n return (\r\n \r\n
Noget gik galt ... \r\n \r\n );\r\n}\r\n","import { del, get, post, put } from \"api\";\r\nimport { Objekttype, SagsbehandlingApi } from \"api/interfaces\";\r\nimport { getFilterValues, getFilterValueUrlString } from \"api/util\";\r\nimport { Bruger } from \"context/AuthProvider\";\r\nimport { FeatureCollection } from \"geojson\";\r\nimport {\r\n convertIndberetningDTO,\r\n ExpandedIndberetningDTO,\r\n Hoeringssag,\r\n IFileUploadResponse,\r\n Indberetning,\r\n IndberetningDTO,\r\n Indlaeg,\r\n Ressource,\r\n RessourceRolleIdEnum,\r\n Sagsakt,\r\n statusIdEnum,\r\n} from \"interfaces/IIndberetning\";\r\nimport { formatDateString } from \"util/date\";\r\n\r\nexport const getIndberetninger = async (options: {\r\n personId: number;\r\n rolleId: number;\r\n filterId: number;\r\n searchEmne?: string;\r\n searchBeskrivelse?: string;\r\n extent?: number[];\r\n}): Promise => {\r\n const { filterId, personId, rolleId, searchBeskrivelse, searchEmne, extent } =\r\n options;\r\n const filterValues = getFilterValues(extent, searchEmne, searchBeskrivelse);\r\n try {\r\n const iDTOs = await get({\r\n query: `stednavn/api/saginfo?filterId=${filterId}&rolleId=${rolleId}&personId=${personId}&domaeneTypes=&filterValues=${filterValues}&page=1&start=0&limit=25&sort=%5B%7B%22property%22%3A%22id%22%2C%22direction%22%3A%22DESC%22%7D%5D`,\r\n });\r\n return iDTOs.map((i) => convertIndberetningDTO(i));\r\n } catch (error) {\r\n return Promise.reject(error);\r\n }\r\n};\r\n\r\nexport const getIndberetning = async (\r\n indberetningId: number,\r\n personId: number\r\n): Promise => {\r\n try {\r\n const iDTO = await get({\r\n query: `stednavn/api/sager/${indberetningId}?filterId=0&personId=${personId}&id=${indberetningId}`,\r\n });\r\n return iDTO;\r\n } catch (error) {\r\n return Promise.reject(error);\r\n }\r\n};\r\n\r\nexport const postIndberetning = async (\r\n personId: number,\r\n email: string,\r\n body: Hoeringssag\r\n): Promise => {\r\n try {\r\n //http://fip.cust.septima.dk/api/sager?personId=4&email=xxx%40yyy.dk\r\n const iDTO = await post({\r\n query: `stednavn/api/sager/?personId=${personId}&email=${email}`,\r\n body,\r\n });\r\n return convertIndberetningDTO(iDTO);\r\n } catch (error) {\r\n return Promise.reject(error);\r\n }\r\n};\r\n\r\nexport const putIndberetningSDSYS = async (\r\n personId: number,\r\n statusId: statusIdEnum,\r\n body: Hoeringssag\r\n): Promise => {\r\n body.statusId = statusId;\r\n try {\r\n //http://fip.cust.septima.dk/api/sager?personId=4&email=xxx%40yyy.dk\r\n const sag = await put({\r\n query: `stednavn/api/sager/${body.id}?personId=${personId}`,\r\n body,\r\n });\r\n return sag;\r\n } catch (error) {\r\n return Promise.reject(error);\r\n }\r\n};\r\n\r\nexport const getStednavnFeatureInfo = async (options: {\r\n personId: number;\r\n rolleId: number;\r\n filterId: number;\r\n searchEmne?: string;\r\n searchBeskrivelse?: string;\r\n extent: number[];\r\n height;\r\n width: number;\r\n x: number;\r\n y: number;\r\n}) => {\r\n const {\r\n filterId,\r\n personId,\r\n rolleId,\r\n searchBeskrivelse,\r\n searchEmne,\r\n extent,\r\n height,\r\n width,\r\n x,\r\n y,\r\n } = options;\r\n try {\r\n const queryParams: any = {\r\n service: \"WMS\",\r\n Version: \"1.1.1\",\r\n request: \"GetFeatureInfo\",\r\n LAYERS: \"fipudv:Sag2\",\r\n QUERY_LAYERS: \"fipudv:Sag2\",\r\n FORMAT: \"application/json\",\r\n INFO_FORMAT: \"application/json\",\r\n SRS: \"EPSG:25832\",\r\n BBOX: extent.join(\",\"),\r\n FEATURE_COUNT: 10,\r\n height,\r\n width,\r\n x,\r\n y,\r\n VIEWPARAMS: `applikationId:4;domaeneTypeIds:;filterId:${\r\n filterId === 6 ? 4 : filterId\r\n };personId:${personId};rolleId:${rolleId};filterValues:${getFilterValueUrlString(\r\n searchEmne,\r\n searchBeskrivelse\r\n )}`,\r\n };\r\n const featureCollection = await get({\r\n query: `proxy.ashx?${new URLSearchParams(queryParams).toString()}`,\r\n });\r\n return featureCollection;\r\n } catch (error) {\r\n return Promise.reject(error);\r\n }\r\n};\r\nexport const afbrydHoering = async (\r\n currentUser: Bruger,\r\n daværendeRessource: Ressource,\r\n indberetning: Hoeringssag,\r\n statusId: statusIdEnum\r\n): Promise => {\r\n try {\r\n const r = await del({\r\n query: `stednavn/api/ressourcer/${daværendeRessource.id}?personId=${currentUser.personId}&sagId=${indberetning.id}&statusId=${statusId}`,\r\n body: daværendeRessource,\r\n });\r\n const resp = JSON.parse(JSON.stringify(r)); // Gets rid of single-quotes\r\n\r\n if (resp.errormsg) Promise.reject(resp);\r\n } catch (error) {\r\n return Promise.reject(error);\r\n }\r\n};\r\n\r\nconst skrivChatBesked = async (\r\n personId: number,\r\n sagId: number,\r\n body: Indlaeg\r\n): Promise => {\r\n try {\r\n const r = await post({\r\n query: `stednavn/api/indlaeg/?personId=${personId}&sagId=${sagId}`,\r\n body: body,\r\n });\r\n const resp = JSON.parse(JSON.stringify(r)); // Gets rid of single-quotes\r\n\r\n if (resp.errormsg) Promise.reject(resp);\r\n return resp;\r\n } catch (error) {\r\n return Promise.reject(error);\r\n }\r\n};\r\nexport const afslutIndberetning = async (\r\n kommentar: string,\r\n currentUser: Bruger,\r\n id: number,\r\n indberetning: Hoeringssag\r\n): Promise => {\r\n try {\r\n // First post the komment as an indlaeg.\r\n let indlaeg = {\r\n id: 0,\r\n indhold: kommentar,\r\n organisationForkortelse: \"\",\r\n organisationId: 0,\r\n organisationNavn: \"\",\r\n personId: currentUser.personId,\r\n personNavn: \"\",\r\n ts: \"\",\r\n typeId: 5,\r\n typeNavn: \"\",\r\n };\r\n const r1 = skrivChatBesked(currentUser.personId, id, indlaeg);\r\n const resp1 = JSON.parse(JSON.stringify(r1)); // Gets rid of single-quotes\r\n if (resp1.errormsg) Promise.reject(resp1);\r\n\r\n // Get the current date in the correct format\r\n const r = await del({\r\n // apiPrefix: \"https://fip.cust.septima.dk/\",\r\n query: `stednavn/api/Sager/${id}?personId=${currentUser.personId}`,\r\n body: indberetning,\r\n });\r\n const resp = JSON.parse(JSON.stringify(r)); // Gets rid of single-quotes\r\n\r\n if (resp.errormsg) Promise.reject(resp);\r\n return resp;\r\n } catch (error) {\r\n return Promise.reject(error);\r\n }\r\n};\r\nexport const opretSag = async (\r\n user: Bruger,\r\n indberetning: Hoeringssag\r\n): Promise => {\r\n try {\r\n const r = await put({\r\n // apiPrefix: \"https://fip.cust.septima.dk/\",\r\n query: `stednavn/api/hoeringssager/${indberetning.id}?personId=${user.personId}&updateMode=1`,\r\n body: indberetning,\r\n });\r\n const resp = JSON.parse(JSON.stringify(r)); // Gets rid of single-quotes\r\n\r\n if (resp.errormsg) Promise.reject(resp);\r\n\r\n return resp;\r\n } catch (error) {\r\n return Promise.reject(error);\r\n }\r\n};\r\n\r\nexport const tagIndberetning = async (\r\n user: Bruger,\r\n indberetning: Hoeringssag,\r\n statusId: statusIdEnum\r\n): Promise => {\r\n try {\r\n let nyRessource: any = {\r\n email: \"\",\r\n fraTs: null,\r\n id: 0,\r\n navn: \"\",\r\n organisationId: 0,\r\n organisationsnavn: \"\",\r\n personId: user.personId,\r\n rolleId: RessourceRolleIdEnum.sagsbehandler,\r\n tilTs: null,\r\n \"fipbase.model.sag_id\": indberetning.id, // TODO: type this?\r\n };\r\n\r\n const r = await post({\r\n query: `stednavn/api/ressourcer/?personId=${user.personId}&sagId=${indberetning.id}&statusId=${statusId}`,\r\n body: nyRessource,\r\n });\r\n const resp = JSON.parse(JSON.stringify(r)); // Gets rid of single-quotes\r\n\r\n if (resp.errormsg) Promise.reject(resp);\r\n return resp;\r\n } catch (error) {\r\n return Promise.reject(error);\r\n }\r\n};\r\n\r\nexport const tagIndberetningFraSagsbehandler = async (\r\n user: Bruger,\r\n ressource: Ressource\r\n): Promise => {\r\n try {\r\n const r = await put({\r\n // apiPrefix: \"https://fip.cust.septima.dk/\",\r\n query: `stednavn/api/ressourcer/${ressource.id}?personId=${user.personId}`,\r\n body: ressource,\r\n });\r\n const resp = JSON.parse(JSON.stringify(r)); // Gets rid of single-quotes\r\n\r\n if (resp.errormsg) Promise.reject(resp);\r\n return resp;\r\n } catch (error) {\r\n return Promise.reject(error);\r\n }\r\n};\r\nexport const redigerIndberetning = async (\r\n user: Bruger,\r\n indberetning: Hoeringssag\r\n): Promise => {\r\n try {\r\n const r = await put({\r\n // apiPrefix: \"https://fip.cust.septima.dk/\",\r\n query: `stednavn/api/hoeringssager/${indberetning.id}?personId=${user.personId}`,\r\n body: indberetning,\r\n });\r\n const resp = JSON.parse(JSON.stringify(r)); // Gets rid of single-quotes\r\n\r\n if (resp.errormsg) Promise.reject(resp);\r\n return resp;\r\n } catch (error) {\r\n return Promise.reject(error);\r\n }\r\n};\r\n\r\nconst objekttyperCache: any = {};\r\nexport const getObjekttyper = async (\r\n domaeneId: number\r\n): Promise => {\r\n try {\r\n if (objekttyperCache[domaeneId.toString()]) {\r\n return objekttyperCache[domaeneId.toString()];\r\n } else {\r\n const objekttyper = await get<{ value: number; text: string }[]>({\r\n query: `stednavn/api/objekttype?domaeneId=${domaeneId}&page=1&start=0&limit=25`,\r\n });\r\n objekttyperCache[domaeneId.toString()] = objekttyper;\r\n return objekttyper;\r\n }\r\n } catch (error) {\r\n return Promise.reject(error);\r\n }\r\n};\r\nexport const redigerAendringsforslag = async (\r\n currentUser: Bruger,\r\n aendringTypeId: number,\r\n aendringType: string,\r\n id: number,\r\n beskrivelse: string,\r\n featureType: string,\r\n featureTypeId: number,\r\n geometri: string,\r\n geometriType: string,\r\n openLayersId: string\r\n): Promise => {\r\n try {\r\n const dato: string = formatDateString(\r\n new Date().toISOString(),\r\n \"yyyy-MM-dd'T'HH:mm:ss\"\r\n );\r\n const nytAendringsforslag = {\r\n aendringType: aendringType,\r\n aendringTypeId: aendringTypeId,\r\n beskrivelse: beskrivelse,\r\n dato: dato,\r\n id: id,\r\n geometri: geometri,\r\n geometriType: geometriType,\r\n featureType: featureType,\r\n featureTypeId: featureTypeId,\r\n openLayersId: openLayersId,\r\n };\r\n // Get the current date in the correct format\r\n const r = await put({\r\n // apiPrefix: \"https://fip.cust.septima.dk/\",\r\n query: `stednavn/api/aendringsforslag/${id}?personId=${currentUser.personId}`,\r\n body: nytAendringsforslag,\r\n });\r\n const resp = JSON.parse(JSON.stringify(r)); // Gets rid of single-quotes\r\n\r\n if (resp.errormsg) Promise.reject(resp);\r\n return resp;\r\n } catch (error) {\r\n return Promise.reject(error);\r\n }\r\n};\r\n\r\nexport const uploadAendringsforslagGeometri = async (\r\n currentUser: Bruger,\r\n aendringTypeId: number,\r\n aendringType: string,\r\n beskrivelse: string,\r\n featureType: string,\r\n featureTypeId: number,\r\n geometri: string,\r\n geometriType: string,\r\n openLayersId: string,\r\n mappeId: number\r\n): Promise => {\r\n try {\r\n const dato: string = formatDateString(\r\n new Date().toISOString(),\r\n \"yyyy-MM-dd'T'HH:mm:ss\"\r\n );\r\n const nytAendringsforslag = {\r\n aendringType: aendringType,\r\n aendringTypeId: aendringTypeId,\r\n beskrivelse: beskrivelse,\r\n dato: dato,\r\n id: 0,\r\n featureType: featureType,\r\n featureTypeId: featureTypeId,\r\n geometri: geometri,\r\n geometriType: geometriType,\r\n kortforsyningId: \"\",\r\n mimetype: \"\",\r\n nr: 1,\r\n openLayersId: openLayersId,\r\n originalFilNavn: \"\",\r\n supplinfo: \"\",\r\n udpeget: false,\r\n url: \"\",\r\n };\r\n // Get the current date in the correct format\r\n const r = await post({\r\n // apiPrefix: \"https://fip.cust.septima.dk/\",\r\n query: `stednavn/api/aendringsforslag?personId=${currentUser.personId}&mappeId=${mappeId}`,\r\n body: nytAendringsforslag,\r\n });\r\n const resp = JSON.parse(JSON.stringify(r)); // Gets rid of single-quotes\r\n\r\n if (resp.errormsg) Promise.reject(resp);\r\n return resp;\r\n } catch (error) {\r\n return Promise.reject(error);\r\n }\r\n};\r\nexport const redigerSagsaktGeometri = async (\r\n currentUser: Bruger,\r\n id: number,\r\n beskrivelse: string,\r\n geometri: string\r\n): Promise => {\r\n try {\r\n const dato: string = formatDateString(\r\n new Date().toISOString(),\r\n \"yyyy-MM-dd'T'HH:mm:ss\"\r\n );\r\n const nySagsaktGeometri = {\r\n beskrivelse: beskrivelse,\r\n dato: dato,\r\n id: id,\r\n geometri: geometri,\r\n };\r\n // Get the current date in the correct format\r\n const r = await put({\r\n // apiPrefix: \"https://fip.cust.septima.dk/\",\r\n query: `stednavn/api/sagsakter/${id}?personId=${currentUser.personId}`,\r\n body: nySagsaktGeometri,\r\n });\r\n const resp = JSON.parse(JSON.stringify(r)); // Gets rid of single-quotes\r\n\r\n if (resp.errormsg) Promise.reject(resp);\r\n return resp;\r\n } catch (error) {\r\n return Promise.reject(error);\r\n }\r\n};\r\n\r\nexport const uploadSagsaktGeometri = async (\r\n currentUser: Bruger,\r\n id: number,\r\n beskrivelse: string,\r\n openLayersId: string,\r\n geometri: string,\r\n geometriType: string,\r\n udpeget: boolean,\r\n mappeId: number\r\n): Promise => {\r\n try {\r\n const dato: string = formatDateString(\r\n new Date().toISOString(),\r\n \"yyyy-MM-dd'T'HH:mm:ss\"\r\n );\r\n const nySagsakt = {\r\n beskrivelse: beskrivelse,\r\n dato: dato,\r\n id: 0,\r\n filId: 0,\r\n openLayersId: openLayersId,\r\n nr: 0, // TODO: check om dette skal sættes korrekt\r\n geometri: geometri,\r\n geometriType: geometriType,\r\n mimetype: \"\",\r\n originalFilNavn: \"\",\r\n supplInfo: \"\",\r\n udpeget: udpeget,\r\n url: \"\",\r\n };\r\n // Get the current date in the correct format\r\n const r = await post({\r\n // apiPrefix: \"https://fip.cust.septima.dk/\",\r\n query: `stednavn/api/sagsakter?personId=${currentUser.personId}&mappeId=${mappeId}`,\r\n body: nySagsakt,\r\n });\r\n const resp = JSON.parse(JSON.stringify(r)); // Gets rid of single-quotes\r\n\r\n if (resp.errormsg) Promise.reject(resp);\r\n return resp;\r\n } catch (error) {\r\n return Promise.reject(error);\r\n }\r\n};\r\nexport const uploadFile = async (\r\n formData: FormData\r\n): Promise => {\r\n try {\r\n const r = await post({\r\n query: \"upload\",\r\n body: formData,\r\n });\r\n const resp = JSON.parse(\r\n r\r\n .replace(\"success\", '\"success\"')\r\n .replace(\"id\", '\"id\"')\r\n .replace(\"originalFilNavn\", '\"originalFilNavn\"')\r\n .replace(\"errormsg\", '\"errormsg\"')\r\n .replaceAll(\"'\", '\"')\r\n );\r\n if (resp.errormsg) Promise.reject(resp);\r\n return resp;\r\n } catch (error) {\r\n return Promise.reject(error);\r\n }\r\n};\r\n\r\nexport const uploadSagsaktFil = async (\r\n currentUser: Bruger,\r\n beskrivelse: string,\r\n filId: number,\r\n geometri: string,\r\n originalFilNavn: string,\r\n openLayersId: string,\r\n geometriType: string,\r\n udpeget: boolean,\r\n mappeId: number\r\n): Promise => {\r\n try {\r\n const dato: string = formatDateString(\r\n new Date().toISOString(),\r\n \"yyyy-MM-dd'T'HH:mm:ss\"\r\n );\r\n const nySagsakt = {\r\n beskrivelse: beskrivelse,\r\n dato: dato,\r\n id: 0,\r\n filId: filId,\r\n openLayersId: openLayersId,\r\n nr: 0, // TODO: check om dette skal sættes korrekt\r\n geometri: geometri,\r\n geometriType: geometriType,\r\n mimetype: \"\",\r\n originalFilNavn: originalFilNavn,\r\n supplInfo: \"\",\r\n udpeget: udpeget,\r\n url: \"\",\r\n };\r\n // Get the current date in the correct format\r\n const r = await post({\r\n // apiPrefix: \"https://fip.cust.septima.dk/\",\r\n query: `stednavn/api/sagsakter?personId=${currentUser.personId}&mappeId=${mappeId}`,\r\n body: nySagsakt,\r\n });\r\n const resp = JSON.parse(JSON.stringify(r)); // Gets rid of single-quotes\r\n\r\n if (resp.errormsg) Promise.reject(resp);\r\n return resp;\r\n } catch (error) {\r\n return Promise.reject(error);\r\n }\r\n};\r\n\r\nvar personerCache: Objekttype[] = [];\r\nexport const getPersoner = async (\r\n currentUser: Bruger\r\n): Promise => {\r\n try {\r\n // If the cache has data, and the currentuser is NOT in the cache, it's fine\r\n if (\r\n personerCache.length > 0 &&\r\n !personerCache.find((p) => p.value === currentUser.personId)\r\n ) {\r\n return personerCache;\r\n } else {\r\n // Else we need to update the cache\r\n const personer = await get<{ value: number; text: string }[]>({\r\n query: `stednavn/api/sagsbehandler?personId=${currentUser.personId}`,\r\n });\r\n personerCache = personer;\r\n return personerCache;\r\n }\r\n } catch (error) {\r\n return Promise.reject(error);\r\n }\r\n};\r\n\r\nexport const videresendIndberetning = async (\r\n personId: number, // person der skal overtage sagen\r\n currentUser: Ressource // den person der havde sagen før\r\n): Promise => {\r\n try {\r\n // Update the personId\r\n let nyRessource = { ...currentUser, ...{ personId: personId } };\r\n\r\n const r = await put({\r\n // apiPrefix: \"https://fip.cust.septima.dk/\",\r\n query: `stednavn/api/ressourcer/${currentUser.id}?personId=${currentUser.personId}`,\r\n body: nyRessource,\r\n });\r\n const resp = JSON.parse(JSON.stringify(r)); // Gets rid of single-quotes\r\n\r\n if (resp.errormsg) Promise.reject(resp);\r\n return resp;\r\n } catch (error) {\r\n return Promise.reject(error);\r\n }\r\n};\r\n\r\nexport const deleteAendringsforslag = async (\r\n currentUser: Bruger,\r\n id: number\r\n): Promise => {\r\n try {\r\n // Get the current date in the correct format\r\n const r = await del({\r\n // apiPrefix: \"https://fip.cust.septima.dk/\",\r\n query: `stednavn/api/aendringsforslag/${id}?personId=${currentUser.personId}`,\r\n body: { id: id },\r\n });\r\n const resp = JSON.parse(JSON.stringify(r)); // Gets rid of single-quotes\r\n\r\n if (resp.errormsg) Promise.reject(resp);\r\n return resp;\r\n } catch (error) {\r\n return Promise.reject(error);\r\n }\r\n};\r\n\r\nexport const deleteSagsakt = async (\r\n currentUser: Bruger,\r\n id: number\r\n): Promise => {\r\n try {\r\n // Get the current date in the correct format\r\n const r = await del({\r\n // apiPrefix: \"https://fip.cust.septima.dk/\",\r\n query: `stednavn/api/sagsakter/${id}?personId=${currentUser.personId}`,\r\n body: { id: id },\r\n });\r\n const resp = JSON.parse(JSON.stringify(r)); // Gets rid of single-quotes\r\n\r\n if (resp.errormsg) Promise.reject(resp);\r\n return resp;\r\n } catch (error) {\r\n return Promise.reject(error);\r\n }\r\n};\r\n\r\nexport const redigerSagsakt = async (\r\n currentUser: Bruger,\r\n id: number,\r\n beskrivelse: string,\r\n openLayersId: string\r\n): Promise => {\r\n try {\r\n const dato: string = formatDateString(\r\n new Date().toISOString(),\r\n \"yyyy-MM-dd'T'HH:mm:ss\"\r\n );\r\n const nySagsakt = {\r\n beskrivelse: beskrivelse,\r\n dato: dato,\r\n id: id,\r\n openLayersId: openLayersId,\r\n };\r\n // Get the current date in the correct format\r\n const r = await put({\r\n // apiPrefix: \"https://fip.cust.septima.dk/\",\r\n query: `stednavn/api/sagsakter/${id}?personId=${currentUser.personId}`,\r\n body: nySagsakt,\r\n });\r\n const resp = JSON.parse(JSON.stringify(r)); // Gets rid of single-quotes\r\n\r\n if (resp.errormsg) Promise.reject(resp);\r\n return resp;\r\n } catch (error) {\r\n return Promise.reject(error);\r\n }\r\n};\r\n\r\n/* Is never used in stednavn but satisfies API impl. */\r\nexport const opretHoeringssag = async (\r\n user: Bruger,\r\n indberetning: Hoeringssag\r\n): Promise => {\r\n return indberetning;\r\n};\r\nexport const sagsbehandlingApi: SagsbehandlingApi = {\r\n afbrydHoering,\r\n afslutIndberetning,\r\n deleteAendringsforslag,\r\n deleteSagsakt,\r\n getIndberetning,\r\n getObjekttyper,\r\n getPersoner,\r\n opretHoeringssag,\r\n redigerAendringsforslag,\r\n redigerIndberetning,\r\n redigerSagsakt,\r\n redigerSagsaktGeometri,\r\n skrivChatBesked,\r\n tagIndberetning,\r\n tagIndberetningFraSagsbehandler,\r\n uploadAendringsforslagGeometri,\r\n uploadFile,\r\n uploadSagsaktFil,\r\n uploadSagsaktGeometri,\r\n videresendIndberetning,\r\n};\r\n","import { FipLayer } from \"interfaces/FipLayer\";\r\nimport {\r\n topoSkærmkort,\r\n stednavnSagWMSLayer,\r\n geodanmark,\r\n ortofoto,\r\n kommunegrænser,\r\n adresser,\r\n matrikler,\r\n stednavneWMS,\r\n stednavneWFSLayer,\r\n} from \"./layers\";\r\n\r\nexport const baselayers: FipLayer[] = [\r\n {\r\n loading: false,\r\n maplayer: geodanmark,\r\n title: geodanmark.get(\"title\"),\r\n visible: true,\r\n },\r\n {\r\n loading: false,\r\n maplayer: topoSkærmkort,\r\n title: topoSkærmkort.get(\"title\"),\r\n visible: false,\r\n },\r\n {\r\n loading: false,\r\n maplayer: ortofoto,\r\n title: ortofoto.get(\"title\"),\r\n visible: false,\r\n },\r\n];\r\nexport const layers: FipLayer[] = [\r\n {\r\n loading: false,\r\n maplayer: kommunegrænser,\r\n title: kommunegrænser.get(\"title\"),\r\n visible: false,\r\n },\r\n // postdistrikter,\r\n // sogne,\r\n {\r\n loading: false,\r\n maplayer: adresser,\r\n title: adresser.get(\"title\"),\r\n visible: false,\r\n },\r\n {\r\n loading: false,\r\n maplayer: matrikler,\r\n title: matrikler.get(\"title\"),\r\n visible: false,\r\n },\r\n {\r\n loading: false,\r\n maplayer: stednavneWMS,\r\n title: stednavneWMS.get(\"title\"),\r\n visible: true,\r\n },\r\n {\r\n loading: false,\r\n maplayer: stednavneWFSLayer,\r\n title: stednavneWFSLayer.get(\"title\"),\r\n visible: false,\r\n },\r\n {\r\n loading: false,\r\n maplayer: stednavnSagWMSLayer,\r\n title: stednavnSagWMSLayer.get(\"title\"),\r\n visible: true,\r\n },\r\n];\r\n\r\nconst FipConfig = { baselayers, layers };\r\nexport default FipConfig;\r\n\r\ntype Kode = { id: number; name: string; className?: string };\r\n\r\nexport const statusStore: Kode[] = [\r\n { id: 1, name: \"Modtaget\", className: \"bg-success\" },\r\n { id: 2, name: \"Afsluttet\", className: \"bg-danger\" },\r\n { id: 3, name: \"Afventer indberetter\", className: \"bg-warning\" },\r\n { id: 4, name: \"Afventer anden myndighed\", className: \"bg-warning\" },\r\n { id: 5, name: \"Under behandling\", className: \"bg-success\" },\r\n { id: 10, name: \"Oprettet\", className: \"bg-primary\" },\r\n { id: 11, name: \"Behandling PD\", className: \"bg-warning\" },\r\n { id: 12, name: \"I høring\", className: \"bg-horing\" },\r\n { id: 13, name: \"Behandling GST\", className: \"bg-warning\" },\r\n { id: 14, name: \"Klarmeldt til DagiSys\", className: \"bg-warning\" },\r\n { id: 15, name: \"Afsluttet GST\", className: \"bg-danger\" },\r\n { id: 16, name: \"Afsluttet\", className: \"bg-danger\" },\r\n { id: 20, name: \"Klarmeldt til SDSYS\", className: \"bg-warning\" },\r\n { id: 21, name: \"Overført til SDSYS\", className: \"bg-horing\" },\r\n];\r\n\r\nexport const rolleStore: Kode[] = [\r\n { id: 0, name: \"Anonym\" },\r\n { id: 1, name: \"Indberetter\" },\r\n { id: 2, name: \"Sagsbehandler\" },\r\n { id: 3, name: \"Høringsansvarlig\" },\r\n { id: 4, name: \"Høringspart\" },\r\n { id: 5, name: \"Høringsansvarlig\" },\r\n];\r\n\r\nexport const prioritetStore: Kode[] = [\r\n { id: -1, name: \"Ikke prioriteret\" },\r\n { id: 0, name: \"Ikke prioriteret\" },\r\n { id: 1, name: \"Lav\" },\r\n { id: 2, name: \"Mellem\" },\r\n { id: 3, name: \"Høj\" },\r\n];\r\n\r\n/**\r\n * StednavneIPs interne nummerering og tekster, der benyttes i dropdown i UI\r\n */\r\nexport const Kategori = [\r\n { value: 3100, label: \"Bebyggelse\" },\r\n //{ value: 6323, text: \"Begravelsesplads\" },\r\n { value: 4000, label: \"Bygning\" },\r\n { value: 5400, label: \"Fortidsminde\" },\r\n //{ value: 5520, text: \"Friluftsbad\" },\r\n //{ value: 2459, text: \"Færgerute\" },\r\n { value: 5510, label: \"Idrætsanlæg\" },\r\n { value: 6200, label: \"Landskabsform\" },\r\n //{ value: 2500, text: \"Lufthavn\" },\r\n { value: 6100, label: \"Naturareal\" },\r\n //{ value: 2460, text: \"Navigationsanlæg\" },\r\n //{ value: 7100, text: \"Farvand\" },\r\n { value: 7219, label: \"Sø\" },\r\n { value: 7310, label: \"Vandløb\" },\r\n { value: 9999, label: \"Andet\" },\r\n];\r\n\r\n/**\r\n * mapning mellem tekster fra Geosearh og StednavneIPs interne nummerering\r\n */\r\nexport const KategoriServiceMapning = [\r\n { value: 3100, label: \"bebyggelser\" },\r\n //{ value: 6323, text: \"begravelsesplads\" },\r\n { value: 4000, label: \"bygning\" },\r\n { value: 5400, label: \"fortidsminde\" },\r\n //{ value: 5520, text: \"friluftsbad\" },\r\n //{ value: 2459, text: \"faergerute\" },\r\n { value: 5510, label: \"idraetsanlæg\" },\r\n { value: 6200, label: \"landskabsform\" },\r\n //{ value: 2500, text: \"lufthavn\" },\r\n { value: 6100, label: \"naturareal\" },\r\n //{ value: 2460, text: \"navigationsanlæg\" },\r\n //{ value: 7100, text: \"farvand\" },\r\n { value: 7219, label: \"soe\" },\r\n { value: 7310, label: \"vandloeb\" },\r\n];\r\n\r\nexport const filtersForRolle: {\r\n rolleId: number;\r\n filterValues: number[];\r\n}[] = [\r\n { rolleId: 0, filterValues: [0, 9] }, // Gæst\r\n { rolleId: 1, filterValues: [0, 3, 4, 6, 9] }, // Indberetter\r\n { rolleId: 2, filterValues: [0, 2, 3, 4, 5, 6, 9] }, // Sagsbehandler\r\n];\r\n\r\nexport function getFilterValuesByRolleId(rolleId: number) {\r\n const filter = filtersForRolle.find((f) => f.rolleId === rolleId);\r\n return filter ? filter : filtersForRolle[0];\r\n}\r\n","export default function ChevronLeft(props: { class?: string }) {\r\n const classNames = props.class ? `${props.class} bi` : \"bi bi-chevron-left\";\r\n return (\r\n \r\n \r\n \r\n );\r\n}\r\n","import {\r\n Hoeringssag,\r\n Ressource,\r\n RessourceRolleIdEnum,\r\n statusIdEnum,\r\n} from \"interfaces/IIndberetning\";\r\nimport Section from \"../../Section\";\r\nimport { useContext } from \"react\";\r\nimport { Bruger } from \"context/AuthProvider\";\r\nimport { isIndberetningMine } from \"routes/Fip/FipIndberetning\";\r\nimport { ModalContext } from \"../../Modal/Modal\";\r\nimport PromptModal from \"../PromptModal\";\r\nimport { baseUrl } from \"api\";\r\nimport { getDownloadGeometryLink } from \"routes/Fip/fipUtil\";\r\n// import AfslutIndberetning from \"./AfslutIndberetningModal\";\r\nimport AfslutIndberetningModal from \"../AfslutIndberetningModal\";\r\nimport { SagsbehandlingApi } from \"api/interfaces\";\r\nimport { putIndberetningSDSYS } from \"api/stednavn\";\r\nimport VideresendIndberetningModal from \"../Fip/VideresendIndberetningModal\";\r\n\r\ninterface IStednavnSagsbehandlerfunktionerProps {\r\n currentUser: Bruger;\r\n indberetning: Hoeringssag;\r\n setIndberetning: Function;\r\n cancelDrawingAndUploadFile: () => void;\r\n sagsbehandlingApi: SagsbehandlingApi;\r\n}\r\n\r\nexport default function StednavnSagsbehandlerfunktioner(\r\n props: IStednavnSagsbehandlerfunktionerProps\r\n) {\r\n const {\r\n currentUser,\r\n indberetning,\r\n setIndberetning,\r\n cancelDrawingAndUploadFile,\r\n sagsbehandlingApi,\r\n } = props;\r\n const { showModal } = useContext(ModalContext);\r\n const { statusId } = indberetning;\r\n const {\r\n afslutIndberetning,\r\n getIndberetning,\r\n tagIndberetning,\r\n tagIndberetningFraSagsbehandler,\r\n } = sagsbehandlingApi;\r\n const indberetningIsAfsluttet =\r\n statusId === statusIdEnum.afsluttet ? true : false;\r\n //const indberetningIsHoeringssag =\r\n // statusId === statusIdEnum.iHoering ? true : false;\r\n return (\r\n \r\n \r\n
\r\n
Sagsbehandlerfunktioner \r\n
Foretag ændringer eller tilføjelser til indberetningen.
\r\n
\r\n \r\n {\r\n cancelDrawingAndUploadFile();\r\n showModal({\r\n title: \"Tag indberetning\",\r\n content: (\r\n