= ({ cases, loading = false, testid }) => {
appealCaseNumber={column.appealCaseNumber}
/>
-
+ |
|
diff --git a/apps/judicial-system/web/src/components/Table/Table.css.ts b/apps/judicial-system/web/src/components/Table/Table.css.ts
index df3f49d234ab..f3d806282e21 100644
--- a/apps/judicial-system/web/src/components/Table/Table.css.ts
+++ b/apps/judicial-system/web/src/components/Table/Table.css.ts
@@ -2,14 +2,9 @@ import { globalStyle, style } from '@vanilla-extract/css'
import { theme } from '@island.is/island-ui/theme'
-export const header = style({
- background: theme.color.blue100,
-})
-
export const table = style({
borderSpacing: 0,
borderCollapse: 'collapse',
- overflow: 'hidden',
// Needed for Safari.
width: '100%',
@@ -46,30 +41,14 @@ export const largeColumn = style({
},
},
})
-export const blockColumn = style({
- display: 'block',
- overflow: 'hidden',
- textOverflow: 'ellipsis',
-})
-export const deleteButtonContainer = style({
- maxWidth: '0',
- height: '100%',
- padding: 0,
- transform: 'translate3d(2px, 0px, 0px)',
-})
-
-export const td = style({
- selectors: {
- [`&:not(${deleteButtonContainer})`]: {
- padding: `${theme.spacing[2]}px ${theme.spacing[3]}px`,
- },
- '&.secondLast': {
- marginLeft: 'auto',
- height: '100%',
- padding: 0,
- },
- },
+export const smallContainer = style({
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'center',
+ width: '34px',
+ height: '34px',
+ marginLeft: 'auto',
})
globalStyle(`${table} td, th`, {
@@ -83,11 +62,6 @@ globalStyle(`${table} td, th`, {
textAlign: 'left',
})
-export const expandLabel = style({
- color: theme.color.blue400,
- cursor: 'pointer',
-})
-
export const row = style({
cursor: 'pointer',
})
diff --git a/apps/judicial-system/web/src/components/Table/Table.tsx b/apps/judicial-system/web/src/components/Table/Table.tsx
index 51abbc83881f..eefb4522490c 100644
--- a/apps/judicial-system/web/src/components/Table/Table.tsx
+++ b/apps/judicial-system/web/src/components/Table/Table.tsx
@@ -8,7 +8,7 @@ import React, {
import { useIntl } from 'react-intl'
import { useLocalStorage } from 'react-use'
import parseISO from 'date-fns/parseISO'
-import { AnimatePresence } from 'framer-motion'
+import { AnimatePresence, motion } from 'framer-motion'
import { Box, Text } from '@island.is/island-ui/core'
import { theme } from '@island.is/island-ui/theme'
@@ -126,7 +126,7 @@ const Table: FC = (props) => {
}
}, [data, sortConfig])
- return width < theme.breakpoints.md ? (
+ return width < theme.breakpoints.lg ? (
<>
{data.map((theCase: CaseListEntry) => (
@@ -205,30 +205,46 @@ const Table: FC = (props) => {
data-testid="tableRow"
>
{columns.map((td) => (
-
- {td.cell(row)}
- |
+ {td.cell(row)} |
))}
{generateContextMenuItems && (
-
+ |
{generateContextMenuItems(row).length > 0 && (
-
+
{isOpeningCaseId === row.id && showLoading ? (
-
+
-
+
) : (
{
evt.stopPropagation()
}}
- />
+ >
+
+
}
/>
)}
diff --git a/apps/judicial-system/web/src/components/Table/TableSkeleton/TableSkeleton.tsx b/apps/judicial-system/web/src/components/Table/TableSkeleton/TableSkeleton.tsx
index 7b99b7e0f664..4c850a5c28da 100644
--- a/apps/judicial-system/web/src/components/Table/TableSkeleton/TableSkeleton.tsx
+++ b/apps/judicial-system/web/src/components/Table/TableSkeleton/TableSkeleton.tsx
@@ -52,122 +52,122 @@ const TableSkeleton = () => {
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
-
+ |
|
diff --git a/apps/judicial-system/web/src/components/index.ts b/apps/judicial-system/web/src/components/index.ts
index dc835ddff6c7..b7e8a1e97e8e 100644
--- a/apps/judicial-system/web/src/components/index.ts
+++ b/apps/judicial-system/web/src/components/index.ts
@@ -10,6 +10,7 @@ export {
default as CheckboxList,
type CheckboxInfo,
} from './CheckboxList/CheckboxList'
+export { default as ConnectedCaseFilesAccordionItem } from './AccordionItems/ConnectedCaseFilesAccordionItem/ConnectedCaseFilesAccordionItem'
export { default as CommentsAccordionItem } from './AccordionItems/CommentsAccordionItem/CommentsAccordionItem'
export { default as ConclusionDraft } from './ConclusionDraft/ConclusionDraft'
export { default as ContextMenu } from './ContextMenu/ContextMenu'
diff --git a/apps/judicial-system/web/src/routes/Court/Indictments/Conclusion/Conclusion.strings.ts b/apps/judicial-system/web/src/routes/Court/Indictments/Conclusion/Conclusion.strings.ts
index 9c4a47021732..e8ef5f5ff537 100644
--- a/apps/judicial-system/web/src/routes/Court/Indictments/Conclusion/Conclusion.strings.ts
+++ b/apps/judicial-system/web/src/routes/Court/Indictments/Conclusion/Conclusion.strings.ts
@@ -145,4 +145,9 @@ export const strings = defineMessages({
description:
'Notaður sem skýritexti í tegund þinghalds valkosti á Niðurstaða skrefi.',
},
+ connectedCaseNumbersTitle: {
+ id: 'judicial.system.core:court.indictments.conclusion.connected_case_numbers_title',
+ defaultMessage: 'Málsnúmer',
+ description: 'Notaður sem titill á tengd mál textabox á Niðurstaða skrefi.',
+ },
})
diff --git a/apps/judicial-system/web/src/routes/Court/Indictments/Conclusion/Conclusion.tsx b/apps/judicial-system/web/src/routes/Court/Indictments/Conclusion/Conclusion.tsx
index 6ef21ea0ca90..5df2c6e08162 100644
--- a/apps/judicial-system/web/src/routes/Court/Indictments/Conclusion/Conclusion.tsx
+++ b/apps/judicial-system/web/src/routes/Court/Indictments/Conclusion/Conclusion.tsx
@@ -40,6 +40,7 @@ import {
useUploadFiles,
} from '@island.is/judicial-system-web/src/utils/hooks'
+import SelectConnectedCase from './SelectConnectedCase'
import { strings } from './Conclusion.strings'
const courtSessionOptions = [
@@ -136,6 +137,11 @@ const Conclusion: FC = () => {
break
case IndictmentDecision.COMPLETING:
update.indictmentRulingDecision = selectedDecision
+ update.mergeCaseId =
+ selectedDecision === CaseIndictmentRulingDecision.MERGE
+ ? workingCase.mergeCase?.id
+ : null
+
break
case IndictmentDecision.REDISTRIBUTING:
update.judgeId = null
@@ -232,14 +238,21 @@ const Conclusion: FC = () => {
file.status === 'done',
)
)
- case CaseIndictmentRulingDecision.FINE:
case CaseIndictmentRulingDecision.CANCELLATION:
- case CaseIndictmentRulingDecision.MERGE:
+ case CaseIndictmentRulingDecision.FINE:
return uploadFiles.some(
(file) =>
file.category === CaseFileCategory.COURT_RECORD &&
file.status === 'done',
)
+ case CaseIndictmentRulingDecision.MERGE:
+ return Boolean(
+ uploadFiles.some(
+ (file) =>
+ file.category === CaseFileCategory.COURT_RECORD &&
+ file.status === 'done',
+ ) && workingCase.mergeCase?.id,
+ )
default:
return false
}
@@ -469,6 +482,19 @@ const Conclusion: FC = () => {
)}
+ {selectedDecision &&
+ selectedDecision === CaseIndictmentRulingDecision.MERGE && (
+
+
+
+
+ )}
{selectedAction && (
>
+}
+
+const SelectConnectedCase: FC = ({ workingCase, setWorkingCase }) => {
+ const { formatMessage } = useIntl()
+
+ const { data: connectedCasesData, loading: connectedCasesLoading } =
+ useConnectedCasesQuery({
+ variables: {
+ input: {
+ id: workingCase.id,
+ },
+ },
+ })
+
+ const setConnectedCase = async (connectedCaseId: string) => {
+ setWorkingCase((prevWorkingCase) => ({
+ ...prevWorkingCase,
+ mergeCase: {
+ id: connectedCaseId,
+ },
+ }))
+ }
+
+ const connectedCases = connectedCasesData?.connectedCases?.map((aCase) => ({
+ label: `${aCase.courtCaseNumber}`,
+ value: aCase.id,
+ })) as ConnectedCaseOption[]
+
+ // For now we only want to allow cases with a single defendant to be able to merge
+ // in to another case
+ const mergeAllowed = workingCase.defendants?.length === 1 ? true : false
+
+ const defaultConnectedCase = connectedCases?.find(
+ (connectedCase) =>
+ workingCase.mergeCase &&
+ connectedCase.value === workingCase.mergeCase?.id,
+ )
+
+ return !mergeAllowed ? (
+
+ ) : connectedCasesLoading ? (
+
+
+
+ ) : connectedCases?.length === 0 ? (
+
+ ) : (
+
)}
+ {workingCase.mergedCases &&
+ workingCase.mergedCases.length > 0 &&
+ workingCase.mergedCases.map((mergedCase) => (
+
+
+
+ ))}
{workingCase.caseFiles && (
diff --git a/apps/judicial-system/web/src/routes/Court/Indictments/Summary/Summary.strings.ts b/apps/judicial-system/web/src/routes/Court/Indictments/Summary/Summary.strings.ts
index f447c563536a..db4df0715552 100644
--- a/apps/judicial-system/web/src/routes/Court/Indictments/Summary/Summary.strings.ts
+++ b/apps/judicial-system/web/src/routes/Court/Indictments/Summary/Summary.strings.ts
@@ -39,9 +39,9 @@ export const strings = defineMessages({
description: 'Notaður sem texti í staðfestingarglugga um að mál sé lokið.',
},
indictmentRulingDecisionTagText: {
- id: 'judicial.system.core:indictments.summary.indictment_ruling_decision_tag_text',
+ id: 'judicial.system.core:indictments.summary.indictment_ruling_decision_tag_text_v2',
defaultMessage:
- '{indictmentRulingDecision, select, RULING {Dómur} FINE {Viðurlagaákvörðun} DISMISSAL {Frávísun} CANCELLATION {Niðurfelling} other {Lokið}}',
+ '{indictmentRulingDecision, select, RULING {Dómur} FINE {Viðurlagaákvörðun} DISMISSAL {Frávísun} CANCELLATION {Niðurfelling} MERGE {Sameinað} other {Lokið}}',
description: 'Notaður sem texti í TagCaseState til að birta úrskurð ákæru.',
},
})
diff --git a/apps/judicial-system/web/src/routes/Court/Indictments/Summary/Summary.tsx b/apps/judicial-system/web/src/routes/Court/Indictments/Summary/Summary.tsx
index d3e3cdab569f..3d5cddccdb9c 100644
--- a/apps/judicial-system/web/src/routes/Court/Indictments/Summary/Summary.tsx
+++ b/apps/judicial-system/web/src/routes/Court/Indictments/Summary/Summary.tsx
@@ -90,6 +90,7 @@ const Summary: FC = () => {
case CaseIndictmentRulingDecision.FINE:
return 'mint'
case CaseIndictmentRulingDecision.CANCELLATION:
+ case CaseIndictmentRulingDecision.MERGE:
return 'rose'
case CaseIndictmentRulingDecision.DISMISSAL:
return 'blue'
diff --git a/apps/judicial-system/web/src/routes/Shared/Cases/ActiveCases.strings.ts b/apps/judicial-system/web/src/routes/Shared/Cases/ActiveCases.strings.ts
deleted file mode 100644
index d3e123d46de1..000000000000
--- a/apps/judicial-system/web/src/routes/Shared/Cases/ActiveCases.strings.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { defineMessages } from 'react-intl'
-
-export const strings = defineMessages({
- postponed: {
- id: 'judicial.system.core:active_cases.postponed',
- defaultMessage: 'Frestað',
- description:
- 'Notaður í stað dagsetningar í töflum fyrir mál sem hefur verið frestað.',
- },
-})
diff --git a/apps/judicial-system/web/src/routes/Shared/Cases/ActiveCases.tsx b/apps/judicial-system/web/src/routes/Shared/Cases/ActiveCases.tsx
index 81929ed240ef..4e9046e60dc9 100644
--- a/apps/judicial-system/web/src/routes/Shared/Cases/ActiveCases.tsx
+++ b/apps/judicial-system/web/src/routes/Shared/Cases/ActiveCases.tsx
@@ -1,427 +1,114 @@
-import React, { FC, useEffect, useMemo, useState } from 'react'
+import React, { FC } from 'react'
import { useIntl } from 'react-intl'
-import { useLocalStorage } from 'react-use'
-import format from 'date-fns/format'
-import localeIS from 'date-fns/locale/is'
-import parseISO from 'date-fns/parseISO'
-import { AnimatePresence, LayoutGroup, motion } from 'framer-motion'
-import { Box, IconMapIcon, Text } from '@island.is/island-ui/core'
-import { theme } from '@island.is/island-ui/theme'
-import {
- capitalize,
- displayFirstPlusRemaining,
- formatDOB,
-} from '@island.is/judicial-system/formatters'
-import { isRequestCase } from '@island.is/judicial-system/types'
+import { capitalize } from '@island.is/judicial-system/formatters'
import { core, tables } from '@island.is/judicial-system-web/messages'
-import {
- ContextMenu,
- Modal,
- TagAppealState,
- TagCaseState,
-} from '@island.is/judicial-system-web/src/components'
-import { contextMenu as contextMenuStrings } from '@island.is/judicial-system-web/src/components/ContextMenu/ContextMenu.strings'
-import IconButton from '@island.is/judicial-system-web/src/components/IconButton/IconButton'
+import { TagCaseState } from '@island.is/judicial-system-web/src/components'
+import { useContextMenu } from '@island.is/judicial-system-web/src/components/ContextMenu/ContextMenu'
+import { contextMenu } from '@island.is/judicial-system-web/src/components/ContextMenu/ContextMenu.strings'
import {
ColumnCaseType,
+ CourtCaseNumber,
CourtDate,
- SortButton,
+ CreatedDate,
+ DefendantInfo,
} from '@island.is/judicial-system-web/src/components/Table'
-import { table as tableStrings } from '@island.is/judicial-system-web/src/components/Table/Table.strings'
-import {
- CaseListEntry,
- CaseState,
-} from '@island.is/judicial-system-web/src/graphql/schema'
-import {
- directionType,
- sortableTableColumn,
- SortConfig,
-} from '@island.is/judicial-system-web/src/types'
-import {
- useCaseList,
- useViewport,
-} from '@island.is/judicial-system-web/src/utils/hooks'
-import { compareLocaleIS } from '@island.is/judicial-system-web/src/utils/sortHelper'
-
-import MobileCase from './MobileCase'
-import { strings } from './ActiveCases.strings'
-import { cases as m } from './Cases.strings'
-import * as styles from './Cases.css'
+import Table from '@island.is/judicial-system-web/src/components/Table/Table'
+import { CaseListEntry } from '@island.is/judicial-system-web/src/graphql/schema'
interface Props {
cases: CaseListEntry[]
- isDeletingCase: boolean
- onDeleteCase?: (caseToDelete: CaseListEntry) => Promise
+ onContextMenuDeleteClick: (id: string) => void
}
-const ActiveCases: FC = ({ cases, isDeletingCase, onDeleteCase }) => {
+const ActiveCases: FC = (props) => {
+ const { cases, onContextMenuDeleteClick } = props
const { formatMessage } = useIntl()
- const { width } = useViewport()
- const [sortConfig, setSortConfig] = useLocalStorage(
- 'sortConfig',
- {
- column: 'courtDate',
- direction: 'descending',
- },
- )
- const { isOpeningCaseId, showLoading, handleOpenCase, LoadingIndicator } =
- useCaseList()
- const [displayCases, setDisplayCases] = useState([])
- const [modalVisible, setVisibleModal] = useState<'DELETE_CASE'>()
- // The id of the case that's about to be removed
- const [caseToRemove, setCaseToRemove] = useState()
-
- useEffect(() => {
- setDisplayCases(cases)
- }, [cases])
-
- useMemo(() => {
- if (cases && sortConfig) {
- cases.sort((a: CaseListEntry, b: CaseListEntry) => {
- const getColumnValue = (entry: CaseListEntry) => {
- if (
- sortConfig.column === 'defendants' &&
- entry.defendants &&
- entry.defendants.length > 0
- ) {
- return entry.defendants[0].name ?? ''
- }
- if (sortConfig.column === 'courtDate') {
- return entry.postponedIndefinitelyExplanation
- ? ''
- : entry.courtDate ?? ''
- }
- return entry.created
- }
- const compareResult = compareLocaleIS(
- getColumnValue(a),
- getColumnValue(b),
- )
-
- return sortConfig.direction === 'ascending'
- ? compareResult
- : -compareResult
- })
- }
- }, [cases, sortConfig])
-
- const requestSort = (column: sortableTableColumn) => {
- let d: directionType = 'ascending'
-
- if (
- sortConfig &&
- sortConfig.column === column &&
- sortConfig.direction === 'ascending'
- ) {
- d = 'descending'
- }
- setSortConfig({ column, direction: d })
- }
-
- const getClassNamesFor = (name: sortableTableColumn) => {
- if (!sortConfig) {
- return
- }
- return sortConfig.column === name ? sortConfig.direction : undefined
- }
+ const { openCaseInNewTabMenuItem } = useContextMenu()
- return width < theme.breakpoints.md ? (
- <>
- {displayCases.map((theCase: CaseListEntry) => (
-
- {
- handleOpenCase(theCase.id)
- }}
- theCase={theCase}
- isCourtRole={false}
- isLoading={isOpeningCaseId === theCase.id && showLoading}
- >
- {theCase.state &&
- theCase.state === CaseState.WAITING_FOR_CONFIRMATION && (
-
- {`${formatMessage(
- m.activeRequests.table.headers.prosecutor,
- )}: ${theCase.prosecutor?.name}`}
-
- )}
- {theCase.postponedIndefinitelyExplanation ? (
- {formatMessage(strings.postponed)}
- ) : (
- theCase.courtDate && (
-
- {`${formatMessage(tableStrings.hearing)} ${format(
- parseISO(theCase.courtDate),
- 'd.M.y',
- )} kl. ${format(parseISO(theCase.courtDate), 'kk:mm')}`}
-
- )
- )}
-
-
- ))}
- >
- ) : (
- <>
-
-
-
-
-
- {formatMessage(tables.caseNumber)}
-
- |
-
- requestSort('defendants')}
- sortAsc={getClassNamesFor('defendants') === 'ascending'}
- sortDes={getClassNamesFor('defendants') === 'descending'}
- isActive={sortConfig?.column === 'defendants'}
- dataTestid="accusedNameSortButton"
- />
- |
-
-
- {formatMessage(m.activeRequests.table.headers.type)}
-
- |
-
- requestSort('created')}
- sortAsc={getClassNamesFor('created') === 'ascending'}
- sortDes={getClassNamesFor('created') === 'descending'}
- isActive={sortConfig?.column === 'created'}
- dataTestid="createdAtSortButton"
- />
- |
-
-
- {formatMessage(tables.state)}
-
- |
-
- requestSort('courtDate')}
- sortAsc={getClassNamesFor('courtDate') === 'ascending'}
- sortDes={getClassNamesFor('courtDate') === 'descending'}
- isActive={sortConfig?.column === 'courtDate'}
- />
- |
- |
-
-
-
-
-
- {cases.map((c) => (
- {
- handleOpenCase(c.id)
- }}
- >
-
- {c.appealCaseNumber ? (
-
-
- {c.appealCaseNumber}
-
-
- {c.courtCaseNumber}
-
-
- {displayFirstPlusRemaining(c.policeCaseNumbers)}
-
-
- ) : c.courtCaseNumber ? (
- <>
-
- {c.courtCaseNumber}
-
-
- {displayFirstPlusRemaining(c.policeCaseNumbers)}
-
- >
- ) : (
-
- {displayFirstPlusRemaining(c.policeCaseNumbers) || '-'}
-
- )}
- |
-
- {c.defendants && c.defendants.length > 0 ? (
- <>
-
-
- {c.defendants[0].name ?? '-'}
-
-
- {c.defendants.length === 1 ? (
- (!c.defendants[0].noNationalId ||
- c.defendants[0].nationalId) && (
-
-
- {formatDOB(
- c.defendants[0].nationalId,
- c.defendants[0].noNationalId,
- )}
-
-
- )
- ) : (
-
- {`+ ${c.defendants.length - 1}`}
-
- )}
- >
- ) : (
- -
- )}
- |
-
-
- |
-
-
- {format(parseISO(c.created ?? ''), 'd.M.y', {
- locale: localeIS,
- })}
-
- |
-
-
-
-
- {c.appealState && (
-
- )}
- |
-
-
- |
-
-
- {isOpeningCaseId === c.id && showLoading ? (
-
-
-
- ) : (
- handleOpenCase(c.id, true),
- icon: 'open',
- },
- ...(isRequestCase(c.type) ||
- c.state === CaseState.DRAFT ||
- c.state === CaseState.WAITING_FOR_CONFIRMATION
- ? [
- {
- title: formatMessage(
- contextMenuStrings.deleteCase,
- ),
- onClick: () => {
- setCaseToRemove(c)
- setVisibleModal('DELETE_CASE')
- },
- icon: 'trash' as IconMapIcon,
- },
- ]
- : []),
- ]}
- disclosure={
- {
- evt.stopPropagation()
- }}
- />
- }
- />
- )}
-
- |
-
- ))}
-
-
-
-
- {modalVisible === 'DELETE_CASE' && (
- {
- if (onDeleteCase && caseToRemove) {
- await onDeleteCase(caseToRemove)
- setDisplayCases((prev) =>
- prev.filter((c) => c.id !== caseToRemove.id),
- )
- setCaseToRemove(undefined)
- setVisibleModal(undefined)
- }
- }}
- onSecondaryButtonClick={() => {
- setVisibleModal(undefined)
- }}
- primaryButtonText={formatMessage(
- m.activeRequests.deleteCaseModal.primaryButtonText,
- )}
- primaryButtonColorScheme="destructive"
- secondaryButtonText={formatMessage(
- m.activeRequests.deleteCaseModal.secondaryButtonText,
- )}
- isPrimaryButtonLoading={isDeletingCase}
- />
- )}
- >
+ return (
+ {
+ return [
+ openCaseInNewTabMenuItem(row.id),
+ {
+ title: formatMessage(contextMenu.deleteCase),
+ onClick: () => {
+ onContextMenuDeleteClick(row.id)
+ },
+ icon: 'trash',
+ },
+ ]
+ }}
+ columns={[
+ {
+ cell: (row) => (
+
+ ),
+ },
+ {
+ cell: (row) => ,
+ },
+ {
+ cell: (row) => ,
+ },
+ {
+ cell: (row) => ,
+ },
+ {
+ cell: (row) => (
+
+ ),
+ },
+ {
+ cell: (row) => (
+
+ ),
+ },
+ ]}
+ />
)
}
diff --git a/apps/judicial-system/web/src/routes/Shared/Cases/Cases.css.ts b/apps/judicial-system/web/src/routes/Shared/Cases/Cases.css.ts
index 527e5b175238..e7bb513aec33 100644
--- a/apps/judicial-system/web/src/routes/Shared/Cases/Cases.css.ts
+++ b/apps/judicial-system/web/src/routes/Shared/Cases/Cases.css.ts
@@ -19,15 +19,6 @@ export const filterContainer = style({
maxWidth: '432px',
})
-export const table = style({
- borderSpacing: 0,
- borderCollapse: 'collapse',
- overflow: 'hidden',
-
- // Needed for Safari.
- width: '100%',
-})
-
export const infoContainer = style({
marginBottom: theme.spacing[3],
@@ -37,85 +28,3 @@ export const infoContainer = style({
},
},
})
-
-export const thead = style({
- background: theme.color.blue100,
- textAlign: 'left',
-})
-
-export const thButton = style({
- outline: 'none',
-
- ':active': {
- color: theme.color.dark400,
- },
-})
-
-export const tableRowContainer = style({
- borderBottom: `1px solid ${theme.color.blue200}`,
- cursor: 'pointer',
- margin: `0 ${theme.spacing[2]}px`,
-})
-
-export const blockColumn = style({
- display: 'block',
- overflow: 'hidden',
- textOverflow: 'ellipsis',
-})
-
-export const th = style({
- padding: `${theme.spacing[2]}px 0`,
-
- selectors: {
- '&:first-child': {
- paddingLeft: theme.spacing[2],
- },
- },
-})
-
-export const td = style({
- padding: `${theme.spacing[2]}px 0`,
- selectors: {
- '&:first-child': {
- paddingLeft: theme.spacing[2],
- },
- },
-})
-
-export const deleteButtonWrapper = style({
- margin: '0 auto',
- padding: 10,
- width: 44,
- height: 44,
-})
-
-export const sortIcon = style({
- opacity: 0.4,
- transition: 'opacity .2s ease-in-out',
-
- selectors: {
- [`${thButton}:hover &`]: {
- opacity: 1,
- },
- },
-})
-
-export const sortCreatedAsc = style({
- opacity: 1,
- transform: 'rotate(180deg)',
-})
-
-export const sortCreatedDes = style({
- opacity: 1,
- transform: 'rotate(0deg)',
-})
-
-export const sortAccusedNameAsc = style({
- opacity: 1,
- transform: 'rotate(0deg)',
-})
-
-export const sortAccusedNameDes = style({
- opacity: 1,
- transform: 'rotate(180deg)',
-})
diff --git a/apps/judicial-system/web/src/routes/Shared/Cases/Cases.spec.tsx b/apps/judicial-system/web/src/routes/Shared/Cases/Cases.spec.tsx
index e4ccf3879de6..7da99096c234 100644
--- a/apps/judicial-system/web/src/routes/Shared/Cases/Cases.spec.tsx
+++ b/apps/judicial-system/web/src/routes/Shared/Cases/Cases.spec.tsx
@@ -205,9 +205,7 @@ describe('Cases', () => {
)
expect(
- await waitFor(
- () => screen.getAllByTestId('custody-cases-table-row').length,
- ),
+ await waitFor(() => screen.getAllByTestId('tableRow').length),
).toEqual(5)
})
@@ -243,9 +241,7 @@ describe('Cases', () => {
,
)
- expect(
- (await screen.findAllByTestId('custody-cases-table-row')).length,
- ).toEqual(5)
+ expect((await screen.findAllByTestId('tableRow')).length).toEqual(5)
})
})
@@ -323,9 +319,9 @@ describe('Cases', () => {
,
)
- await user.click(await screen.findByTestId('accusedNameSortButton'))
+ await user.click(await screen.findByTestId('defendantsSortButton'))
- const tableRows = await screen.findAllByTestId('custody-cases-table-row')
+ const tableRows = await screen.findAllByTestId('tableRow')
expect(tableRows[0]).toHaveTextContent('D. M. Kil')
expect(tableRows[1]).toHaveTextContent('Erlingur L Kristinsson')
@@ -349,9 +345,9 @@ describe('Cases', () => {
,
)
- await user.dblClick(await screen.findByTestId('accusedNameSortButton'))
+ await user.dblClick(await screen.findByTestId('defendantsSortButton'))
- const tableRows = await screen.findAllByTestId('custody-cases-table-row')
+ const tableRows = await screen.findAllByTestId('tableRow')
expect(tableRows[0]).toHaveTextContent('D. M. Kil')
expect(tableRows[1]).toHaveTextContent('Erlingur L Kristinsson')
@@ -375,9 +371,9 @@ describe('Cases', () => {
,
)
- await user.click(await screen.findByTestId('createdAtSortButton'))
+ await user.click(await screen.findByTestId('createdSortButton'))
- const tableRows = await screen.findAllByTestId('custody-cases-table-row')
+ const tableRows = await screen.findAllByTestId('tableRow')
expect(tableRows[0]).toHaveTextContent('Erlingur L Kristinsson')
expect(tableRows[1]).toHaveTextContent('Jon Harring Sr.')
@@ -401,9 +397,9 @@ describe('Cases', () => {
,
)
- await user.dblClick(await screen.findByTestId('createdAtSortButton'))
+ await user.dblClick(await screen.findByTestId('createdSortButton'))
- const tableRows = await screen.findAllByTestId('custody-cases-table-row')
+ const tableRows = await screen.findAllByTestId('tableRow')
expect(tableRows[0]).toHaveTextContent('Erlingur L Kristinsson')
expect(tableRows[1]).toHaveTextContent('Jon Harring Sr.')
diff --git a/apps/judicial-system/web/src/routes/Shared/Cases/Cases.strings.ts b/apps/judicial-system/web/src/routes/Shared/Cases/Cases.strings.ts
index 3bd539610055..131fd30f48df 100644
--- a/apps/judicial-system/web/src/routes/Shared/Cases/Cases.strings.ts
+++ b/apps/judicial-system/web/src/routes/Shared/Cases/Cases.strings.ts
@@ -16,33 +16,6 @@ export const cases = {
},
}),
activeRequests: {
- table: {
- headers: defineMessages({
- type: {
- id: 'judicial.system.core:cases.active_requests.table.headers.type',
- defaultMessage: 'Tegund',
- description:
- 'Notaður sem titill fyrir tegund dálk í lista yfir mál í vinnslu.',
- },
- date: {
- id: 'judicial.system.core:cases.active_requests.table.headers.date',
- defaultMessage: 'Stofnað/Fyrirtaka',
- description:
- 'Notaður sem titill fyrir dagsetningardálk í lista yfir óafgreidd mál í vinnslu.',
- },
- created: {
- id: 'judicial.system.core:cases.active_requests.table.headers.created',
- defaultMessage: 'Stofnað',
- description:
- 'Notaður sem titill fyrir dagsetningu í lista yfir óafgreidd mál í vinnslu.',
- },
- prosecutor: {
- id: 'judicial.system.core:cases.active_requests.table.headers.prosecutor',
- defaultMessage: 'Sækjandi',
- description: 'Notaður sem titill fyrir sækjanda í málalista.',
- },
- }),
- },
title: defineMessage({
id: 'judicial.system.core:cases.active_requests.title',
defaultMessage: 'Mál í vinnslu',
diff --git a/apps/judicial-system/web/src/routes/Shared/Cases/Cases.tsx b/apps/judicial-system/web/src/routes/Shared/Cases/Cases.tsx
index 90c4dd02d541..d84fc1a7a347 100644
--- a/apps/judicial-system/web/src/routes/Shared/Cases/Cases.tsx
+++ b/apps/judicial-system/web/src/routes/Shared/Cases/Cases.tsx
@@ -300,10 +300,7 @@ export const Cases: FC = () => {
{activeCases.length > 0 ? (
) : (
diff --git a/apps/judicial-system/web/src/routes/Shared/Cases/useFilter.spec.tsx b/apps/judicial-system/web/src/routes/Shared/Cases/useFilter.spec.tsx
index 2b1f8b3d554a..4986c47e99b9 100644
--- a/apps/judicial-system/web/src/routes/Shared/Cases/useFilter.spec.tsx
+++ b/apps/judicial-system/web/src/routes/Shared/Cases/useFilter.spec.tsx
@@ -4,7 +4,6 @@ import {
User,
UserRole,
} from '@island.is/judicial-system-web/src/graphql/schema'
-import { TempCase as Case } from '@island.is/judicial-system-web/src/types'
import { filterCases, FilterOption, filterOptionsForUser } from './useFilter'
diff --git a/apps/judicial-system/web/src/routes/Shared/SignedVerdictOverview/SignedVerdictOverview.tsx b/apps/judicial-system/web/src/routes/Shared/SignedVerdictOverview/SignedVerdictOverview.tsx
index 1288c0d39528..c552eb851fd7 100644
--- a/apps/judicial-system/web/src/routes/Shared/SignedVerdictOverview/SignedVerdictOverview.tsx
+++ b/apps/judicial-system/web/src/routes/Shared/SignedVerdictOverview/SignedVerdictOverview.tsx
@@ -719,7 +719,7 @@ export const SignedVerdictOverview: FC = () => {
onPrimaryButtonClick={() => setSharedCaseModal(undefined)}
/>
)}
-
+
{isModifyingDates && (
export type UpdateCase = Omit & {
@@ -66,6 +67,7 @@ const isChildKey = (key: keyof UpdateCaseInput): key is keyof ChildKeys => {
'appealJudge2Id',
'appealJudge3Id',
'indictmentReviewerId',
+ 'mergeCaseId',
].includes(key)
}
@@ -80,6 +82,7 @@ const childof: { [Property in keyof ChildKeys]-?: keyof Case } = {
appealJudge2Id: 'appealJudge2',
appealJudge3Id: 'appealJudge3',
indictmentReviewerId: 'indictmentReviewer',
+ mergeCaseId: 'mergeCase',
}
const overwrite = (update: UpdateCase): UpdateCase => {
diff --git a/apps/judicial-system/web/src/utils/hooks/useCase/updateCase.graphql b/apps/judicial-system/web/src/utils/hooks/useCase/updateCase.graphql
index a336f71e71c3..5e0cca32c647 100644
--- a/apps/judicial-system/web/src/utils/hooks/useCase/updateCase.graphql
+++ b/apps/judicial-system/web/src/utils/hooks/useCase/updateCase.graphql
@@ -221,5 +221,8 @@ mutation UpdateCase($input: UpdateCaseInput!) {
indictmentDeniedExplanation
indictmentReturnedExplanation
indictmentDecision
+ mergeCase {
+ id
+ }
}
}
diff --git a/apps/native/app/src/screens/applications/applications.tsx b/apps/native/app/src/screens/applications/applications.tsx
index 63723209843b..d3913a43d973 100644
--- a/apps/native/app/src/screens/applications/applications.tsx
+++ b/apps/native/app/src/screens/applications/applications.tsx
@@ -25,6 +25,7 @@ import { useConnectivityIndicator } from '../../hooks/use-connectivity-indicator
import { useBrowser } from '../../lib/useBrowser'
import { getApplicationOverviewUrl } from '../../utils/applications-utils'
import { testIDs } from '../../utils/test-ids'
+import { getRightButtons } from '../../utils/get-main-root'
import { ApplicationsModule } from '../home/applications-module'
import { isIos } from '../../utils/devices'
@@ -42,6 +43,7 @@ const { useNavigationOptions, getNavigationOptions } =
searchBar: {
visible: false,
},
+ rightButtons: initialized ? getRightButtons({ theme } as any) : [],
},
bottomTab: {
iconColor: theme.color.blue400,
@@ -98,6 +100,7 @@ export const ApplicationsScreen: NavigationFunctionComponent = ({
useConnectivityIndicator({
componentId,
+ rightButtons: getRightButtons(),
refetching,
queryResult: [applicationsRes, res],
})
diff --git a/apps/native/app/src/screens/home/home.tsx b/apps/native/app/src/screens/home/home.tsx
index 2d7d6b2b0500..4d9419420efb 100644
--- a/apps/native/app/src/screens/home/home.tsx
+++ b/apps/native/app/src/screens/home/home.tsx
@@ -47,9 +47,7 @@ const { useNavigationOptions, getNavigationOptions } =
createNavigationOptionHooks(
(theme, intl, initialized) => ({
topBar: {
- rightButtons: initialized
- ? getRightButtons({ screen: 'Home', theme: theme as any })
- : [],
+ rightButtons: initialized ? getRightButtons({ theme } as any) : [],
},
bottomTab: {
...({
@@ -107,7 +105,7 @@ export const MainHomeScreen: NavigationFunctionComponent = ({
useConnectivityIndicator({
componentId,
- rightButtons: getRightButtons({ screen: 'Home' }),
+ rightButtons: getRightButtons(),
queryResult: applicationsRes,
refetching,
})
diff --git a/apps/native/app/src/screens/inbox/inbox.tsx b/apps/native/app/src/screens/inbox/inbox.tsx
index 062b4e81c05d..be171b346367 100644
--- a/apps/native/app/src/screens/inbox/inbox.tsx
+++ b/apps/native/app/src/screens/inbox/inbox.tsx
@@ -42,6 +42,7 @@ import { navigateTo } from '../../lib/deep-linking'
import { useOrganizationsStore } from '../../stores/organizations-store'
import { useUiStore } from '../../stores/ui-store'
import { ComponentRegistry } from '../../utils/component-registry'
+import { getRightButtons } from '../../utils/get-main-root'
import { testIDs } from '../../utils/test-ids'
import { isAndroid } from '../../utils/devices'
import { useApolloClient } from '@apollo/client'
@@ -80,6 +81,7 @@ const { useNavigationOptions, getNavigationOptions } =
title: {
text: intl.formatMessage({ id: 'inbox.screenTitle' }),
},
+ rightButtons: initialized ? getRightButtons({ theme } as any) : [],
},
bottomTab: {
iconColor: theme.color.blue400,
@@ -240,6 +242,7 @@ export const InboxScreen: NavigationFunctionComponent<{
useConnectivityIndicator({
componentId,
+ rightButtons: getRightButtons(),
queryResult: res,
refetching: refetching || markAllAsReadLoading,
})
diff --git a/apps/native/app/src/screens/more/more.tsx b/apps/native/app/src/screens/more/more.tsx
index d2b30145ca0c..1d04d79c6441 100644
--- a/apps/native/app/src/screens/more/more.tsx
+++ b/apps/native/app/src/screens/more/more.tsx
@@ -44,9 +44,7 @@ const { useNavigationOptions, getNavigationOptions } =
title: {
text: intl.formatMessage({ id: 'profile.screenTitle' }),
},
- rightButtons: initialized
- ? getRightButtons({ screen: 'More', theme: theme as any })
- : [],
+ rightButtons: initialized ? getRightButtons({ theme } as any) : [],
},
bottomTab: {
iconColor: theme.color.blue400,
@@ -87,17 +85,11 @@ export const MoreScreen: NavigationFunctionComponent = ({ componentId }) => {
useConnectivityIndicator({
componentId,
- rightButtons: getRightButtons({ screen: 'More' }),
+ rightButtons: getRightButtons(),
})
useNavigationComponentDidAppear(() => {
setHiddenContent(false)
- // This is needed to make sure we show the settings icon on a cold boot
- Navigation.mergeOptions(componentId, {
- topBar: {
- rightButtons: getRightButtons({ screen: 'More' }),
- },
- })
}, componentId)
// Fix for a bug in react-native-navigation where the large title is not visible on iOS with bottom tabs https://github.com/wix/react-native-navigation/issues/6717
diff --git a/apps/native/app/src/screens/wallet/wallet.tsx b/apps/native/app/src/screens/wallet/wallet.tsx
index 92c34efb44c5..8f12cf32de5a 100644
--- a/apps/native/app/src/screens/wallet/wallet.tsx
+++ b/apps/native/app/src/screens/wallet/wallet.tsx
@@ -33,6 +33,7 @@ import { getRightButtons } from '../../utils/get-main-root'
import { isDefined } from '../../utils/is-defined'
import { testIDs } from '../../utils/test-ids'
import { WalletItem } from './components/wallet-item'
+import { ButtonRegistry } from '../../utils/component-registry'
type FlatListItem =
| GenericUserLicense
@@ -53,9 +54,15 @@ const { useNavigationOptions, getNavigationOptions } =
title: {
text: intl.formatMessage({ id: 'wallet.screenTitle' }),
},
- rightButtons: initialized
- ? getRightButtons({ screen: 'Wallet', theme: theme as any })
- : [],
+ rightButtons: initialized ? getRightButtons({ theme } as any) : [],
+ leftButtons: [
+ {
+ id: ButtonRegistry.ScanLicenseButton,
+ testID: testIDs.TOPBAR_SCAN_LICENSE_BUTTON,
+ icon: require('../../assets/icons/navbar-scan.png'),
+ color: theme.color.blue400,
+ },
+ ],
},
bottomTab: {
iconColor: theme.color.blue400,
@@ -127,7 +134,7 @@ export const WalletScreen: NavigationFunctionComponent = ({ componentId }) => {
useConnectivityIndicator({
componentId,
- rightButtons: getRightButtons({ screen: 'Wallet' }),
+ rightButtons: getRightButtons(),
queryResult: [res, resPassport],
refetching,
})
diff --git a/apps/native/app/src/utils/get-main-root.ts b/apps/native/app/src/utils/get-main-root.ts
index 1b0e9f120608..50296577a1e5 100644
--- a/apps/native/app/src/utils/get-main-root.ts
+++ b/apps/native/app/src/utils/get-main-root.ts
@@ -10,18 +10,14 @@ import {
import { getThemeWithPreferences } from './get-theme-with-preferences'
import { testIDs } from './test-ids'
-type Screen = 'Inbox' | 'Wallet' | 'Home' | 'Applications' | 'More'
-
type RightButtonProps = {
unseenCount?: number
theme?: ReturnType
- screen?: Screen
}
export const getRightButtons = ({
unseenCount = notificationsStore.getState().unseenCount,
theme = getThemeWithPreferences(preferencesStore.getState()),
- screen,
}: RightButtonProps = {}): OptionsTopBarButton[] => {
const iconBackground = {
color: 'transparent',
@@ -30,43 +26,25 @@ export const getRightButtons = ({
height: theme.spacing[4],
}
- switch (screen) {
- case 'Home':
- return [
- {
- accessibilityLabel: 'Notifications',
- id: ButtonRegistry.NotificationsButton,
- testID: testIDs.TOPBAR_NOTIFICATIONS_BUTTON,
- icon:
- unseenCount > 0
- ? require('../assets/icons/topbar-notifications-bell.png')
- : require('../assets/icons/topbar-notifications.png'),
- iconBackground,
- },
- ]
- case 'Wallet':
- return [
- {
- id: ButtonRegistry.ScanLicenseButton,
- testID: testIDs.TOPBAR_SCAN_LICENSE_BUTTON,
- icon: require('../assets/icons/navbar-scan.png'),
- color: theme.color.blue400,
- iconBackground,
- },
- ]
- case 'More':
- return [
- {
- accessibilityLabel: 'Settings',
- id: ButtonRegistry.SettingsButton,
- testID: testIDs.TOPBAR_SETTINGS_BUTTON,
- icon: require('../assets/icons/settings.png'),
- iconBackground,
- },
- ]
- default:
- return []
- }
+ return [
+ {
+ accessibilityLabel: 'Settings',
+ id: ButtonRegistry.SettingsButton,
+ testID: testIDs.TOPBAR_SETTINGS_BUTTON,
+ icon: require('../assets/icons/settings.png'),
+ iconBackground,
+ },
+ {
+ accessibilityLabel: 'Notifications',
+ id: ButtonRegistry.NotificationsButton,
+ testID: testIDs.TOPBAR_NOTIFICATIONS_BUTTON,
+ icon:
+ unseenCount > 0
+ ? require('../assets/icons/topbar-notifications-bell.png')
+ : require('../assets/icons/topbar-notifications.png'),
+ iconBackground,
+ },
+ ]
}
/**
diff --git a/apps/portals/admin/src/app/App.tsx b/apps/portals/admin/src/app/App.tsx
index 90c1a4d546e8..918f04a4307c 100644
--- a/apps/portals/admin/src/app/App.tsx
+++ b/apps/portals/admin/src/app/App.tsx
@@ -22,6 +22,7 @@ export const App = () => (
portalMeta={{
portalType: 'admin',
basePath: AdminPortalPaths.Base,
+ portalTitle: 'Stjórnborð - Ísland.is',
}}
/>
diff --git a/apps/reference-backend/README.md b/apps/reference-backend/README.md
index 38426cd06ee1..c51674d6727e 100644
--- a/apps/reference-backend/README.md
+++ b/apps/reference-backend/README.md
@@ -15,7 +15,7 @@ This project is used as reference for future backend project.
If your service or app needs external services like Postgres, ActiveMQ, etc. you can provision those using:
```bash
-docker-compose
+docker compose
```
Your local dev setup should be in a file named `docker-compose.yml`. If you are using those services as part of an integration or end-to-end tests you need to add them to the ci scripts.
diff --git a/apps/reference-backend/project.json b/apps/reference-backend/project.json
index 771d5abb6d70..44cc24043d46 100644
--- a/apps/reference-backend/project.json
+++ b/apps/reference-backend/project.json
@@ -63,7 +63,7 @@
"dev-services": {
"executor": "nx:run-commands",
"options": {
- "command": "docker-compose up -d",
+ "command": "docker compose up -d",
"cwd": "apps/reference-backend"
}
},
diff --git a/apps/service-portal/src/app/App.tsx b/apps/service-portal/src/app/App.tsx
index 49040397773c..c1cb0c1ec286 100644
--- a/apps/service-portal/src/app/App.tsx
+++ b/apps/service-portal/src/app/App.tsx
@@ -24,6 +24,7 @@ export const App = () => (
portalMeta={{
basePath: ServicePortalPaths.Base,
portalType: 'my-pages',
+ portalTitle: 'Mínar síður - Ísland.is',
}}
/>
diff --git a/apps/services/auth/ids-api/project.json b/apps/services/auth/ids-api/project.json
index 6a03a0f66fb7..cfefdd77acda 100644
--- a/apps/services/auth/ids-api/project.json
+++ b/apps/services/auth/ids-api/project.json
@@ -99,7 +99,7 @@
"dev-services": {
"executor": "nx:run-commands",
"options": {
- "command": "docker-compose up -d",
+ "command": "docker compose up -d",
"cwd": "apps/services/auth/ids-api"
}
},
diff --git a/apps/services/documents/project.json b/apps/services/documents/project.json
index dbaa504cc65e..afde09fce406 100644
--- a/apps/services/documents/project.json
+++ b/apps/services/documents/project.json
@@ -61,7 +61,7 @@
"dev-services": {
"executor": "nx:run-commands",
"options": {
- "command": "docker-compose up -d",
+ "command": "docker compose up -d",
"cwd": "apps/services/documents"
}
},
diff --git a/apps/services/endorsements/api/infra/endorsement-system-api.ts b/apps/services/endorsements/api/infra/endorsement-system-api.ts
index 33e2dc2ba6ce..c7d794069fe1 100644
--- a/apps/services/endorsements/api/infra/endorsement-system-api.ts
+++ b/apps/services/endorsements/api/infra/endorsement-system-api.ts
@@ -45,3 +45,50 @@ export const serviceSetup =
.xroad(Base, Client, NationalRegistry, NationalRegistryB2C)
.liveness('/liveness')
.readiness('/liveness')
+
+const serviceName = 'endorsement-system-api'
+const serviceCleanupWorkerName = `${serviceName}-cleanup-worker`
+export const endorsementSystemCleanUpWorkerSetup = (): ServiceBuilder<
+ typeof serviceCleanupWorkerName
+> =>
+ service(serviceCleanupWorkerName)
+ .image('services-endorsements-api')
+ .namespace('endorsement-system')
+ .serviceAccount(serviceCleanupWorkerName)
+ .command('node')
+ .args('--no-experimental-fetch', 'main.js', '--job=cleanup')
+ .db({ name: 'services-endorsements-api' })
+ .migrations()
+ .env({
+ EMAIL_REGION: 'eu-west-1',
+ EMAIL_FROM_NAME: {
+ dev: 'devland.is',
+ staging: 'devland.is',
+ prod: 'island.is',
+ },
+ EMAIL_FROM_ADDRESS: {
+ dev: 'development@island.is',
+ staging: 'development@island.is',
+ prod: 'noreply@island.is',
+ },
+ IDENTITY_SERVER_ISSUER_URL: {
+ dev: 'https://identity-server.dev01.devland.is',
+ staging: 'https://identity-server.staging01.devland.is',
+ prod: 'https://innskra.island.is',
+ },
+ IDENTITY_SERVER_CLIENT_ID: '@island.is/clients/endorsement',
+ })
+ .secrets({
+ IDENTITY_SERVER_CLIENT_SECRET:
+ '/k8s/endorsement-system-api/IDS-shared-secret',
+ NATIONAL_REGISTRY_B2C_CLIENT_SECRET:
+ '/k8s/api/NATIONAL_REGISTRY_B2C_CLIENT_SECRET',
+ })
+ .xroad(Base, Client, NationalRegistry, NationalRegistryB2C)
+ .liveness('/liveness')
+ .readiness('/liveness')
+ .extraAttributes({
+ dev: { schedule: '@hourly' },
+ staging: { schedule: '@hourly' },
+ prod: { schedule: '@hourly' },
+ })
diff --git a/apps/services/endorsements/api/project.json b/apps/services/endorsements/api/project.json
index bc645e6bc495..d4de95faa3ab 100644
--- a/apps/services/endorsements/api/project.json
+++ b/apps/services/endorsements/api/project.json
@@ -50,6 +50,13 @@
"buildTarget": "services-endorsements-api:build"
}
},
+ "cleanup": {
+ "executor": "@nx/js:node",
+ "options": {
+ "buildTarget": "services-endorsements-api:build",
+ "args": ["--job", "cleanup"]
+ }
+ },
"lint": {
"executor": "@nx/eslint:lint"
},
@@ -64,7 +71,7 @@
"dev-services": {
"executor": "nx:run-commands",
"options": {
- "command": "docker-compose up -d --build",
+ "command": "docker compose up -d --build",
"cwd": "apps/services/endorsements/api"
}
},
diff --git a/apps/services/endorsements/api/src/app/cleanup/worker.module.ts b/apps/services/endorsements/api/src/app/cleanup/worker.module.ts
new file mode 100644
index 000000000000..20a449a46a34
--- /dev/null
+++ b/apps/services/endorsements/api/src/app/cleanup/worker.module.ts
@@ -0,0 +1,30 @@
+import { Module } from '@nestjs/common'
+import { SequelizeModule } from '@nestjs/sequelize'
+import { LoggingModule } from '@island.is/logging'
+import { EndorsementSystemCleanupWorkerService } from './worker.service'
+
+import { Endorsement } from '../modules/endorsement/models/endorsement.model'
+import { SequelizeConfigService } from '../sequelizeConfig.service'
+import {
+ NationalRegistryV3ClientConfig,
+ NationalRegistryV3ClientModule,
+} from '@island.is/clients/national-registry-v3'
+import { ConfigModule } from '@nestjs/config'
+import { IdsClientConfig, XRoadConfig } from '@island.is/nest/config'
+
+@Module({
+ imports: [
+ LoggingModule,
+ SequelizeModule.forRootAsync({
+ useClass: SequelizeConfigService,
+ }),
+ SequelizeModule.forFeature([Endorsement]),
+ NationalRegistryV3ClientModule,
+ ConfigModule.forRoot({
+ isGlobal: true,
+ load: [NationalRegistryV3ClientConfig, IdsClientConfig, XRoadConfig],
+ }),
+ ],
+ providers: [EndorsementSystemCleanupWorkerService],
+})
+export class EndorsementSystemCleanupWorkerModule {}
diff --git a/apps/services/endorsements/api/src/app/cleanup/worker.service.ts b/apps/services/endorsements/api/src/app/cleanup/worker.service.ts
new file mode 100644
index 000000000000..7b8bec1b6b2d
--- /dev/null
+++ b/apps/services/endorsements/api/src/app/cleanup/worker.service.ts
@@ -0,0 +1,79 @@
+import { Inject, Injectable } from '@nestjs/common'
+import { LOGGER_PROVIDER } from '@island.is/logging'
+import type { Logger } from '@island.is/logging'
+import { InjectModel } from '@nestjs/sequelize'
+import { Endorsement } from '../modules/endorsement/models/endorsement.model'
+import { Op } from 'sequelize'
+import { NationalRegistryV3ClientService } from '@island.is/clients/national-registry-v3'
+
+@Injectable()
+export class EndorsementSystemCleanupWorkerService {
+ constructor(
+ @Inject(LOGGER_PROVIDER)
+ private readonly logger: Logger,
+ @InjectModel(Endorsement)
+ private readonly endorsementModel: typeof Endorsement,
+ private readonly nationalRegistryApiV3: NationalRegistryV3ClientService,
+ ) {}
+
+ public async run() {
+ await this.fixLocality()
+ }
+
+ async fixLocality() {
+ this.logger.info('Cleanup worker starting...')
+ // Find all rows with COUNTRY_CODE as locality value
+ const rows = await this.endorsementModel.findAll({
+ where: {
+ created: {
+ //filtering rows created after May 6th this year
+ [Op.gt]: new Date(new Date().getFullYear(), 4, 6),
+ },
+ meta: {
+ locality: {
+ [Op.regexp]: '^[A-Z]{2}$',
+ },
+ },
+ },
+ })
+ this.logger.info(`Found ${rows.length} rows with invalid locality`)
+ // Loop through rows and fix the locality value
+ for (const row of rows) {
+ this.logger.info(`Proccessing row id:${row.id}`)
+ try {
+ const person = await this.nationalRegistryApiV3.getAllDataIndividual(
+ row.endorser,
+ )
+ if (person) {
+ const oldLocality = row.meta.locality
+ const newLocality = person?.heimilisfang?.sveitarfelag || ''
+ const newMeta = {
+ ...row.meta,
+ locality: newLocality,
+ }
+ try {
+ await this.endorsementModel.update(
+ { meta: newMeta },
+ { where: { id: row.id } },
+ )
+ this.logger.info(
+ `Fixed locality for row id:${row.id} from ${oldLocality} to ${newLocality}`,
+ )
+ } catch (error) {
+ this.logger.error(
+ `Error fixing locality for row id:${row.id} from ${oldLocality} to ${newLocality}`,
+ )
+ }
+ } else {
+ this.logger.error(
+ `Person not found in national registry for row id:${row.id}`,
+ )
+ }
+ } catch (error) {
+ this.logger.error(
+ `Error fixing locality for row id:${row.id} locality ${row.meta.locality}`,
+ )
+ }
+ }
+ }
+}
diff --git a/apps/services/endorsements/api/src/app/modules/endorsement/endorsement.service.ts b/apps/services/endorsements/api/src/app/modules/endorsement/endorsement.service.ts
index 9c59d6eb29bf..4292d78f5e94 100644
--- a/apps/services/endorsements/api/src/app/modules/endorsement/endorsement.service.ts
+++ b/apps/services/endorsements/api/src/app/modules/endorsement/endorsement.service.ts
@@ -129,7 +129,7 @@ export class EndorsementService {
endorsementListId: endorsementList.id,
meta: {
fullName: person?.fulltNafn?.fulltNafn,
- locality: person?.rikisfang?.rikisfangKodi,
+ locality: person?.heimilisfang?.sveitarfelag,
showName,
},
}
diff --git a/apps/services/endorsements/api/src/cleanup.ts b/apps/services/endorsements/api/src/cleanup.ts
new file mode 100644
index 000000000000..268c8579d3a5
--- /dev/null
+++ b/apps/services/endorsements/api/src/cleanup.ts
@@ -0,0 +1,13 @@
+import { NestFactory } from '@nestjs/core'
+import { EndorsementSystemCleanupWorkerModule } from './app/cleanup/worker.module'
+import { EndorsementSystemCleanupWorkerService } from './app/cleanup/worker.service'
+
+export const cleanup = async () => {
+ const app = await NestFactory.createApplicationContext(
+ EndorsementSystemCleanupWorkerModule,
+ )
+ app.enableShutdownHooks()
+ await app.get(EndorsementSystemCleanupWorkerService).run()
+ await app.close()
+ process.exit(0)
+}
diff --git a/apps/services/endorsements/api/src/main.ts b/apps/services/endorsements/api/src/main.ts
index 8f94fbafe7ef..7f122924ba2f 100644
--- a/apps/services/endorsements/api/src/main.ts
+++ b/apps/services/endorsements/api/src/main.ts
@@ -1,9 +1,13 @@
-import { bootstrap } from '@island.is/infra-nest-server'
+import { bootstrap, processJob } from '@island.is/infra-nest-server'
import { AppModule } from './app/app.module'
import { environment } from './environments'
import { openApi } from './openApi'
-if (require.main === module || !environment.production) {
+const job = processJob()
+
+if (job === 'cleanup') {
+ import('./cleanup').then((app) => app.cleanup())
+} else if (require.main === module || !environment.production) {
bootstrap({
appModule: AppModule,
name: 'services-endorsements-api',
diff --git a/apps/services/regulations-admin-backend/project.json b/apps/services/regulations-admin-backend/project.json
index c16cbe8dd104..09c1c3522842 100644
--- a/apps/services/regulations-admin-backend/project.json
+++ b/apps/services/regulations-admin-backend/project.json
@@ -66,7 +66,7 @@
"dev-services": {
"executor": "nx:run-commands",
"options": {
- "command": "docker-compose up -d",
+ "command": "docker compose up -d",
"cwd": "apps/services/regulations-admin-backend"
}
},
diff --git a/apps/services/search-indexer/dev-services/README.md b/apps/services/search-indexer/dev-services/README.md
index 08c44ca6d0b5..5cda44f3ef96 100644
--- a/apps/services/search-indexer/dev-services/README.md
+++ b/apps/services/search-indexer/dev-services/README.md
@@ -2,7 +2,7 @@
### Dependencies
-You must have `docker` and `docker-compose` installed and running on you machine.
+You must have `docker` and `docker compose` installed and running on you machine.
**Docker must be given 4gb+ of ram**
### Start the server
@@ -11,7 +11,7 @@ You must have `docker` and `docker-compose` installed and running on you machine
yarn dev-services services-search-indexer
```
-In about 30 seconds
+In about 30 seconds
You should have Elasticsearch running on `localhost:9200`
And Kibana running on port `localhost:5601`
@@ -33,7 +33,19 @@ yarn nx run services-search-indexer:migrate
### Nice to know
+#### Dictionaries
+
Dictionaries for icelandic are pulled into the elastic docker container on build under `analyzers/`
The index template is not imported automagically so you must insert them manually...for now
There is no unseen functionality here, these dockerfiles are **not used in production**,
so if you add a plug to this docker file you must make sure it is also added to required deployments
+
+#### Local errors
+
+In case you see a `TOO_MANY_REQUESTS/12/disk usage exceeded flood-stage watermark, index has read-only-allow-delete block` error in your local terminal, you can allow more disk usage with the following commands:
+
+`curl -XPUT -H "Content-Type: application/json" http://localhost:9200/_cluster/settings -d '{ "transient": { "cluster.routing.allocation.disk.threshold_enabled": false } }'`
+
+`curl -XPUT -H "Content-Type: application/json" http://localhost:9200/_all/_settings -d '{"index.blocks.read_only_allow_delete": null}'`
+
+Source: [Stack Overflow](https://stackoverflow.com/questions/63880017/elasticsearch-docker-flood-stage-disk-watermark-95-exceeded#answer-63881121)
diff --git a/apps/services/search-indexer/project.json b/apps/services/search-indexer/project.json
index 948ddfd445c0..5541e3b453fe 100644
--- a/apps/services/search-indexer/project.json
+++ b/apps/services/search-indexer/project.json
@@ -46,7 +46,7 @@
"dev-services": {
"executor": "nx:run-commands",
"options": {
- "command": "docker-compose -f docker-compose.yml up -d --build",
+ "command": "docker compose -f docker-compose.yml up -d --build",
"cwd": "apps/services/search-indexer/dev-services"
}
},
diff --git a/apps/services/search-indexer/webpack.config.js b/apps/services/search-indexer/webpack.config.js
index 369feed7acd3..06cadb76f5e6 100644
--- a/apps/services/search-indexer/webpack.config.js
+++ b/apps/services/search-indexer/webpack.config.js
@@ -1,9 +1,10 @@
+const { composePlugins, withNx } = require('@nx/webpack')
const path = require('path')
const createEntry = (pathSuffix) =>
path.resolve(__dirname, `src/migrate/${pathSuffix}`)
-module.exports = (config) => {
+module.exports = composePlugins(withNx(), (config) => {
config.entry = {
...config.entry,
migrateAws: createEntry('migrateAws.ts'),
@@ -15,4 +16,4 @@ module.exports = (config) => {
return {
...config,
}
-}
+})
diff --git a/apps/services/sessions/project.json b/apps/services/sessions/project.json
index 363a8c8706ce..eb509c749b64 100644
--- a/apps/services/sessions/project.json
+++ b/apps/services/sessions/project.json
@@ -86,7 +86,7 @@
"dev-services": {
"executor": "nx:run-commands",
"options": {
- "command": "docker-compose up -d",
+ "command": "docker compose up -d",
"cwd": "apps/services/sessions"
}
},
diff --git a/apps/services/university-gateway/migrations/20240607123131-remove-undefined-mode-of-delivery.js b/apps/services/university-gateway/migrations/20240607123131-remove-undefined-mode-of-delivery.js
new file mode 100644
index 000000000000..e3d1114cf774
--- /dev/null
+++ b/apps/services/university-gateway/migrations/20240607123131-remove-undefined-mode-of-delivery.js
@@ -0,0 +1,71 @@
+'use strict'
+
+module.exports = {
+ up: (queryInterface, Sequelize) => {
+ return queryInterface.sequelize.query(`
+ BEGIN TRANSACTION;
+
+ -- Delete UNDEFINED entries if other modes exist for the same program_id
+ DELETE FROM program_mode_of_delivery
+ WHERE mode_of_delivery = 'UNDEFINED'
+ AND program_id IN (
+ SELECT program_id
+ FROM program_mode_of_delivery
+ GROUP BY program_id
+ HAVING COUNT(*) > 1
+ );
+
+ -- Update remaining UNDEFINED entries to ON_SITE if no other modes exist for the same program_id
+ UPDATE program_mode_of_delivery
+ SET mode_of_delivery = 'ON_SITE'
+ WHERE mode_of_delivery = 'UNDEFINED'
+ AND program_id NOT IN (
+ SELECT program_id
+ FROM program_mode_of_delivery
+ WHERE mode_of_delivery <> 'UNDEFINED'
+ );
+
+ -- Change name of existing enum
+ ALTER TYPE enum_program_mode_of_delivery_mode_of_delivery RENAME TO enum_program_mode_of_delivery_mode_of_delivery_old;
+
+ -- Create new enum based on existing enum
+ CREATE TYPE enum_program_mode_of_delivery_mode_of_delivery AS ENUM ('ON_SITE', 'ONLINE', 'REMOTE', 'MIXED');
+
+ -- Change type for mode_of_delivery column to new enum
+ ALTER TABLE program_mode_of_delivery
+ ALTER COLUMN mode_of_delivery
+ TYPE enum_program_mode_of_delivery_mode_of_delivery
+ USING mode_of_delivery::text::enum_program_mode_of_delivery_mode_of_delivery;
+
+ -- Delete old enum
+ DROP TYPE enum_program_mode_of_delivery_mode_of_delivery_old;
+
+ COMMIT;
+ `)
+ },
+
+ //Down migration will not restore entries deleted or changed in up migration.
+ //Those entries should not have entered into the database in the first place.
+ down(queryInterface, Sequelize) {
+ return queryInterface.sequelize.query(`
+ BEGIN;
+
+ -- Change name of existing enum
+ ALTER TYPE enum_program_mode_of_delivery_mode_of_delivery RENAME TO enum_program_mode_of_delivery_mode_of_delivery_old;
+
+ -- Create new enum based on existing enum
+ CREATE TYPE enum_program_mode_of_delivery_mode_of_delivery AS ENUM ('ON_SITE', 'ONLINE', 'REMOTE', 'MIXED', 'UNDEFINED');
+
+ -- Change type for mode_of_delivery column to new enum
+ ALTER TABLE program_mode_of_delivery
+ ALTER COLUMN mode_of_delivery
+ TYPE enum_program_mode_of_delivery_mode_of_delivery
+ USING mode_of_delivery::text::enum_program_mode_of_delivery_mode_of_delivery;
+
+ -- Delete old enum
+ DROP TYPE enum_program_mode_of_delivery_mode_of_delivery_old;
+
+ COMMIT;
+ `)
+ },
+}
diff --git a/apps/services/university-gateway/migrations/20240607123132-change-application-mode-of-delivery.js b/apps/services/university-gateway/migrations/20240607123132-change-application-mode-of-delivery.js
new file mode 100644
index 000000000000..c161ddd8f015
--- /dev/null
+++ b/apps/services/university-gateway/migrations/20240607123132-change-application-mode-of-delivery.js
@@ -0,0 +1,60 @@
+'use strict'
+
+module.exports = {
+ up: (queryInterface, Sequelize) => {
+ return queryInterface.sequelize.query(`
+ BEGIN;
+
+ -- Add new column to the application table using enum instead of foreign key
+ ALTER TABLE application
+ ADD COLUMN program_mode_of_delivery enum_program_mode_of_delivery_mode_of_delivery;
+
+ -- Update the new column with the correct mode of delivery
+ UPDATE application
+ SET program_mode_of_delivery = mode_of_delivery FROM program_mode_of_delivery
+ WHERE application.program_mode_of_delivery_id = program_mode_of_delivery.id;
+
+ -- Set the new column to NOT NULL (need to do this after populating the column)
+ ALTER TABLE application
+ ALTER COLUMN program_mode_of_delivery SET NOT NULL;
+
+ -- Drop the old column
+ ALTER TABLE application
+ DROP COLUMN program_mode_of_delivery_id;
+
+ COMMIT;
+ `)
+ },
+
+ down(queryInterface, Sequelize) {
+ return queryInterface.sequelize.query(`
+ BEGIN;
+
+ -- Add back the old column
+ ALTER TABLE application
+ ADD COLUMN program_mode_of_delivery_id UUID;
+
+ -- Populate the old column with the correct mode of delivery
+ UPDATE application
+ SET program_mode_of_delivery_id = program_mode_of_delivery.id FROM program_mode_of_delivery
+ WHERE application.program_id = program_mode_of_delivery.program_id
+ AND application.program_mode_of_delivery = program_mode_of_delivery.mode_of_delivery;
+
+ -- Set the old column to NOT NULL (need to do this after populating the column)
+ ALTER TABLE application
+ ALTER COLUMN program_mode_of_delivery_id SET NOT NULL;
+
+ -- Add the foreign key constraint (need to do this after populating the column)
+ ALTER TABLE application
+ ADD CONSTRAINT fk_program_mode_of_delivery
+ FOREIGN KEY (program_mode_of_delivery_id)
+ REFERENCES program_mode_of_delivery (id);
+
+ -- Drop the new column
+ ALTER TABLE application
+ DROP COLUMN program_mode_of_delivery;
+
+ COMMIT;
+ `)
+ },
+}
diff --git a/apps/services/university-gateway/project.json b/apps/services/university-gateway/project.json
index 3b5d58a41b84..21d6caceb936 100644
--- a/apps/services/university-gateway/project.json
+++ b/apps/services/university-gateway/project.json
@@ -66,7 +66,7 @@
"dev-services": {
"executor": "nx:run-commands",
"options": {
- "command": "docker-compose up -d",
+ "command": "docker compose up -d",
"cwd": "apps/services/university-gateway"
}
},
diff --git a/apps/services/university-gateway/src/app/modules/application/model/application.ts b/apps/services/university-gateway/src/app/modules/application/model/application.ts
index db28c42057b8..210bfd49a900 100644
--- a/apps/services/university-gateway/src/app/modules/application/model/application.ts
+++ b/apps/services/university-gateway/src/app/modules/application/model/application.ts
@@ -13,9 +13,11 @@ import {
UpdatedAt,
} from 'sequelize-typescript'
import { Program } from '../../program/model/program'
-import { ProgramModeOfDelivery } from '../../program/model/programModeOfDelivery'
import { University } from '../../university/model/university'
-import { ApplicationStatus } from '@island.is/university-gateway'
+import {
+ ApplicationStatus,
+ ModeOfDelivery,
+} from '@island.is/university-gateway'
import {
CreationOptional,
InferAttributes,
@@ -86,15 +88,16 @@ export class Application extends Model<
programId!: string
@ApiProperty({
- description: 'Program mode of delivery ID',
- example: '00000000-0000-0000-0000-000000000000',
+ description: 'The mode of delivery selected in the application',
+ example: ModeOfDelivery.ON_SITE,
+ enum: ModeOfDelivery,
})
@Column({
- type: DataType.UUID,
+ type: DataType.ENUM,
+ values: Object.values(ModeOfDelivery),
allowNull: false,
})
- @ForeignKey(() => ProgramModeOfDelivery)
- programModeOfDeliveryId!: string
+ programModeOfDelivery!: ModeOfDelivery
@ApiProperty({
description: 'Application status',
diff --git a/apps/services/university-gateway/src/app/modules/application/universityApplication.service.ts b/apps/services/university-gateway/src/app/modules/application/universityApplication.service.ts
index 127e9123f7e9..f0d282b2082f 100644
--- a/apps/services/university-gateway/src/app/modules/application/universityApplication.service.ts
+++ b/apps/services/university-gateway/src/app/modules/application/universityApplication.service.ts
@@ -131,7 +131,7 @@ export class UniversityApplicationService {
nationalId: user.nationalId,
universityId: university.id,
programId: program.id,
- programModeOfDeliveryId: programModeOfDelivery.id,
+ programModeOfDelivery: programModeOfDelivery.modeOfDelivery,
status: ApplicationStatus.IN_REVIEW,
externalId: 'testid124',
})
diff --git a/apps/services/user-notification/project.json b/apps/services/user-notification/project.json
index 0dac2fb896a8..130e8aa9f4fa 100644
--- a/apps/services/user-notification/project.json
+++ b/apps/services/user-notification/project.json
@@ -90,7 +90,7 @@
"dev-services": {
"executor": "nx:run-commands",
"options": {
- "command": "docker-compose up -d --build",
+ "command": "docker compose up -d --build",
"cwd": "apps/services/user-notification"
}
},
diff --git a/apps/services/user-profile/project.json b/apps/services/user-profile/project.json
index 32f31cf51a8d..316db6cce4ff 100644
--- a/apps/services/user-profile/project.json
+++ b/apps/services/user-profile/project.json
@@ -67,7 +67,7 @@
"dev-services": {
"executor": "nx:run-commands",
"options": {
- "command": "docker-compose up -d",
+ "command": "docker compose up -d",
"cwd": "apps/services/user-profile"
}
},
diff --git a/apps/skilavottord/README.md b/apps/skilavottord/README.md
index 02c5a48cb136..26d1a21eb683 100644
--- a/apps/skilavottord/README.md
+++ b/apps/skilavottord/README.md
@@ -68,7 +68,7 @@ cd apps/skilavottord/ws
and run
```bash
-docker-compose up
+docker compose up
```
Then run migrations and seed the database:
diff --git a/apps/system-e2e/src/tests/islandis/service-portal/acceptance/licenses.spec.ts b/apps/system-e2e/src/tests/islandis/service-portal/acceptance/licenses.spec.ts
index ad4be60bb28f..5ee8ff3a7074 100644
--- a/apps/system-e2e/src/tests/islandis/service-portal/acceptance/licenses.spec.ts
+++ b/apps/system-e2e/src/tests/islandis/service-portal/acceptance/licenses.spec.ts
@@ -52,10 +52,33 @@ test.describe('MS - Licenses', () => {
await expect(element).toBeVisible()
}
})
+ await test.step(
+ 'should display the firearm license detail screen',
+ async () => {
+ //More complex so gets it's own test
+ // Arrange
+ const element = page.locator(`[href*="skotvopnaleyfi"]`)
+ await element.waitFor()
+ await element.click()
+
+ const title = page.getByRole('heading', {
+ name: 'Skotvopnaleyfið þitt',
+ })
+ await title.waitFor()
+ await expect(title).toBeVisible()
+
+ const rights = page.getByText('Réttindaflokkar')
+ await expect(rights).toBeVisible()
+
+ const properties = page.getByText('Skotvopn í eigu leyfishafa')
+ await expect(properties).toBeVisible()
+
+ await page.goBack()
+ },
+ )
await test.step('should display each detail screen', async () => {
// Arrange
const licenses = [
- { title: 'Skotvopnaleyfið þitt', ref: 'skotvopnaleyfi' },
{ title: 'Ökuréttindin þín', ref: 'okurettindi' },
{ title: 'ADR réttindin þín', ref: 'adrrettindi' },
{ title: 'Vinnuvélaréttindin þín', ref: 'vinnuvelarettindi' },
diff --git a/apps/system-e2e/src/tests/islandis/service-portal/acceptance/mocks/occupationalLicenses.mock.ts b/apps/system-e2e/src/tests/islandis/service-portal/acceptance/mocks/occupationalLicenses.mock.ts
index f643e2b08881..735bb96c648b 100644
--- a/apps/system-e2e/src/tests/islandis/service-portal/acceptance/mocks/occupationalLicenses.mock.ts
+++ b/apps/system-e2e/src/tests/islandis/service-portal/acceptance/mocks/occupationalLicenses.mock.ts
@@ -1,6 +1,7 @@
import { addXroadMock } from '../../../../../support/wire-mocks'
import { Response } from '@anev/ts-mountebank'
import {
+ DistrictCommissionersPCard,
Education,
OccupationalLicenses,
} from '../../../../../../../../infra/src/dsl/xroad'
@@ -10,14 +11,14 @@ export const loadOccupationalLicensesXroadMocks = async () => {
prefixType: 'only-base-path',
config: Education,
prefix: 'XROAD_MMS_LICENSE_SERVICE_ID',
- apiPath: '/api/public/users/0101302209/licenses',
+ apiPath: '/api/public/users/0101302399/licenses',
response: [
new Response().withJSONBody([
{
id: '123',
- issued: '2022-06-25T00:00:00.000Z',
- nationalId: '0101302209',
- type: 'kennari',
+ issued: '2999-01-01T00:00:00.000Z',
+ nationalId: '123',
+ type: 'kennari TEST',
fullName: 'Testi gæ',
s3Key: null,
contentHash: null,
@@ -52,4 +53,111 @@ export const loadOccupationalLicensesXroadMocks = async () => {
]),
],
})
+
+ await addXroadMock({
+ prefixType: 'only-base-path',
+ config: DistrictCommissionersPCard,
+ prefix: 'XROAD_DISTRICT_COMMISSIONERS_P_CARD_PATH',
+ apiPath: '/RettindiFyrirIslandIs/RettindiFyrirIslandIs',
+ response: [
+ new Response().withJSONBody({
+ leyfi: [
+ {
+ audkenni: '1010101',
+ titill: 'Heimagisting - Test',
+ utgafudagur: '2022-07-11T14:40:36',
+ utgefandi: {
+ audkenni: '41',
+ titill: 'Sýslumaðurinn á höfuðborgarsvæðinu',
+ },
+ stada: {
+ titill: 'Útrunnið',
+ kodi: 'EXPIRED',
+ },
+ },
+
+ {
+ audkenni: '123',
+ titill: 'Verðbréfaréttindi',
+ utgafudagur: '2023-03-29T22:54:26',
+ utgefandi: {
+ audkenni: '41',
+ titill: 'Sýslumaðurinn á höfuðborgarsvæðinu',
+ },
+ stada: {
+ titill: 'Í gildi',
+ kodi: 'VALID',
+ },
+ },
+ {
+ audkenni: '789',
+ titill: 'Heimagisting - Test2',
+ utgafudagur: null,
+ utgefandi: {
+ audkenni: '41',
+ titill: 'Sýslumaðurinn á höfuðborgarsvæðinu',
+ },
+ stada: {
+ titill: 'Í vinnslu',
+ kodi: 'INPROGRESS',
+ },
+ },
+ ],
+ villur: {
+ kodi: null,
+ skilabod: null,
+ },
+ }),
+ ],
+ })
+
+ await addXroadMock({
+ prefixType: 'only-base-path',
+ config: DistrictCommissionersPCard,
+ prefix: 'XROAD_DISTRICT_COMMISSIONERS_P_CARD_PATH',
+ apiPath: '/RettindiFyrirIslandIs/RettindiFyrirIslandIs/123',
+ response: [
+ new Response().withJSONBody({
+ nafn: 'Bubbi verðbréfakall',
+ leyfi: {
+ audkenni: '123',
+ titill: 'Verðbréfaréttindi',
+ utgafudagur: '1999-12-12T01:01:01',
+ utgefandi: {
+ audkenni: '999',
+ titill: 'Sýslukall',
+ },
+ stada: {
+ titill: 'Í vinnslu',
+ kodi: 'INPROGRESS',
+ },
+ },
+ svid: [
+ {
+ heiti: 'Gildir til',
+ gildi: '1.1.2999',
+ tegund: 'date',
+ },
+ ],
+ textar: {
+ haus: 'Verðbréfaréttindi abc',
+ fotur: 'blablabla',
+ },
+ adgerdir: [
+ {
+ tegund: 'postholf',
+ titill: 'test pósthólf',
+ slod: '123xyz',
+ },
+ {
+ tegund: 'link',
+ titill: 'Test link',
+ slod: 'https://example.org',
+ },
+ ],
+ skrar: null,
+ villur: null,
+ }),
+ ],
+ })
}
diff --git a/apps/system-e2e/src/tests/islandis/service-portal/acceptance/occupational-licenses.spec.ts b/apps/system-e2e/src/tests/islandis/service-portal/acceptance/occupational-licenses.spec.ts
index 6335d93dbd0f..cc1323ac5a50 100644
--- a/apps/system-e2e/src/tests/islandis/service-portal/acceptance/occupational-licenses.spec.ts
+++ b/apps/system-e2e/src/tests/islandis/service-portal/acceptance/occupational-licenses.spec.ts
@@ -15,7 +15,7 @@ test.describe('MS - Occupational licenses', () => {
browser: browser,
storageState: 'service-portal-faereyjar.json',
homeUrl,
- phoneNumber: '0102209',
+ phoneNumber: '0102399',
idsLoginOn: true,
})
await setupXroadMocks()
@@ -27,7 +27,11 @@ test.describe('MS - Occupational licenses', () => {
await test.step('should display each license type in list', async () => {
// Arrange
- const licenses = ['Kennari', 'Bebeb - Starfsleyfi']
+ const licenses = [
+ 'Kennari test',
+ 'Bebeb - Starfsleyfi',
+ 'Verðbréfaréttindi',
+ ]
await page.goto(icelandicAndNoPopupUrl('minarsidur/starfsleyfi'))
@@ -45,8 +49,9 @@ test.describe('MS - Occupational licenses', () => {
await test.step('should display each detail screen', async () => {
// Arrange
const licenses = [
- { title: 'Bebeb', ref: 'Bebeb/1337' },
- { title: 'Kennari', ref: 'Kennari/123' },
+ { title: 'Bebeb', ref: 'minarsidur/starfsleyfi/H13' },
+ { title: 'Kennari test', ref: 'minarsidur/starfsleyfi/123' },
+ { title: 'Verðbréfaréttindi', ref: 'minarsidur/starfsleyfi/D123' },
]
for await (const license of licenses) {
diff --git a/apps/web/components/BulletList/BulletList.tsx b/apps/web/components/BulletList/BulletList.tsx
index 98a8d89a8e22..a27f8461fa7e 100644
--- a/apps/web/components/BulletList/BulletList.tsx
+++ b/apps/web/components/BulletList/BulletList.tsx
@@ -26,10 +26,10 @@ type NumberBulletGroup = {
bullets: NumberBullet[]
}
-type Entry = IconBullet | NumberBulletGroup
+export type BulletEntry = IconBullet | NumberBulletGroup
export interface BulletListProps {
- bullets: Entry[]
+ bullets: BulletEntry[]
}
export const BulletList: FC> = ({
diff --git a/apps/web/components/Charts/v2/messages.ts b/apps/web/components/Charts/v2/messages.ts
index 7dc3f2d64858..c98482155b22 100644
--- a/apps/web/components/Charts/v2/messages.ts
+++ b/apps/web/components/Charts/v2/messages.ts
@@ -7,6 +7,8 @@ export const messages = {
changeYOY: 'Breyting milli ára',
millionPostfix: 'm',
thousandPostfix: 'þ',
+ thousandSeparator: '.',
+ fractionSeparator: ',',
},
en: {
skipGraph: 'Skip graph with title',
@@ -16,5 +18,7 @@ export const messages = {
changeYOY: 'Change year over year',
millionPostfix: 'm',
thousandPostfix: 'k',
+ thousandSeparator: ',',
+ fractionSeparator: '.',
},
}
diff --git a/apps/web/components/Charts/v2/renderers/TooltipRenderer/TooltipRenderer.tsx b/apps/web/components/Charts/v2/renderers/TooltipRenderer/TooltipRenderer.tsx
index 43de4dc45268..28d89f7dc09e 100644
--- a/apps/web/components/Charts/v2/renderers/TooltipRenderer/TooltipRenderer.tsx
+++ b/apps/web/components/Charts/v2/renderers/TooltipRenderer/TooltipRenderer.tsx
@@ -1,10 +1,12 @@
+import { useMemo } from 'react'
import { Tooltip, TooltipProps } from 'recharts'
import { theme } from '@island.is/island-ui/theme'
import { Chart } from '@island.is/web/graphql/schema'
import { useI18n } from '@island.is/web/i18n'
-import { ChartComponentWithRenderProps } from '../../types'
+import { messages } from '../../messages'
+import { ChartComponentWithRenderProps, CustomStyleConfig } from '../../types'
import { formatValueForPresentation } from '../../utils'
import * as style from './TooltipRenderer.css'
@@ -22,6 +24,14 @@ export const CustomTooltipRenderer = (props: CustomTooltipProps) => {
const { activeLocale } = useI18n()
+ const customStyleConfig = useMemo(() => {
+ if (!props.slice.customStyleConfig) {
+ return {}
+ }
+
+ return JSON.parse(props.slice.customStyleConfig)
+ }, [props.slice.customStyleConfig]) as CustomStyleConfig
+
if (!isActive) {
return null
}
@@ -34,7 +44,7 @@ export const CustomTooltipRenderer = (props: CustomTooltipProps) => {
)}
- {payload.map((item, i) => {
+ {payload.map((item) => {
const key = item?.payload?.key ?? item.dataKey
let labelColor = theme.color.dark400
@@ -52,6 +62,26 @@ export const CustomTooltipRenderer = (props: CustomTooltipProps) => {
labelColor = theme.color.blue400
}
+ const value =
+ typeof item.value === 'number' || item.value
+ ? formatValueForPresentation(
+ activeLocale,
+ item.value,
+ props.slice.reduceAndRoundValue ?? true,
+ 1,
+ )
+ : ''
+
+ const fractionSeparator =
+ messages[activeLocale].fractionSeparator ?? ','
+
+ const postfix =
+ !props.slice.reduceAndRoundValue &&
+ customStyleConfig.tooltip?.appendFractionToIntegers &&
+ Number.isInteger(item.value)
+ ? `${fractionSeparator}0`
+ : ''
+
return (
-
{
>
{item.name}
- :{' '}
- {typeof item.value === 'number' || item.value
- ? formatValueForPresentation(
- activeLocale,
- item.value,
- props.slice.reduceAndRoundValue ?? true,
- 1,
- )
- : ''}
+ : {value}
+ {postfix}
)
})}
diff --git a/apps/web/components/Charts/v2/types/index.ts b/apps/web/components/Charts/v2/types/index.ts
index 43d0572f1ad6..3e0b0879ff1c 100644
--- a/apps/web/components/Charts/v2/types/index.ts
+++ b/apps/web/components/Charts/v2/types/index.ts
@@ -91,4 +91,7 @@ export interface CustomStyleConfig {
outerRadius?: number
fontSize?: number
}
+ tooltip?: {
+ appendFractionToIntegers?: boolean
+ }
}
diff --git a/apps/web/components/Charts/v2/utils/chart.tsx b/apps/web/components/Charts/v2/utils/chart.tsx
index 6dc852c0dd4b..e66aa13682af 100644
--- a/apps/web/components/Charts/v2/utils/chart.tsx
+++ b/apps/web/components/Charts/v2/utils/chart.tsx
@@ -1,4 +1,4 @@
-import { CartesianGrid, XAxis, YAxis } from 'recharts'
+import { CartesianGrid, Label, XAxis, YAxis } from 'recharts'
import { theme } from '@island.is/island-ui/theme'
import type { Locale } from '@island.is/shared/types'
@@ -126,7 +126,18 @@ export const getCartesianGridComponents = ({
domain={customStyleConfig.yAxis?.domain ?? [0, 'auto']}
tick={customStyleConfig.yAxis?.tick ?? undefined}
ticks={customStyleConfig.yAxis?.ticks ?? undefined}
- />,
+ >
+ {slice.yAxisLabel && (
+
+ )}
+ ,
]
}
diff --git a/apps/web/components/Charts/v2/utils/format.ts b/apps/web/components/Charts/v2/utils/format.ts
index 038d976951b1..f324f599f1df 100644
--- a/apps/web/components/Charts/v2/utils/format.ts
+++ b/apps/web/components/Charts/v2/utils/format.ts
@@ -60,7 +60,20 @@ export const formatValueForPresentation = (
v = round(value / divider, precision)
}
- return `${v.toString().replace(/\B(?=(\d{3})+(?!\d))/g, '.')}${postfix}`
+ const thousandSeparator = messages[activeLocale].thousandSeparator ?? '.'
+ const fractionSeparator = messages[activeLocale].fractionSeparator ?? ','
+
+ const [integer, fraction] = v.toString().split('.')
+
+ // Add thousand separator
+ let result = integer.replace(/\B(?=(\d{3})+(?!\d))/g, thousandSeparator)
+
+ // Add fraction separator
+ if (fraction) {
+ result += `${fractionSeparator}${fraction}`
+ }
+
+ return `${result}${postfix}`
}
} catch {
// pass
diff --git a/apps/web/components/OpenApiDocumentation/OpenApiDocumentation.tsx b/apps/web/components/OpenApiDocumentation/OpenApiDocumentation.tsx
index 0d75b3004d11..37266c99baec 100644
--- a/apps/web/components/OpenApiDocumentation/OpenApiDocumentation.tsx
+++ b/apps/web/components/OpenApiDocumentation/OpenApiDocumentation.tsx
@@ -1,6 +1,8 @@
import React from 'react'
+
import { OpenApi } from '@island.is/api-catalogue/types'
import { Box } from '@island.is/island-ui/core'
+
import RedocStandalone from './RedocStandalone'
export interface OpenApiDocumentationProps {
@@ -9,7 +11,8 @@ export interface OpenApiDocumentationProps {
export const OpenApiDocumentation = ({ spec }: OpenApiDocumentationProps) => {
return (
-
+ // Use transform that has no effect(similar to null) to keep Redocly watermark inside element
+
> = ({
id={slice.id}
aria-labelledby={'sliceTitle-' + slice.id}
>
+ {slice.dividerOnTop && }
{
- switch (bullet.__typename) {
- case 'IconBullet':
- return {
- ...bullet,
- type: 'IconBullet',
- icon: bullet.icon.url,
+ bullets={
+ slice.bullets
+ .map((bullet) => {
+ switch (bullet.__typename) {
+ case 'IconBullet':
+ return {
+ ...bullet,
+ type: 'IconBullet',
+ icon: bullet.icon.url,
+ }
+ case 'NumberBulletGroup':
+ return { ...bullet, type: 'NumberBulletGroup' }
+ default:
+ return null
}
- case 'NumberBulletGroup':
- return { ...bullet, type: 'NumberBulletGroup' }
- default:
- return null
- }
- })}
+ })
+ .filter(Boolean) as BulletEntry[]
+ }
/>
)
diff --git a/apps/web/components/Organization/Slice/SliceMachine.tsx b/apps/web/components/Organization/Slice/SliceMachine.tsx
index fcfac420043d..983dc5b8b840 100644
--- a/apps/web/components/Organization/Slice/SliceMachine.tsx
+++ b/apps/web/components/Organization/Slice/SliceMachine.tsx
@@ -94,6 +94,10 @@ const PowerBiSlice = dynamic(() =>
import('@island.is/web/components').then((mod) => mod.PowerBiSlice),
)
+const ChartNumberBox = dynamic(() =>
+ import('@island.is/web/components').then((mod) => mod.ChartNumberBox),
+)
+
interface SliceMachineProps {
slice: Slice
namespace?: Record
@@ -192,6 +196,8 @@ const renderSlice = (
filterTags={(slice as GenericListSchema).filterTags}
/>
)
+ case 'ChartNumberBox':
+ return
default:
return
}
diff --git a/apps/web/components/connected/vehicles/PublicVehicleSearch.tsx b/apps/web/components/connected/vehicles/PublicVehicleSearch.tsx
index 0484ee1685a6..48d8005f5c2e 100644
--- a/apps/web/components/connected/vehicles/PublicVehicleSearch.tsx
+++ b/apps/web/components/connected/vehicles/PublicVehicleSearch.tsx
@@ -101,8 +101,8 @@ const PublicVehicleSearch = ({ slice }: PublicVehicleSearchProps) => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [router?.isReady, router?.query?.vq])
- const formattedRegistrationDate = vehicleInformation?.newRegDate
- ? format(new Date(vehicleInformation.newRegDate), 'do MMMM yyyy')
+ const formattedRegistrationDate = vehicleInformation?.firstRegDate
+ ? format(new Date(vehicleInformation.firstRegDate), 'do MMMM yyyy')
: ''
const formattedNextVehicleMainInspectionDate =
vehicleInformation?.nextVehicleMainInspection
@@ -228,7 +228,7 @@ const PublicVehicleSearch = ({ slice }: PublicVehicleSearchProps) => {
- {n('newRegDate', 'Fyrst skráð:')}
+ {n('firstRegDate', 'Fyrst skráð:')}
diff --git a/apps/web/layouts/main.tsx b/apps/web/layouts/main.tsx
index a420f400076a..e243da70d00f 100644
--- a/apps/web/layouts/main.tsx
+++ b/apps/web/layouts/main.tsx
@@ -728,13 +728,13 @@ export const withMainLayout = (
])
const layoutComponentProps = componentProps as LayoutComponentProps
- const themeConfig = layoutComponentProps.themeConfig ?? {}
+ const themeConfig = layoutComponentProps?.themeConfig ?? {}
const organizationAlertBannerContent =
- layoutComponentProps.organizationPage?.alertBanner
- const articleAlertBannerContent = layoutComponentProps.article?.alertBanner
- const customAlertBannerContent = layoutComponentProps.customAlertBanner
+ layoutComponentProps?.organizationPage?.alertBanner
+ const articleAlertBannerContent = layoutComponentProps?.article?.alertBanner
+ const customAlertBannerContent = layoutComponentProps?.customAlertBanner
const languageToggleQueryParams =
- layoutComponentProps.languageToggleQueryParams
+ layoutComponentProps?.languageToggleQueryParams
return {
layoutProps: {
diff --git a/apps/web/screens/News.css.ts b/apps/web/screens/News.css.ts
deleted file mode 100644
index e82d335020e6..000000000000
--- a/apps/web/screens/News.css.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { themeUtils } from '@island.is/island-ui/theme'
-import { style } from '@vanilla-extract/css'
-
-export const floatedImage = style({
- ...themeUtils.responsiveStyle({
- sm: {
- float: 'right',
- width: '50%',
- marginLeft: '16px',
- },
- }),
-})
-
-export const clearBoth = style({
- clear: 'both',
-})
diff --git a/apps/web/screens/News.tsx b/apps/web/screens/News.tsx
index 9c3f6e5352c1..c2cde637d40f 100644
--- a/apps/web/screens/News.tsx
+++ b/apps/web/screens/News.tsx
@@ -1,61 +1,59 @@
/* eslint-disable jsx-a11y/anchor-is-valid */
import capitalize from 'lodash/capitalize'
-import cn from 'classnames'
-import { useRouter } from 'next/router'
import NextLink from 'next/link'
-import { Screen } from '../types'
-import { Image, Slice as SliceType } from '@island.is/island-ui/contentful'
-import { useDateUtils } from '@island.is/web/i18n/useDateUtils'
+import { useRouter } from 'next/router'
+
import {
Box,
- Text,
- Stack,
- Breadcrumbs,
BreadCrumbItem,
- Pagination,
+ Breadcrumbs,
+ Button,
+ Divider,
Hidden,
Link,
Navigation,
NavigationItem,
+ Pagination,
ResponsiveSpace,
- Button,
+ Stack,
Tag,
- Divider,
+ Text,
} from '@island.is/island-ui/core'
-import { withMainLayout } from '@island.is/web/layouts/main'
import {
- GET_NAMESPACE_QUERY,
- GET_NEWS_DATES_QUERY,
- GET_NEWS_QUERY,
- GET_SINGLE_NEWS_ITEM_QUERY,
-} from './queries'
-import { SidebarLayout } from './Layouts/SidebarLayout'
+ HeadWithSocialSharing,
+ NewsArticle,
+ NewsCard,
+ Webreader,
+} from '@island.is/web/components'
+import { FRONTPAGE_NEWS_TAG_ID } from '@island.is/web/constants'
+import { useNamespace } from '@island.is/web/hooks'
+import { useDateUtils } from '@island.is/web/i18n/useDateUtils'
+import { withMainLayout } from '@island.is/web/layouts/main'
+
import {
- GetNewsDatesQuery,
- QueryGetNewsDatesArgs,
- GetNewsQuery,
- QueryGetNewsArgs,
ContentLanguage,
- QueryGetNamespaceArgs,
+ GenericTag,
GetNamespaceQuery,
+ GetNewsDatesQuery,
+ GetNewsQuery,
GetSingleNewsItemQuery,
+ QueryGetNamespaceArgs,
+ QueryGetNewsArgs,
+ QueryGetNewsDatesArgs,
QueryGetSingleNewsArgs,
- GenericTag,
} from '../graphql/schema'
-import {
- NewsCard,
- HeadWithSocialSharing,
- Webreader,
- NewsArticle,
-} from '@island.is/web/components'
-import { useNamespace } from '@island.is/web/hooks'
+import useContentfulId from '../hooks/useContentfulId'
import { LinkType, useLinkResolver } from '../hooks/useLinkResolver'
-import { FRONTPAGE_NEWS_TAG_ID } from '@island.is/web/constants'
+import { Screen } from '../types'
import { CustomNextError } from '../units/errors'
-import useContentfulId from '../hooks/useContentfulId'
-import { webRichText } from '../utils/richText'
-
-import * as styles from './News.css'
+import { getIntParam } from '../utils/queryParams'
+import { SidebarLayout } from './Layouts/SidebarLayout'
+import {
+ GET_NAMESPACE_QUERY,
+ GET_NEWS_DATES_QUERY,
+ GET_NEWS_QUERY,
+ GET_SINGLE_NEWS_ITEM_QUERY,
+} from './queries'
const PERPAGE = 10
@@ -407,25 +405,14 @@ const createDatesMap = (datesList: string[]) => {
)
}
-const getIntParam = (s: string | string[]) => {
- const i = parseInt(Array.isArray(s) ? s[0] : s, 10)
- if (!isNaN(i)) return i
-}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error make web strict
NewsListNew.getProps = async ({ apolloClient, locale, query }) => {
const slug = query.slug as string
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-expect-error make web strict
- const year = getIntParam(query.y)
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-expect-error make web strict
- const month = year && getIntParam(query.m)
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-expect-error make web strict
- const selectedPage = getIntParam(query.page) ?? 1
+ const year = getIntParam(query.y, { minValue: 1000, maxValue: 9999 })
+ const month = year && getIntParam(query.m, { minValue: 1, maxValue: 12 })
+ const selectedPage = getIntParam(query.page, { minValue: 1 }) ?? 1
const tag = (query.tag as string) ?? FRONTPAGE_NEWS_TAG_ID
-
const [
{
data: { getNewsDates: newsDatesList },
@@ -479,10 +466,7 @@ NewsListNew.getProps = async ({ apolloClient, locale, query }) => {
})
// map data here to reduce data processing in component
.then((variables) => {
- // map data here to reduce data processing in component
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-expect-error make web strict
- return JSON.parse(variables.data.getNamespace.fields)
+ return JSON.parse(variables?.data?.getNamespace?.fields || '{}')
}),
])
diff --git a/apps/web/screens/Organization/OrganizationNews/OrganizationNewsList.tsx b/apps/web/screens/Organization/OrganizationNews/OrganizationNewsList.tsx
index 6a2b713c9716..e868b65c663a 100644
--- a/apps/web/screens/Organization/OrganizationNews/OrganizationNewsList.tsx
+++ b/apps/web/screens/Organization/OrganizationNews/OrganizationNewsList.tsx
@@ -1,4 +1,8 @@
+import capitalize from 'lodash/capitalize'
+import { useRouter } from 'next/router'
+
import { BreadCrumbItem, NavigationItem } from '@island.is/island-ui/core'
+import { Locale } from '@island.is/shared/types'
import {
getThemeConfig,
NewsList,
@@ -27,9 +31,8 @@ import { useDateUtils } from '@island.is/web/i18n/useDateUtils'
import { LayoutProps, withMainLayout } from '@island.is/web/layouts/main'
import type { Screen } from '@island.is/web/types'
import { CustomNextError } from '@island.is/web/units/errors'
-import { Locale } from '@island.is/shared/types'
-import capitalize from 'lodash/capitalize'
-import { useRouter } from 'next/router'
+import { getIntParam } from '@island.is/web/utils/queryParams'
+
import {
GET_CONTENT_SLUG,
GET_NAMESPACE_QUERY,
@@ -226,22 +229,12 @@ const createDatesMap = (datesList: string[]) => {
)
}
-const getIntParam = (s: string | string[]) => {
- const i = parseInt(Array.isArray(s) ? s[0] : s, 10)
- if (!isNaN(i)) return i
-}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore make web strict
OrganizationNewsList.getProps = async ({ apolloClient, query, locale }) => {
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-ignore make web strict
- const year = getIntParam(query.y)
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-ignore make web strict
- const month = year && getIntParam(query.m)
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-ignore make web strict
- const selectedPage = getIntParam(query.page) ?? 1
+ const year = getIntParam(query.y, { minValue: 1000, maxValue: 9999 })
+ const month = year && getIntParam(query.m, { minValue: 1, maxValue: 12 })
+ const selectedPage = getIntParam(query.page, { minValue: 1 }) ?? 1
const organizationPage = (
await Promise.resolve(
@@ -332,9 +325,7 @@ OrganizationNewsList.getProps = async ({ apolloClient, query, locale }) => {
},
})
.then((variables) =>
- variables.data.getNamespace?.fields
- ? JSON.parse(variables.data.getNamespace.fields)
- : {},
+ JSON.parse(variables?.data?.getNamespace?.fields || '{}'),
),
])
diff --git a/apps/web/screens/PetitionView/PetitionView.tsx b/apps/web/screens/PetitionView/PetitionView.tsx
index 480eb57c183f..cfc48425d463 100644
--- a/apps/web/screens/PetitionView/PetitionView.tsx
+++ b/apps/web/screens/PetitionView/PetitionView.tsx
@@ -224,7 +224,7 @@ const PetitionView: Screen = ({ namespace }) => {
>
)}
{list.closedDate && new Date() <= new Date(list.closedDate) ? (
- listEndorsements.data && listEndorsements.data.length ? (
+ listEndorsements.data?.length && !loadingEndorsements ? (
{
)
}
-const getIntParam = (s: string | string[]) => {
- const i = parseInt(Array.isArray(s) ? s[0] : s, 10)
- if (!isNaN(i)) return i
-}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore make web strict
ProjectNewsList.getProps = async ({ apolloClient, query, locale }) => {
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-ignore make web strict
- const year = getIntParam(query.y)
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-ignore make web strict
- const month = year && getIntParam(query.m)
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-ignore make web strict
- const selectedPage = getIntParam(query.page) ?? 1
+ const year = getIntParam(query.y, { minValue: 1000, maxValue: 9999 })
+ const month = year && getIntParam(query.m, { minValue: 1, maxValue: 12 })
+ const selectedPage = getIntParam(query.page, { minValue: 1 }) ?? 1
const projectPage = (
await Promise.resolve(
@@ -300,9 +293,7 @@ ProjectNewsList.getProps = async ({ apolloClient, query, locale }) => {
})
// map data here to reduce data processing in component
.then((variables) =>
- variables.data.getNamespace?.fields
- ? JSON.parse(variables.data.getNamespace.fields)
- : {},
+ JSON.parse(variables?.data?.getNamespace?.fields || '{}'),
),
])
diff --git a/apps/web/screens/Search/Search.tsx b/apps/web/screens/Search/Search.tsx
index f788cfc1b250..86018074625d 100644
--- a/apps/web/screens/Search/Search.tsx
+++ b/apps/web/screens/Search/Search.tsx
@@ -66,7 +66,10 @@ import { useLinkResolver, usePlausible } from '@island.is/web/hooks'
import { useI18n } from '@island.is/web/i18n'
import { withMainLayout } from '@island.is/web/layouts/main'
import { CustomNextError } from '@island.is/web/units/errors'
-import { AnchorPageType } from '@island.is/web/utils/anchorPage'
+import {
+ AnchorPageType,
+ extractAnchorPageLinkType,
+} from '@island.is/web/utils/anchorPage'
import { hasProcessEntries } from '@island.is/web/utils/article'
import { Screen } from '../../types'
@@ -314,11 +317,8 @@ const Search: Screen = ({
}, [countResults.typesCount, getArticleCount, tagTitles])
const getItemLink = (item: SearchEntryType) => {
- if (
- item.__typename === 'AnchorPage' &&
- item.pageType === AnchorPageType.DIGITAL_ICELAND_SERVICE
- ) {
- return linkResolver('digitalicelandservicesdetailpage', [item.slug])
+ if (item.__typename === 'AnchorPage') {
+ return linkResolver(extractAnchorPageLinkType(item), [item.slug])
}
if (item.__typename === 'ManualChapterItem') {
diff --git a/apps/web/screens/ServiceWeb/SubPage/SubPage.tsx b/apps/web/screens/ServiceWeb/SubPage/SubPage.tsx
index 7c602ca8d74d..bfe31cb4d0bc 100644
--- a/apps/web/screens/ServiceWeb/SubPage/SubPage.tsx
+++ b/apps/web/screens/ServiceWeb/SubPage/SubPage.tsx
@@ -1,4 +1,3 @@
-import { Locale } from '@island.is/shared/types'
import groupBy from 'lodash/groupBy'
import NextLink from 'next/link'
import { useRouter } from 'next/router'
@@ -19,6 +18,7 @@ import {
Text,
TopicCard,
} from '@island.is/island-ui/core'
+import { Locale } from '@island.is/shared/types'
import { ServiceWebWrapper } from '@island.is/web/components'
import {
ContentLanguage,
@@ -41,6 +41,7 @@ import useContentfulId from '@island.is/web/hooks/useContentfulId'
import useLocalLinkTypeResolver from '@island.is/web/hooks/useLocalLinkTypeResolver'
import { useI18n } from '@island.is/web/i18n'
import { withMainLayout } from '@island.is/web/layouts/main'
+import { CustomNextError } from '@island.is/web/units/errors'
import { webRichText } from '@island.is/web/utils/richText'
import { Screen } from '../../../types'
@@ -431,16 +432,18 @@ SubPage.getProps = async ({ apolloClient, locale, query, res }) => {
const categorySlug = slugs[1]
const questionSlug = slugs[2] ?? undefined
- if (single(query.q)) {
+ const q = single(query.q)
+
+ if (q) {
if (res) {
res.writeHead(302, {
- Location: linkResolver(
- 'supportqna',
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-ignore make web strict
- [organizationSlug, categorySlug, single(query.q)],
- locale as Locale,
- ).href,
+ Location: encodeURI(
+ linkResolver(
+ 'supportqna',
+ [organizationSlug, categorySlug, q],
+ locale as Locale,
+ ).href,
+ ),
})
res.end()
}
@@ -519,6 +522,13 @@ SubPage.getProps = async ({ apolloClient, locale, query, res }) => {
}),
])
+ if (
+ categorySlug &&
+ (!singleSupportCategory || !singleSupportCategory?.data?.getSupportCategory)
+ ) {
+ throw new CustomNextError(404, 'Support category not found')
+ }
+
const organizationNamespace = JSON.parse(
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore make web strict
diff --git a/apps/web/screens/queries/PublicVehicleSearch.ts b/apps/web/screens/queries/PublicVehicleSearch.ts
index a3e0708d338b..c1ea4763549d 100644
--- a/apps/web/screens/queries/PublicVehicleSearch.ts
+++ b/apps/web/screens/queries/PublicVehicleSearch.ts
@@ -10,6 +10,7 @@ export const PUBLIC_VEHICLE_SEARCH_QUERY = gql`
vehicleCommercialName
color
newRegDate
+ firstRegDate
vehicleStatus
nextVehicleMainInspection
co2
diff --git a/apps/web/screens/queries/fragments.ts b/apps/web/screens/queries/fragments.ts
index 2c5b155a939d..983b4cf2f42c 100644
--- a/apps/web/screens/queries/fragments.ts
+++ b/apps/web/screens/queries/fragments.ts
@@ -173,6 +173,7 @@ export const slices = gql`
}
}
}
+ dividerOnTop
}
fragment FaqListFields on FaqList {
@@ -835,6 +836,7 @@ export const slices = gql`
xAxisValueType
customStyleConfig
reduceAndRoundValue
+ yAxisLabel
}
fragment ChartNumberBoxFields on ChartNumberBox {
diff --git a/apps/web/utils/queryParams.ts b/apps/web/utils/queryParams.ts
new file mode 100644
index 000000000000..94c46a2ce4ee
--- /dev/null
+++ b/apps/web/utils/queryParams.ts
@@ -0,0 +1,21 @@
+export const getIntParam = (
+ s: string | string[] | undefined,
+ range?: { minValue?: number; maxValue?: number },
+) => {
+ if (s === undefined) {
+ return undefined
+ }
+ const i = parseInt(Array.isArray(s) ? s[0] : s, 10)
+
+ if (Number.isNaN(i)) {
+ return undefined
+ }
+ if (range?.minValue !== undefined && i < range.minValue) {
+ return undefined
+ }
+ if (range?.maxValue !== undefined && i > range.maxValue) {
+ return undefined
+ }
+
+ return i
+}
diff --git a/charts/islandis/values.dev.yaml b/charts/islandis/values.dev.yaml
index c37074a33485..f1e667e15c4b 100644
--- a/charts/islandis/values.dev.yaml
+++ b/charts/islandis/values.dev.yaml
@@ -1379,6 +1379,117 @@ endorsement-system-api:
eks.amazonaws.com/role-arn: 'arn:aws:iam::013313053092:role/endorsement-system-api'
create: true
name: 'endorsement-system-api'
+endorsement-system-api-cleanup-worker:
+ args:
+ - '--no-experimental-fetch'
+ - 'main.js'
+ - '--job=cleanup'
+ command:
+ - 'node'
+ enabled: true
+ env:
+ DB_HOST: 'postgres-applications.internal'
+ DB_NAME: 'services_endorsements_api'
+ DB_REPLICAS_HOST: 'postgres-applications-reader.internal'
+ DB_USER: 'services_endorsements_api'
+ EMAIL_FROM_ADDRESS: 'development@island.is'
+ EMAIL_FROM_NAME: 'devland.is'
+ EMAIL_REGION: 'eu-west-1'
+ IDENTITY_SERVER_CLIENT_ID: '@island.is/clients/endorsement'
+ IDENTITY_SERVER_ISSUER_URL: 'https://identity-server.dev01.devland.is'
+ LOG_LEVEL: 'info'
+ NATIONAL_REGISTRY_B2C_CLIENT_ID: 'b464afdd-056b-406d-b650-6d41733cfeb7'
+ NATIONAL_REGISTRY_B2C_ENDPOINT: 'https://skraidentitydev.b2clogin.com/skraidentitydev.onmicrosoft.com/b2c_1_midlun_flow/oauth2/v2.0/token'
+ NATIONAL_REGISTRY_B2C_PATH: 'IS-DEV/GOV/10001/SKRA-Cloud-Protected/Midlun-v1'
+ NATIONAL_REGISTRY_B2C_SCOPE: 'https://skraidentitydev.onmicrosoft.com/midlun/.default'
+ NODE_OPTIONS: '--max-old-space-size=230 -r dd-trace/init'
+ SERVERSIDE_FEATURES_ON: ''
+ XROAD_BASE_PATH: 'http://securityserver.dev01.devland.is'
+ XROAD_BASE_PATH_WITH_ENV: 'http://securityserver.dev01.devland.is/r1/IS-DEV'
+ XROAD_CLIENT_ID: 'IS-DEV/GOV/10000/island-is-client'
+ XROAD_NATIONAL_REGISTRY_REDIS_NODES: '["clustercfg.general-redis-cluster-group.5fzau3.euw1.cache.amazonaws.com:6379"]'
+ XROAD_NATIONAL_REGISTRY_SERVICE_PATH: 'IS-DEV/GOV/10001/SKRA-Protected/Einstaklingar-v1'
+ XROAD_TJODSKRA_API_PATH: '/SKRA-Protected/Einstaklingar-v1'
+ XROAD_TJODSKRA_MEMBER_CODE: '10001'
+ XROAD_TLS_BASE_PATH: 'https://securityserver.dev01.devland.is'
+ XROAD_TLS_BASE_PATH_WITH_ENV: 'https://securityserver.dev01.devland.is/r1/IS-DEV'
+ grantNamespaces:
+ - 'islandis'
+ - 'application-system'
+ grantNamespacesEnabled: true
+ healthCheck:
+ liveness:
+ initialDelaySeconds: 3
+ path: '/liveness'
+ timeoutSeconds: 3
+ readiness:
+ initialDelaySeconds: 3
+ path: '/liveness'
+ timeoutSeconds: 3
+ hpa:
+ scaling:
+ metric:
+ cpuAverageUtilization: 90
+ nginxRequestsIrate: 5
+ replicas:
+ max: 3
+ min: 1
+ image:
+ repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-endorsements-api'
+ initContainer:
+ containers:
+ - args:
+ - 'sequelize-cli'
+ - 'db:migrate'
+ command:
+ - 'npx'
+ name: 'migrations'
+ resources:
+ limits:
+ cpu: '200m'
+ memory: '256Mi'
+ requests:
+ cpu: '50m'
+ memory: '128Mi'
+ env:
+ DB_HOST: 'postgres-applications.internal'
+ DB_NAME: 'services_endorsements_api'
+ DB_REPLICAS_HOST: 'postgres-applications-reader.internal'
+ DB_USER: 'services_endorsements_api'
+ SERVERSIDE_FEATURES_ON: ''
+ secrets:
+ DB_PASS: '/k8s/services-endorsements-api/DB_PASSWORD'
+ namespace: 'endorsement-system'
+ podDisruptionBudget:
+ maxUnavailable: 1
+ podSecurityContext:
+ fsGroup: 65534
+ pvcs: []
+ replicaCount:
+ default: 1
+ max: 3
+ min: 1
+ resources:
+ limits:
+ cpu: '200m'
+ memory: '256Mi'
+ requests:
+ cpu: '100m'
+ memory: '128Mi'
+ schedule: '@hourly'
+ secrets:
+ CONFIGCAT_SDK_KEY: '/k8s/configcat/CONFIGCAT_SDK_KEY'
+ DB_PASS: '/k8s/services-endorsements-api/DB_PASSWORD'
+ IDENTITY_SERVER_CLIENT_SECRET: '/k8s/endorsement-system-api/IDS-shared-secret'
+ NATIONAL_REGISTRY_B2C_CLIENT_SECRET: '/k8s/api/NATIONAL_REGISTRY_B2C_CLIENT_SECRET'
+ securityContext:
+ allowPrivilegeEscalation: false
+ privileged: false
+ serviceAccount:
+ annotations:
+ eks.amazonaws.com/role-arn: 'arn:aws:iam::013313053092:role/endorsement-system-api-cleanup-worker'
+ create: true
+ name: 'endorsement-system-api-cleanup-worker'
external-contracts-tests:
enabled: true
env:
diff --git a/charts/islandis/values.prod.yaml b/charts/islandis/values.prod.yaml
index 6ccb3917b3bd..82322bfc41c4 100644
--- a/charts/islandis/values.prod.yaml
+++ b/charts/islandis/values.prod.yaml
@@ -1374,6 +1374,117 @@ endorsement-system-api:
eks.amazonaws.com/role-arn: 'arn:aws:iam::251502586493:role/endorsement-system-api'
create: true
name: 'endorsement-system-api'
+endorsement-system-api-cleanup-worker:
+ args:
+ - '--no-experimental-fetch'
+ - 'main.js'
+ - '--job=cleanup'
+ command:
+ - 'node'
+ enabled: true
+ env:
+ DB_HOST: 'postgres-applications.internal'
+ DB_NAME: 'services_endorsements_api'
+ DB_REPLICAS_HOST: 'postgres-applications.internal'
+ DB_USER: 'services_endorsements_api'
+ EMAIL_FROM_ADDRESS: 'noreply@island.is'
+ EMAIL_FROM_NAME: 'island.is'
+ EMAIL_REGION: 'eu-west-1'
+ IDENTITY_SERVER_CLIENT_ID: '@island.is/clients/endorsement'
+ IDENTITY_SERVER_ISSUER_URL: 'https://innskra.island.is'
+ LOG_LEVEL: 'info'
+ NATIONAL_REGISTRY_B2C_CLIENT_ID: '2304d7ca-7ed3-4188-8b6d-e1b7e0e3df7f'
+ NATIONAL_REGISTRY_B2C_ENDPOINT: 'https://skraidentity.b2clogin.com/skraidentity.onmicrosoft.com/b2c_1_midlun_flow/oauth2/v2.0/token'
+ NATIONAL_REGISTRY_B2C_PATH: 'IS/GOV/6503760649/SKRA-Cloud-Protected/Midlun-v1'
+ NATIONAL_REGISTRY_B2C_SCOPE: 'https://skraidentity.onmicrosoft.com/midlun/.default'
+ NODE_OPTIONS: '--max-old-space-size=230 -r dd-trace/init'
+ SERVERSIDE_FEATURES_ON: 'driving-license-use-v1-endpoint-for-v2-comms'
+ XROAD_BASE_PATH: 'http://securityserver.island.is'
+ XROAD_BASE_PATH_WITH_ENV: 'http://securityserver.island.is/r1/IS'
+ XROAD_CLIENT_ID: 'IS/GOV/5501692829/island-is-client'
+ XROAD_NATIONAL_REGISTRY_REDIS_NODES: '["clustercfg.general-redis-cluster-group.whakos.euw1.cache.amazonaws.com:6379"]'
+ XROAD_NATIONAL_REGISTRY_SERVICE_PATH: 'IS/GOV/6503760649/SKRA-Protected/Einstaklingar-v1'
+ XROAD_TJODSKRA_API_PATH: '/SKRA-Protected/Einstaklingar-v1'
+ XROAD_TJODSKRA_MEMBER_CODE: '6503760649'
+ XROAD_TLS_BASE_PATH: 'https://securityserver.island.is'
+ XROAD_TLS_BASE_PATH_WITH_ENV: 'https://securityserver.island.is/r1/IS'
+ grantNamespaces:
+ - 'islandis'
+ - 'application-system'
+ grantNamespacesEnabled: true
+ healthCheck:
+ liveness:
+ initialDelaySeconds: 3
+ path: '/liveness'
+ timeoutSeconds: 3
+ readiness:
+ initialDelaySeconds: 3
+ path: '/liveness'
+ timeoutSeconds: 3
+ hpa:
+ scaling:
+ metric:
+ cpuAverageUtilization: 90
+ nginxRequestsIrate: 5
+ replicas:
+ max: 10
+ min: 3
+ image:
+ repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-endorsements-api'
+ initContainer:
+ containers:
+ - args:
+ - 'sequelize-cli'
+ - 'db:migrate'
+ command:
+ - 'npx'
+ name: 'migrations'
+ resources:
+ limits:
+ cpu: '200m'
+ memory: '256Mi'
+ requests:
+ cpu: '50m'
+ memory: '128Mi'
+ env:
+ DB_HOST: 'postgres-applications.internal'
+ DB_NAME: 'services_endorsements_api'
+ DB_REPLICAS_HOST: 'postgres-applications.internal'
+ DB_USER: 'services_endorsements_api'
+ SERVERSIDE_FEATURES_ON: 'driving-license-use-v1-endpoint-for-v2-comms'
+ secrets:
+ DB_PASS: '/k8s/services-endorsements-api/DB_PASSWORD'
+ namespace: 'endorsement-system'
+ podDisruptionBudget:
+ maxUnavailable: 1
+ podSecurityContext:
+ fsGroup: 65534
+ pvcs: []
+ replicaCount:
+ default: 3
+ max: 10
+ min: 3
+ resources:
+ limits:
+ cpu: '200m'
+ memory: '256Mi'
+ requests:
+ cpu: '100m'
+ memory: '128Mi'
+ schedule: '@hourly'
+ secrets:
+ CONFIGCAT_SDK_KEY: '/k8s/configcat/CONFIGCAT_SDK_KEY'
+ DB_PASS: '/k8s/services-endorsements-api/DB_PASSWORD'
+ IDENTITY_SERVER_CLIENT_SECRET: '/k8s/endorsement-system-api/IDS-shared-secret'
+ NATIONAL_REGISTRY_B2C_CLIENT_SECRET: '/k8s/api/NATIONAL_REGISTRY_B2C_CLIENT_SECRET'
+ securityContext:
+ allowPrivilegeEscalation: false
+ privileged: false
+ serviceAccount:
+ annotations:
+ eks.amazonaws.com/role-arn: 'arn:aws:iam::251502586493:role/endorsement-system-api-cleanup-worker'
+ create: true
+ name: 'endorsement-system-api-cleanup-worker'
global:
env:
AUDIT_GROUP_NAME: '/island-is/audit-log'
diff --git a/charts/islandis/values.staging.yaml b/charts/islandis/values.staging.yaml
index d779344442f4..cc73a07a5347 100644
--- a/charts/islandis/values.staging.yaml
+++ b/charts/islandis/values.staging.yaml
@@ -1250,6 +1250,117 @@ endorsement-system-api:
eks.amazonaws.com/role-arn: 'arn:aws:iam::261174024191:role/endorsement-system-api'
create: true
name: 'endorsement-system-api'
+endorsement-system-api-cleanup-worker:
+ args:
+ - '--no-experimental-fetch'
+ - 'main.js'
+ - '--job=cleanup'
+ command:
+ - 'node'
+ enabled: true
+ env:
+ DB_HOST: 'postgres-applications.internal'
+ DB_NAME: 'services_endorsements_api'
+ DB_REPLICAS_HOST: 'postgres-applications.internal'
+ DB_USER: 'services_endorsements_api'
+ EMAIL_FROM_ADDRESS: 'development@island.is'
+ EMAIL_FROM_NAME: 'devland.is'
+ EMAIL_REGION: 'eu-west-1'
+ IDENTITY_SERVER_CLIENT_ID: '@island.is/clients/endorsement'
+ IDENTITY_SERVER_ISSUER_URL: 'https://identity-server.staging01.devland.is'
+ LOG_LEVEL: 'info'
+ NATIONAL_REGISTRY_B2C_CLIENT_ID: 'ca128c23-b43c-443d-bade-ec5a146a933f'
+ NATIONAL_REGISTRY_B2C_ENDPOINT: 'https://skraidentitydev.b2clogin.com/skraidentitystaging.onmicrosoft.com/b2c_1_midlun_flow/oauth2/v2.0/token'
+ NATIONAL_REGISTRY_B2C_PATH: 'IS-TEST/GOV/6503760649/SKRA-Cloud-Protected/Midlun-v1'
+ NATIONAL_REGISTRY_B2C_SCOPE: 'https://skraidentitystaging.onmicrosoft.com/midlun/.default'
+ NODE_OPTIONS: '--max-old-space-size=230 -r dd-trace/init'
+ SERVERSIDE_FEATURES_ON: ''
+ XROAD_BASE_PATH: 'http://securityserver.staging01.devland.is'
+ XROAD_BASE_PATH_WITH_ENV: 'http://securityserver.staging01.devland.is/r1/IS-TEST'
+ XROAD_CLIENT_ID: 'IS-TEST/GOV/5501692829/island-is-client'
+ XROAD_NATIONAL_REGISTRY_REDIS_NODES: '["clustercfg.general-redis-cluster-group.ab9ckb.euw1.cache.amazonaws.com:6379"]'
+ XROAD_NATIONAL_REGISTRY_SERVICE_PATH: 'IS-TEST/GOV/6503760649/SKRA-Protected/Einstaklingar-v1'
+ XROAD_TJODSKRA_API_PATH: '/SKRA-Protected/Einstaklingar-v1'
+ XROAD_TJODSKRA_MEMBER_CODE: '6503760649'
+ XROAD_TLS_BASE_PATH: 'https://securityserver.staging01.devland.is'
+ XROAD_TLS_BASE_PATH_WITH_ENV: 'https://securityserver.staging01.devland.is/r1/IS-TEST'
+ grantNamespaces:
+ - 'islandis'
+ - 'application-system'
+ grantNamespacesEnabled: true
+ healthCheck:
+ liveness:
+ initialDelaySeconds: 3
+ path: '/liveness'
+ timeoutSeconds: 3
+ readiness:
+ initialDelaySeconds: 3
+ path: '/liveness'
+ timeoutSeconds: 3
+ hpa:
+ scaling:
+ metric:
+ cpuAverageUtilization: 90
+ nginxRequestsIrate: 5
+ replicas:
+ max: 3
+ min: 1
+ image:
+ repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-endorsements-api'
+ initContainer:
+ containers:
+ - args:
+ - 'sequelize-cli'
+ - 'db:migrate'
+ command:
+ - 'npx'
+ name: 'migrations'
+ resources:
+ limits:
+ cpu: '200m'
+ memory: '256Mi'
+ requests:
+ cpu: '50m'
+ memory: '128Mi'
+ env:
+ DB_HOST: 'postgres-applications.internal'
+ DB_NAME: 'services_endorsements_api'
+ DB_REPLICAS_HOST: 'postgres-applications.internal'
+ DB_USER: 'services_endorsements_api'
+ SERVERSIDE_FEATURES_ON: ''
+ secrets:
+ DB_PASS: '/k8s/services-endorsements-api/DB_PASSWORD'
+ namespace: 'endorsement-system'
+ podDisruptionBudget:
+ maxUnavailable: 1
+ podSecurityContext:
+ fsGroup: 65534
+ pvcs: []
+ replicaCount:
+ default: 1
+ max: 3
+ min: 1
+ resources:
+ limits:
+ cpu: '200m'
+ memory: '256Mi'
+ requests:
+ cpu: '100m'
+ memory: '128Mi'
+ schedule: '@hourly'
+ secrets:
+ CONFIGCAT_SDK_KEY: '/k8s/configcat/CONFIGCAT_SDK_KEY'
+ DB_PASS: '/k8s/services-endorsements-api/DB_PASSWORD'
+ IDENTITY_SERVER_CLIENT_SECRET: '/k8s/endorsement-system-api/IDS-shared-secret'
+ NATIONAL_REGISTRY_B2C_CLIENT_SECRET: '/k8s/api/NATIONAL_REGISTRY_B2C_CLIENT_SECRET'
+ securityContext:
+ allowPrivilegeEscalation: false
+ privileged: false
+ serviceAccount:
+ annotations:
+ eks.amazonaws.com/role-arn: 'arn:aws:iam::261174024191:role/endorsement-system-api-cleanup-worker'
+ create: true
+ name: 'endorsement-system-api-cleanup-worker'
global:
env:
AUDIT_GROUP_NAME: '/island-is/audit-log'
diff --git a/infra/src/cli/cli.ts b/infra/src/cli/cli.ts
index a83658a6af72..546cfc242792 100644
--- a/infra/src/cli/cli.ts
+++ b/infra/src/cli/cli.ts
@@ -57,19 +57,22 @@ const cli = yargs(process.argv.slice(2))
'Render environment variables needed by service.\nThis is to be used when developing locally and loading of the environment variables for "dev" environment is needed.',
(yargs) => {
return yargs
- .option('service', { demandOption: true, array: true, type: 'string' })
+ .option('services', { demandOption: true, array: true, type: 'string' })
.option('json', { type: 'boolean', default: false })
.option('dry', { type: 'boolean', default: true })
.option('no-update-secrets', { type: 'boolean', default: false })
},
- async (argv) =>
- await renderLocalServices({
- services: argv.service,
+ async (argv) => {
+ const services = await renderLocalServices({
+ services: argv.services,
dryRun: argv.dry,
json: argv.json,
print: true,
noUpdateSecrets: argv['no-update-secrets'],
- }),
+ })
+
+ return
+ },
)
.command(
'run-local-env',
diff --git a/infra/src/dsl/README.md b/infra/src/dsl/README.md
index 7e310be4f08b..d0b2f628f918 100644
--- a/infra/src/dsl/README.md
+++ b/infra/src/dsl/README.md
@@ -4,7 +4,7 @@
In order to ensure the most effortless and error-free way to connect our code to the execution environment we created a Domain-Specific Language(DSL) to support an expressive way for developers to define the services' expected configuration. The DSL is written intentionally such that it enforces conventions and principles we have.
-Additionally, we have started experimenting with using the DSL to generate _bash_ commands for running locally services. The DSL is abstract enough that is not tied to any one specific execution environment and leaves our options open to generating pretty much any deployment environments we might want to explore in the future - docker-compose, raw k8s manifests, etc.
+Additionally, we have started experimenting with using the DSL to generate _bash_ commands for running locally services. The DSL is abstract enough that is not tied to any one specific execution environment and leaves our options open to generating pretty much any deployment environments we might want to explore in the future - docker compose, raw k8s manifests, etc.
## A few key abstractions
diff --git a/infra/src/uber-charts/islandis.ts b/infra/src/uber-charts/islandis.ts
index 7c2f09f796c0..5239d4333d88 100644
--- a/infra/src/uber-charts/islandis.ts
+++ b/infra/src/uber-charts/islandis.ts
@@ -36,6 +36,7 @@ import {
userNotificationCleanUpWorkerSetup,
userNotificationWorkerSetup,
} from '../../../apps/services/user-notification/infra/user-notification'
+import { endorsementSystemCleanUpWorkerSetup } from '../../../apps/services/endorsements/api/infra/endorsement-system-api'
import { serviceSetup as adsApiSetup } from '../../../apps/air-discount-scheme/api/infra/api'
import { serviceSetup as adsWebSetup } from '../../../apps/air-discount-scheme/web/infra/web'
@@ -134,6 +135,9 @@ const userNotificationWorkerService = userNotificationWorkerSetup({
const userNotificationCleanupWorkerService =
userNotificationCleanUpWorkerSetup()
+const endorsementSystemCleanUpWorkerService =
+ endorsementSystemCleanUpWorkerSetup()
+
const githubActionsCache = githubActionsCacheSetup()
const externalContractsTests = externalContractsTestsSetup()
@@ -165,6 +169,7 @@ export const Services: EnvironmentServices = {
userNotificationService,
userNotificationWorkerService,
userNotificationCleanupWorkerService,
+ endorsementSystemCleanUpWorkerService,
licenseApi,
sessionsService,
sessionsWorker,
@@ -200,6 +205,7 @@ export const Services: EnvironmentServices = {
userNotificationService,
userNotificationWorkerService,
userNotificationCleanupWorkerService,
+ endorsementSystemCleanUpWorkerService,
licenseApi,
sessionsService,
sessionsWorker,
@@ -233,6 +239,7 @@ export const Services: EnvironmentServices = {
userNotificationService,
userNotificationWorkerService,
userNotificationCleanupWorkerService,
+ endorsementSystemCleanUpWorkerService,
externalContractsTests,
appSystemApiWorker,
contentfulEntryTagger,
@@ -254,6 +261,7 @@ export const ExcludedFeatureDeploymentServices: ServiceBuilder[] = [
userNotificationService,
userNotificationWorkerService,
userNotificationCleanupWorkerService,
+ endorsementSystemCleanUpWorkerService,
contentfulEntryTagger,
searchIndexer,
contentfulApps,
diff --git a/libs/api-catalogue/elastic/README.md b/libs/api-catalogue/elastic/README.md
index 385d62260310..1067116f3e0f 100644
--- a/libs/api-catalogue/elastic/README.md
+++ b/libs/api-catalogue/elastic/README.md
@@ -9,7 +9,7 @@ Run `ng test api-catalogue-elastic` to execute the unit tests via [Jest](https:/
Local development uses a docker container for elasticsearch.
The `elastic.yml` sets up a docker container named `es01` and needs to be running.
-For the initial setup the command: `docker-compose -f .\libs\api-catalogue\elastic\elastic.yml up` initiates the container which can then be managed through Docker.
+For the initial setup the command: `docker compose -f .\libs\api-catalogue\elastic\elastic.yml up` initiates the container which can then be managed through Docker.
After the `es01` is running it can be initialized with data from `initialData.json` using curl command:
`curl -H 'Content-Type: application/x-ndjson' -XPOST localhost:9200/_bulk --data-binary '@./libs/api-catalogue/elastic/initialData.txt'`
diff --git a/libs/api/domains/financial-statement-cemetery/.eslintrc.json b/libs/api/domains/financial-statement-cemetery/.eslintrc.json
new file mode 100644
index 000000000000..632e9b0e2225
--- /dev/null
+++ b/libs/api/domains/financial-statement-cemetery/.eslintrc.json
@@ -0,0 +1,18 @@
+{
+ "extends": ["../../../../.eslintrc.json"],
+ "ignorePatterns": ["!**/*"],
+ "overrides": [
+ {
+ "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
+ "rules": {}
+ },
+ {
+ "files": ["*.ts", "*.tsx"],
+ "rules": {}
+ },
+ {
+ "files": ["*.js", "*.jsx"],
+ "rules": {}
+ }
+ ]
+}
diff --git a/libs/api/domains/financial-statement-cemetery/README.md b/libs/api/domains/financial-statement-cemetery/README.md
new file mode 100644
index 000000000000..c6681ee81827
--- /dev/null
+++ b/libs/api/domains/financial-statement-cemetery/README.md
@@ -0,0 +1,7 @@
+# api-domains-financial-statement-cemetery
+
+This library was generated with [Nx](https://nx.dev).
+
+## Running unit tests
+
+Run `nx test api-domains-financial-statement-cemetery` to execute the unit tests via [Jest](https://jestjs.io).
diff --git a/libs/api/domains/financial-statement-cemetery/jest.config.ts b/libs/api/domains/financial-statement-cemetery/jest.config.ts
new file mode 100644
index 000000000000..880743b31e26
--- /dev/null
+++ b/libs/api/domains/financial-statement-cemetery/jest.config.ts
@@ -0,0 +1,12 @@
+/* eslint-disable */
+export default {
+ displayName: 'api-domains-financial-statement-cemetery',
+ preset: '../../../../jest.preset.js',
+ testEnvironment: 'node',
+ transform: {
+ '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }],
+ },
+ moduleFileExtensions: ['ts', 'js', 'html'],
+ coverageDirectory:
+ '../../../../coverage/libs/api/domains/financial-statement-cemetery',
+}
diff --git a/libs/api/domains/financial-statement-cemetery/project.json b/libs/api/domains/financial-statement-cemetery/project.json
new file mode 100644
index 000000000000..cb9487d30f43
--- /dev/null
+++ b/libs/api/domains/financial-statement-cemetery/project.json
@@ -0,0 +1,19 @@
+{
+ "name": "api-domains-financial-statement-cemetery",
+ "$schema": "../../../../node_modules/nx/schemas/project-schema.json",
+ "sourceRoot": "libs/api/domains/financial-statement-cemetery/src",
+ "projectType": "library",
+ "tags": ["lib:api", "scope:api"],
+ "targets": {
+ "lint": {
+ "executor": "@nx/eslint:lint"
+ },
+ "test": {
+ "executor": "@nx/jest:jest",
+ "outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
+ "options": {
+ "jestConfig": "libs/api/domains/financial-statement-cemetery/jest.config.ts"
+ }
+ }
+ }
+}
diff --git a/libs/api/domains/financial-statement-cemetery/src/index.ts b/libs/api/domains/financial-statement-cemetery/src/index.ts
new file mode 100644
index 000000000000..6ed2c3549634
--- /dev/null
+++ b/libs/api/domains/financial-statement-cemetery/src/index.ts
@@ -0,0 +1,2 @@
+export * from './lib/financialStatementCemetery.module'
+export * from './lib/financialStatementCemetery.service'
diff --git a/libs/api/domains/financial-statement-cemetery/src/lib/dto/clientFinancialLimit.input.ts b/libs/api/domains/financial-statement-cemetery/src/lib/dto/clientFinancialLimit.input.ts
new file mode 100644
index 000000000000..9e26cfb11c8a
--- /dev/null
+++ b/libs/api/domains/financial-statement-cemetery/src/lib/dto/clientFinancialLimit.input.ts
@@ -0,0 +1,13 @@
+import { Field, InputType } from '@nestjs/graphql'
+import { IsString } from 'class-validator'
+
+@InputType()
+export class CemeteryClientFinancialLimitInput {
+ @Field(() => String)
+ @IsString()
+ clientType!: string
+
+ @Field(() => String)
+ @IsString()
+ year!: string
+}
diff --git a/libs/api/domains/financial-statement-cemetery/src/lib/financialStatementCemetery.module.ts b/libs/api/domains/financial-statement-cemetery/src/lib/financialStatementCemetery.module.ts
new file mode 100644
index 000000000000..fb869b4413c8
--- /dev/null
+++ b/libs/api/domains/financial-statement-cemetery/src/lib/financialStatementCemetery.module.ts
@@ -0,0 +1,20 @@
+import { Module } from '@nestjs/common'
+import { ConfigModule } from '@island.is/nest/config'
+import {
+ FinancialStatementsInaoClientConfig,
+ FinancialStatementsInaoClientModule,
+ FinancialStatementsInaoClientService,
+} from '@island.is/clients/financial-statements-inao'
+import { FinancialStatementCemeteryResolver } from './financialStatementCemetery.resolver'
+
+@Module({
+ imports: [
+ ConfigModule.forRoot({
+ load: [FinancialStatementsInaoClientConfig],
+ }),
+ FinancialStatementsInaoClientModule,
+ ],
+ providers: [FinancialStatementCemeteryResolver],
+ exports: [],
+})
+export class ApiDomainsFinancialStatementCemeteryModule {}
diff --git a/libs/api/domains/financial-statement-cemetery/src/lib/financialStatementCemetery.resolver.ts b/libs/api/domains/financial-statement-cemetery/src/lib/financialStatementCemetery.resolver.ts
new file mode 100644
index 000000000000..cf1cc62e1ad3
--- /dev/null
+++ b/libs/api/domains/financial-statement-cemetery/src/lib/financialStatementCemetery.resolver.ts
@@ -0,0 +1,62 @@
+import {
+ CurrentUser,
+ IdsUserGuard,
+ Scopes,
+ ScopesGuard,
+ User,
+} from '@island.is/auth-nest-tools'
+import { UseGuards } from '@nestjs/common'
+import { ApiScope } from '@island.is/auth/scopes'
+import { FinancialStatementCemeteryService } from './financialStatementCemetery.service'
+import { Args, Query, Resolver } from '@nestjs/graphql'
+import { ClientType } from './models/clientType.model'
+import { Config } from './models/config.model'
+import { TaxInfo } from './models/taxInfo.model'
+import { CemeteryClientFinancialLimitInput } from './dto/clientFinancialLimit.input'
+
+@UseGuards(IdsUserGuard, ScopesGuard)
+@Scopes(ApiScope.internal, ApiScope.internalProcuring)
+@Resolver()
+export class FinancialStatementCemeteryResolver {
+ constructor(
+ private financialStatementsService: FinancialStatementCemeteryService,
+ ) {}
+
+ @Query(() => [ClientType], { nullable: true })
+ async financialStatementsInaoClientTypes() {
+ return this.financialStatementsService.getClientTypes()
+ }
+
+ @Query(() => ClientType, { nullable: true })
+ async financialStatementsInaoCurrentUserClientType(
+ @CurrentUser() user: User,
+ ): Promise {
+ return this.financialStatementsService.getUserClientType(user.nationalId)
+ }
+
+ @Query(() => Number, { nullable: true })
+ async financialStatementsInaoClientFinancialLimit(
+ @Args('input') input: CemeteryClientFinancialLimitInput,
+ ) {
+ return this.financialStatementsService.getClientFinancialLimit(
+ input.clientType,
+ input.year,
+ )
+ }
+
+ @Query(() => [Config])
+ async financialStatementsInaoConfig() {
+ return this.financialStatementsService.getConfig()
+ }
+
+ @Query(() => [TaxInfo])
+ async financialStatementsInaoTaxInfo(
+ @CurrentUser() user: User,
+ @Args('year') year: string,
+ ) {
+ return this.financialStatementsService.getTaxInformation(
+ user.nationalId,
+ year,
+ )
+ }
+}
diff --git a/libs/api/domains/financial-statement-cemetery/src/lib/financialStatementCemetery.service.ts b/libs/api/domains/financial-statement-cemetery/src/lib/financialStatementCemetery.service.ts
new file mode 100644
index 000000000000..d8c7852fcd0a
--- /dev/null
+++ b/libs/api/domains/financial-statement-cemetery/src/lib/financialStatementCemetery.service.ts
@@ -0,0 +1,32 @@
+import { FinancialStatementsInaoClientService } from '@island.is/clients/financial-statements-inao'
+import { Injectable } from '@nestjs/common'
+import * as kennitala from 'kennitala'
+
+@Injectable()
+export class FinancialStatementCemeteryService {
+ constructor(private dataverseClient: FinancialStatementsInaoClientService) {}
+
+ async getClientTypes() {
+ return this.dataverseClient.getClientTypes()
+ }
+
+ async getUserClientType(nationalId: string) {
+ if (kennitala.isPerson(nationalId)) {
+ return this.dataverseClient.getClientType('Einstaklingur')
+ } else {
+ return this.dataverseClient.getUserClientType(nationalId)
+ }
+ }
+
+ async getClientFinancialLimit(clientType: string, year: string) {
+ return this.dataverseClient.getClientFinancialLimit(clientType, year)
+ }
+
+ async getConfig() {
+ return this.dataverseClient.getConfig()
+ }
+
+ async getTaxInformation(nationalId: string, year: string) {
+ return this.dataverseClient.getTaxInformationValues(nationalId, year)
+ }
+}
diff --git a/libs/api/domains/financial-statement-cemetery/src/lib/models/clientType.model.ts b/libs/api/domains/financial-statement-cemetery/src/lib/models/clientType.model.ts
new file mode 100644
index 000000000000..0e32a379049a
--- /dev/null
+++ b/libs/api/domains/financial-statement-cemetery/src/lib/models/clientType.model.ts
@@ -0,0 +1,10 @@
+import { Field, ObjectType } from '@nestjs/graphql'
+
+@ObjectType('FinancialStatementCemeteryClientType')
+export class ClientType {
+ @Field()
+ value!: string
+
+ @Field()
+ label!: string
+}
diff --git a/libs/api/domains/financial-statement-cemetery/src/lib/models/config.model.ts b/libs/api/domains/financial-statement-cemetery/src/lib/models/config.model.ts
new file mode 100644
index 000000000000..62c4904ddc4a
--- /dev/null
+++ b/libs/api/domains/financial-statement-cemetery/src/lib/models/config.model.ts
@@ -0,0 +1,10 @@
+import { Field, ObjectType } from '@nestjs/graphql'
+
+@ObjectType('FinancialStatementCemeteryConfig')
+export class Config {
+ @Field()
+ key!: string
+
+ @Field()
+ value!: string
+}
diff --git a/libs/api/domains/financial-statement-cemetery/src/lib/models/taxInfo.model.ts b/libs/api/domains/financial-statement-cemetery/src/lib/models/taxInfo.model.ts
new file mode 100644
index 000000000000..ad972c635ec1
--- /dev/null
+++ b/libs/api/domains/financial-statement-cemetery/src/lib/models/taxInfo.model.ts
@@ -0,0 +1,10 @@
+import { Field, ObjectType } from '@nestjs/graphql'
+
+@ObjectType('FinancialStatementCemeteryTaxInfo')
+export class TaxInfo {
+ @Field()
+ key!: number
+
+ @Field()
+ value!: number
+}
diff --git a/libs/api/domains/financial-statement-cemetery/tsconfig.json b/libs/api/domains/financial-statement-cemetery/tsconfig.json
new file mode 100644
index 000000000000..4022fd4d0ad7
--- /dev/null
+++ b/libs/api/domains/financial-statement-cemetery/tsconfig.json
@@ -0,0 +1,22 @@
+{
+ "extends": "../../../../tsconfig.base.json",
+ "compilerOptions": {
+ "module": "commonjs",
+ "forceConsistentCasingInFileNames": true,
+ "strict": true,
+ "noImplicitOverride": true,
+ "noPropertyAccessFromIndexSignature": true,
+ "noImplicitReturns": true,
+ "noFallthroughCasesInSwitch": true
+ },
+ "files": [],
+ "include": [],
+ "references": [
+ {
+ "path": "./tsconfig.lib.json"
+ },
+ {
+ "path": "./tsconfig.spec.json"
+ }
+ ]
+}
diff --git a/libs/api/domains/financial-statement-cemetery/tsconfig.lib.json b/libs/api/domains/financial-statement-cemetery/tsconfig.lib.json
new file mode 100644
index 000000000000..e6b77320ab6a
--- /dev/null
+++ b/libs/api/domains/financial-statement-cemetery/tsconfig.lib.json
@@ -0,0 +1,16 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "outDir": "../../../../dist/out-tsc",
+ "declaration": true,
+ "types": ["node"],
+ "target": "es2021",
+ "strictNullChecks": true,
+ "noImplicitAny": true,
+ "strictBindCallApply": true,
+ "forceConsistentCasingInFileNames": true,
+ "noFallthroughCasesInSwitch": true
+ },
+ "include": ["src/**/*.ts"],
+ "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]
+}
diff --git a/libs/api/domains/financial-statement-cemetery/tsconfig.spec.json b/libs/api/domains/financial-statement-cemetery/tsconfig.spec.json
new file mode 100644
index 000000000000..6668655fc397
--- /dev/null
+++ b/libs/api/domains/financial-statement-cemetery/tsconfig.spec.json
@@ -0,0 +1,14 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "outDir": "../../../../dist/out-tsc",
+ "module": "commonjs",
+ "types": ["jest", "node"]
+ },
+ "include": [
+ "jest.config.ts",
+ "src/**/*.test.ts",
+ "src/**/*.spec.ts",
+ "src/**/*.d.ts"
+ ]
+}
diff --git a/libs/api/domains/occupational-licenses-v2/src/lib/models/license.model.ts b/libs/api/domains/occupational-licenses-v2/src/lib/models/license.model.ts
index 71749367beab..ba637d673c7b 100644
--- a/libs/api/domains/occupational-licenses-v2/src/lib/models/license.model.ts
+++ b/libs/api/domains/occupational-licenses-v2/src/lib/models/license.model.ts
@@ -23,8 +23,8 @@ export class License {
@Field({ nullable: true })
issuerTitle?: string
- @Field()
- profession!: string
+ @Field({ nullable: true })
+ profession?: string
@Field({ nullable: true })
permit?: string
diff --git a/libs/api/domains/occupational-licenses-v2/src/lib/occupationalLicensesV2.service.ts b/libs/api/domains/occupational-licenses-v2/src/lib/occupationalLicensesV2.service.ts
index b8a2ff125267..55abcf0b71da 100644
--- a/libs/api/domains/occupational-licenses-v2/src/lib/occupationalLicensesV2.service.ts
+++ b/libs/api/domains/occupational-licenses-v2/src/lib/occupationalLicensesV2.service.ts
@@ -72,7 +72,6 @@ export class OccupationalLicensesV2Service {
type: LicenseType.DISTRICT_COMMISSIONERS,
issuer: l.issuerId,
issuerTitle: l.issuerTitle,
- profession: l.title,
permit: l.title,
dateOfBirth: info(user.nationalId).birthday,
validFrom: l.validFrom,
@@ -110,7 +109,6 @@ export class OccupationalLicensesV2Service {
type: LicenseType.DISTRICT_COMMISSIONERS,
licenseHolderName: license.holderName,
issuer: license.licenseInfo.issuerId,
- profession: license.licenseInfo.title,
dateOfBirth: info(user.nationalId).birthday,
validFrom: license.licenseInfo.validFrom,
status: mapDistrictCommissionersLicenseStatusToStatus(
diff --git a/libs/api/domains/occupational-licenses/src/lib/occupationalLicenses.service.ts b/libs/api/domains/occupational-licenses/src/lib/occupationalLicenses.service.ts
index 6311eebd7252..8f08316cc97c 100644
--- a/libs/api/domains/occupational-licenses/src/lib/occupationalLicenses.service.ts
+++ b/libs/api/domains/occupational-licenses/src/lib/occupationalLicenses.service.ts
@@ -67,7 +67,7 @@ export class OccupationalLicensesService {
case 'WAIVED':
return OccupationalLicenseStatus.waived
default:
- this.logger.log('Unknown health directorate status', {
+ this.logger.warn('Unknown health directorate status', {
category: LOG_CATEGORY,
status: status,
})
diff --git a/libs/api/domains/official-journal-of-iceland-application/src/lib/ojoiApplication.resolver.ts b/libs/api/domains/official-journal-of-iceland-application/src/lib/ojoiApplication.resolver.ts
index 3cf976a4c693..4b681ff24ef4 100644
--- a/libs/api/domains/official-journal-of-iceland-application/src/lib/ojoiApplication.resolver.ts
+++ b/libs/api/domains/official-journal-of-iceland-application/src/lib/ojoiApplication.resolver.ts
@@ -10,6 +10,8 @@ import { PostCommentResponse } from '../models/postComment.response'
import { PostApplicationInput } from '../models/postApplication.input'
import { UseGuards } from '@nestjs/common'
import { CaseGetPriceResponse } from '../models/getPrice.response'
+import { GetPdfUrlResponse } from '../models/getPdfUrlResponse'
+import { GetPdfResponse } from '../models/getPdfResponse'
@Scopes(ApiScope.internal)
@UseGuards(IdsUserGuard, ScopesGuard)
@@ -47,4 +49,18 @@ export class OfficialJournalOfIcelandApplicationResolver {
async getPrice(@Args('id') id: string) {
return await this.ojoiApplicationService.getPrice(id)
}
+
+ @Query(() => GetPdfUrlResponse, {
+ name: 'officialJournalOfIcelandApplicationGetPdfUrl',
+ })
+ async getPdfUrl(@Args('id') id: string) {
+ return await this.ojoiApplicationService.getPdfUrl(id)
+ }
+
+ @Query(() => GetPdfResponse, {
+ name: 'officialJournalOfIcelandApplicationGetPdf',
+ })
+ async getPdf(@Args('id') id: string) {
+ return (await this.ojoiApplicationService.getPdf(id)).toString('base64')
+ }
}
diff --git a/libs/api/domains/official-journal-of-iceland-application/src/lib/ojoiApplication.service.ts b/libs/api/domains/official-journal-of-iceland-application/src/lib/ojoiApplication.service.ts
index e3a9d25e25be..a810f69c9345 100644
--- a/libs/api/domains/official-journal-of-iceland-application/src/lib/ojoiApplication.service.ts
+++ b/libs/api/domains/official-journal-of-iceland-application/src/lib/ojoiApplication.service.ts
@@ -17,9 +17,19 @@ export class OfficialJournalOfIcelandApplicationService {
async postComment(input: PostCommentInput) {
return this.ojoiApplicationService.postComment({
id: input.id,
- postApplicationComment: {
- comment: input.comment,
- },
+ // comment: input.comment,
+ })
+ }
+
+ async getPdfUrl(id: string) {
+ return this.ojoiApplicationService.getPdfUrl({
+ id,
+ })
+ }
+
+ async getPdf(id: string) {
+ return this.ojoiApplicationService.getPdf({
+ id,
})
}
diff --git a/libs/api/domains/official-journal-of-iceland-application/src/models/getPdfResponse.ts b/libs/api/domains/official-journal-of-iceland-application/src/models/getPdfResponse.ts
new file mode 100644
index 000000000000..3f9ecbdb49b5
--- /dev/null
+++ b/libs/api/domains/official-journal-of-iceland-application/src/models/getPdfResponse.ts
@@ -0,0 +1,7 @@
+import { Field, ObjectType } from '@nestjs/graphql'
+
+@ObjectType('OfficialJournalOfIcelandApplicationGetPdfResponse')
+export class GetPdfResponse {
+ @Field(() => String)
+ buffer!: Buffer
+}
diff --git a/libs/api/domains/official-journal-of-iceland-application/src/models/getPdfUrlResponse.ts b/libs/api/domains/official-journal-of-iceland-application/src/models/getPdfUrlResponse.ts
new file mode 100644
index 000000000000..5e3062492d49
--- /dev/null
+++ b/libs/api/domains/official-journal-of-iceland-application/src/models/getPdfUrlResponse.ts
@@ -0,0 +1,7 @@
+import { Field, ObjectType } from '@nestjs/graphql'
+
+@ObjectType('OfficialJournalOfIcelandApplicationGetPdfUrlResponse')
+export class GetPdfUrlResponse {
+ @Field(() => String)
+ url!: string
+}
diff --git a/libs/api/domains/official-journal-of-iceland/src/index.ts b/libs/api/domains/official-journal-of-iceland/src/index.ts
index dfae47f53bff..6795efda07ae 100644
--- a/libs/api/domains/official-journal-of-iceland/src/index.ts
+++ b/libs/api/domains/official-journal-of-iceland/src/index.ts
@@ -1,2 +1,8 @@
export { OfficialJournalOfIcelandModule } from './lib/officialJournalOfIceland.module'
export { OfficialJournalOfIcelandService } from './lib/officialJournalOfIceland.service'
+
+export {
+ AdvertSingleParams,
+ QueryParams,
+ TypeQueryParams,
+} from './lib/models/advert.input'
diff --git a/libs/api/domains/official-journal-of-iceland/src/lib/mapper.ts b/libs/api/domains/official-journal-of-iceland/src/lib/mapper.ts
deleted file mode 100644
index d68507e01313..000000000000
--- a/libs/api/domains/official-journal-of-iceland/src/lib/mapper.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { AdvertStatus } from './models/advert.model'
-export const mapAdvertStatus = (status?: string) => {
- if (!status) return AdvertStatus.Unknown
-
- switch (status) {
- case 'Virk':
- return AdvertStatus.Active
- case 'Afturkölluð':
- return AdvertStatus.Revoked
- case 'Drög':
- return AdvertStatus.Draft
- case 'Eldri auglýsing':
- return AdvertStatus.Old
- case 'Hafnað':
- return AdvertStatus.Rejected
- case 'Í bið':
- return AdvertStatus.Waiting
- case 'Í vinnslu':
- return AdvertStatus.InProgress
- case 'Innsend':
- return AdvertStatus.Submitted
- case 'Tilbúin til útgáfu':
- return AdvertStatus.ReadyForPublication
- case 'Útgefin':
- return AdvertStatus.Published
- default:
- return AdvertStatus.Unknown
- }
-}
diff --git a/libs/api/domains/official-journal-of-iceland/src/lib/models/advert.input.ts b/libs/api/domains/official-journal-of-iceland/src/lib/models/advert.input.ts
index 454b493d8e5f..ac167ed5ffcb 100644
--- a/libs/api/domains/official-journal-of-iceland/src/lib/models/advert.input.ts
+++ b/libs/api/domains/official-journal-of-iceland/src/lib/models/advert.input.ts
@@ -1,11 +1,7 @@
+import { AdvertSignatureTypeEnum } from '@island.is/clients/official-journal-of-iceland'
import { InputType, Field, registerEnumType } from '@nestjs/graphql'
-export enum AdvertSignatureBodyTypeEnum {
- Hefbundin = 'Hefðbundin',
- Nefnd = 'Nefnd',
-}
-
-registerEnumType(AdvertSignatureBodyTypeEnum, {
+registerEnumType(AdvertSignatureTypeEnum, {
name: 'OfficialJournalOfIcelandAdvertSignatureType',
})
@@ -99,8 +95,8 @@ export class AdvertSignatureData {
}
@InputType('OfficialJournalOfIcelandAdvertSignature')
export class AdvertSignature {
- @Field(() => AdvertSignatureBodyTypeEnum)
- type!: AdvertSignatureBodyTypeEnum
+ @Field(() => AdvertSignatureTypeEnum)
+ type!: AdvertSignatureTypeEnum
@Field(() => String, { nullable: true })
additional?: string
diff --git a/libs/api/domains/official-journal-of-iceland/src/lib/models/advert.model.ts b/libs/api/domains/official-journal-of-iceland/src/lib/models/advert.model.ts
index b512d3dc7443..9bd9576d0d79 100644
--- a/libs/api/domains/official-journal-of-iceland/src/lib/models/advert.model.ts
+++ b/libs/api/domains/official-journal-of-iceland/src/lib/models/advert.model.ts
@@ -1,20 +1,7 @@
+import { AdvertStatusEnum } from '@island.is/clients/official-journal-of-iceland'
import { Field, ID, Int, ObjectType, registerEnumType } from '@nestjs/graphql'
-export enum AdvertStatus {
- Active = 'Virk',
- Revoked = 'Afturkölluð',
- Draft = 'Drög',
- Old = 'Eldri auglýsing',
- Rejected = 'Hafnað',
- Waiting = 'Í bið',
- InProgress = 'Í vinnslu',
- Submitted = 'Innsend',
- ReadyForPublication = 'Tilbúin til útgáfu',
- Published = 'Útgefin',
- Unknown = 'Óþekkt',
-}
-
-registerEnumType(AdvertStatus, {
+registerEnumType(AdvertStatusEnum, {
name: 'OfficialJournalOfIcelandAdvertStatus',
})
@@ -119,8 +106,8 @@ export class Advert {
@Field(() => String)
title!: string
- @Field(() => AdvertStatus)
- status!: AdvertStatus
+ @Field(() => AdvertStatusEnum)
+ status!: AdvertStatusEnum
@Field(() => AdvertPublicationNumber)
publicationNumber!: AdvertPublicationNumber | null
diff --git a/libs/api/domains/official-journal-of-iceland/src/lib/officialJournalOfIceland.resolver.ts b/libs/api/domains/official-journal-of-iceland/src/lib/officialJournalOfIceland.resolver.ts
index 2e5627bca461..e96092c25c66 100644
--- a/libs/api/domains/official-journal-of-iceland/src/lib/officialJournalOfIceland.resolver.ts
+++ b/libs/api/domains/official-journal-of-iceland/src/lib/officialJournalOfIceland.resolver.ts
@@ -32,63 +32,63 @@ export class OfficialJournalOfIcelandResolver {
@Query(() => AdvertResponse, {
name: 'officialJournalOfIcelandAdvert',
})
- advert(@Args('params') params: AdvertSingleParams) {
- return this.ojoiService.advert(params)
+ getAdvertById(@Args('params') params: AdvertSingleParams) {
+ return this.ojoiService.getAdvertById(params)
}
@Query(() => AdvertsResponse, {
name: 'officialJournalOfIcelandAdverts',
})
- adverts(@Args('input') input: AdvertsInput) {
- return this.ojoiService.adverts(input)
+ getAdverts(@Args('input') input: AdvertsInput) {
+ return this.ojoiService.getAdverts(input)
}
@Query(() => AdvertDepartmentResponse, {
name: 'officialJournalOfIcelandDepartment',
})
- department(@Args('params') params: AdvertSingleParams) {
- return this.ojoiService.department(params)
+ getDepartmentById(@Args('params') params: AdvertSingleParams) {
+ return this.ojoiService.getDepartmentById(params)
}
@Query(() => AdvertDepartmentsResponse, {
name: 'officialJournalOfIcelandDepartments',
})
- departments(@Args('params') params: QueryParams) {
- return this.ojoiService.departments(params)
+ getDepartments(@Args('params') params: QueryParams) {
+ return this.ojoiService.getDepartments(params)
}
@Query(() => AdvertTypeResponse, {
name: 'officialJournalOfIcelandType',
})
- type(@Args('params') params: AdvertSingleParams) {
- return this.ojoiService.type(params)
+ getAdvertTypeById(@Args('params') params: AdvertSingleParams) {
+ return this.ojoiService.getAdvertTypeById(params)
}
@Query(() => AdvertTypesResponse, {
name: 'officialJournalOfIcelandTypes',
})
- types(@Args('params') params: TypeQueryParams) {
- return this.ojoiService.types(params)
+ getAdvertTypes(@Args('params') params: TypeQueryParams) {
+ return this.ojoiService.getAdvertTypes(params)
}
@Query(() => AdvertMainCategoriesResponse, {
name: 'officialJournalOfIcelandMainCategories',
})
- mainCategories(@Args('params') params: QueryParams) {
- return this.ojoiService.mainCategories(params)
+ getMainCategories(@Args('params') params: QueryParams) {
+ return this.ojoiService.getMainCategories(params)
}
@Query(() => AdvertCategoryResponse, {
name: 'officialJournalOfIcelandCategories',
})
- categories(@Args('params') params: QueryParams) {
- return this.ojoiService.categories(params)
+ getCategories(@Args('params') params: QueryParams) {
+ return this.ojoiService.getCategories(params)
}
@Query(() => AdvertInstitutionsResponse, {
name: 'officialJournalOfIcelandInstitutions',
})
- institutions(@Args('params') params: QueryParams) {
- return this.ojoiService.institutions(params)
+ getInstitutions(@Args('params') params: QueryParams) {
+ return this.ojoiService.getInstitutions(params)
}
}
diff --git a/libs/api/domains/official-journal-of-iceland/src/lib/officialJournalOfIceland.service.ts b/libs/api/domains/official-journal-of-iceland/src/lib/officialJournalOfIceland.service.ts
index 965a5c7c2d55..bf825bdc72eb 100644
--- a/libs/api/domains/official-journal-of-iceland/src/lib/officialJournalOfIceland.service.ts
+++ b/libs/api/domains/official-journal-of-iceland/src/lib/officialJournalOfIceland.service.ts
@@ -1,8 +1,7 @@
import {
- JournalControllerAdvertsRequest,
+ GetAdvertsRequest,
OfficialJournalOfIcelandClientService,
} from '@island.is/clients/official-journal-of-iceland'
-import { mapAdvertStatus } from './mapper'
import { Injectable } from '@nestjs/common'
import {
AdvertSingleParams,
@@ -25,63 +24,45 @@ export class OfficialJournalOfIcelandService {
private readonly ojoiService: OfficialJournalOfIcelandClientService,
) {}
- async department(params: AdvertSingleParams) {
- return await this.ojoiService.department(params)
+ async getDepartmentById(params: AdvertSingleParams) {
+ return await this.ojoiService.getDepartmentById(params)
}
- async departments(params: QueryParams): Promise {
- return await this.ojoiService.departments(params)
+ async getDepartments(
+ params: QueryParams,
+ ): Promise {
+ return await this.ojoiService.getDepartments(params)
}
- async mainCategories(
+ async getMainCategories(
params: QueryParams,
): Promise {
- return await this.ojoiService.mainCategories(params)
+ return await this.ojoiService.getMainCategories(params)
}
- async categories(params: QueryParams): Promise {
- return await this.ojoiService.categories(params)
+ async getCategories(params: QueryParams): Promise {
+ return await this.ojoiService.getCategories(params)
}
- async type(params: AdvertSingleParams) {
- return await this.ojoiService.type(params)
+ async getAdvertTypeById(params: AdvertSingleParams) {
+ return await this.ojoiService.getAdvertTypeById(params)
}
- async types(params: TypeQueryParams): Promise {
- return await this.ojoiService.types(params)
+ async getAdvertTypes(params: TypeQueryParams): Promise {
+ return await this.ojoiService.getAdvertTypes(params)
}
- async institutions(params: QueryParams): Promise {
- return await this.ojoiService.institutions(params)
+ async getInstitutions(
+ params: QueryParams,
+ ): Promise {
+ return await this.ojoiService.getInstitutions(params)
}
- async advert(params: AdvertSingleParams): Promise {
- const { advert } = await this.ojoiService.advert(params)
- return {
- advert: {
- ...advert,
- status: mapAdvertStatus(advert.status),
- },
- }
+ async getAdvertById(params: AdvertSingleParams): Promise {
+ return await this.ojoiService.getAdvertById(params)
}
- async adverts(
- input: JournalControllerAdvertsRequest,
- ): Promise {
- const adverts = await this.ojoiService.adverts(input)
-
- const mappedAdverts = adverts.adverts.map((advert) => {
- return {
- ...advert,
- status: mapAdvertStatus(advert.status),
- }
- })
-
- const response: AdvertsResponse = {
- adverts: mappedAdverts,
- paging: adverts.paging,
- }
-
- return response
+ async getAdverts(input: GetAdvertsRequest): Promise {
+ return await this.ojoiService.getAdverts(input)
}
}
diff --git a/libs/api/domains/vehicles/src/models/getPublicVehicleSearch.model.ts b/libs/api/domains/vehicles/src/models/getPublicVehicleSearch.model.ts
index 45621a72911e..32c97266371c 100644
--- a/libs/api/domains/vehicles/src/models/getPublicVehicleSearch.model.ts
+++ b/libs/api/domains/vehicles/src/models/getPublicVehicleSearch.model.ts
@@ -23,6 +23,9 @@ export class VehiclesPublicVehicleSearch {
@Field(() => Date, { nullable: true })
newRegDate?: Date | null
+ @Field(() => Date, { nullable: true })
+ firstRegDate?: Date | null
+
@Field(() => String, { nullable: true })
vehicleStatus?: string | null
diff --git a/libs/application/core/src/lib/fieldBuilders.ts b/libs/application/core/src/lib/fieldBuilders.ts
index 86fc114660cc..ba710d8df748 100644
--- a/libs/application/core/src/lib/fieldBuilders.ts
+++ b/libs/application/core/src/lib/fieldBuilders.ts
@@ -602,8 +602,10 @@ export function buildImageField(
marginTop,
marginBottom,
condition,
- imageWidth = 'full',
titleVariant = 'h4',
+ // imageWidth and imagePosition can be arrays [sm, md, lg, xl] for different screen sizes
+ imageWidth = 'full',
+ imagePosition = 'left',
} = data
return {
children: undefined,
@@ -616,6 +618,7 @@ export function buildImageField(
marginBottom,
condition,
titleVariant,
+ imagePosition,
type: FieldTypes.IMAGE,
component: FieldComponents.IMAGE,
}
diff --git a/libs/application/template-api-modules/src/lib/modules/templates/announcement-of-death/announcement-of-death.service.ts b/libs/application/template-api-modules/src/lib/modules/templates/announcement-of-death/announcement-of-death.service.ts
index 9589c03b6571..a802991e3b1d 100644
--- a/libs/application/template-api-modules/src/lib/modules/templates/announcement-of-death/announcement-of-death.service.ts
+++ b/libs/application/template-api-modules/src/lib/modules/templates/announcement-of-death/announcement-of-death.service.ts
@@ -105,8 +105,7 @@ export class AnnouncementOfDeathService extends BaseTemplateApiService {
const syslumennOnEntryData: any = application.externalData.syslumennOnEntry
const electPerson: any = (application.answers?.pickRole as PickRole)
.electPerson
- const electPersonNationalId: string =
- electPerson.electedPersonNationalId ?? ''
+ const electPersonNationalId: string = electPerson.nationalId ?? ''
if (!isPerson(electPersonNationalId)) {
return {
@@ -174,8 +173,7 @@ export class AnnouncementOfDeathService extends BaseTemplateApiService {
application.externalData.syslumennOnEntry
const electPerson: any = (application.answers?.pickRole as PickRole)
.electPerson
- const electPersonNationalId: string =
- electPerson.electedPersonNationalId ?? ''
+ const electPersonNationalId: string = electPerson.nationalId ?? ''
if (!isPerson(electPersonNationalId)) {
return {
diff --git a/libs/application/template-api-modules/src/lib/modules/templates/announcement-of-death/types/index.ts b/libs/application/template-api-modules/src/lib/modules/templates/announcement-of-death/types/index.ts
index 564c1b837778..1852e0147d42 100644
--- a/libs/application/template-api-modules/src/lib/modules/templates/announcement-of-death/types/index.ts
+++ b/libs/application/template-api-modules/src/lib/modules/templates/announcement-of-death/types/index.ts
@@ -22,7 +22,7 @@ export interface RealEstateAddress {
export type PickRole = {
roleConfirmation: RoleConfirmationEnum
electPerson: {
- electedPersonNationalId: string
- electedPersonName: string
+ nationalId: string
+ name: string
}
}
diff --git a/libs/application/template-api-modules/src/lib/modules/templates/estate/estate.service.ts b/libs/application/template-api-modules/src/lib/modules/templates/estate/estate.service.ts
index 8190bf949c3c..6cb7f6d60cd5 100644
--- a/libs/application/template-api-modules/src/lib/modules/templates/estate/estate.service.ts
+++ b/libs/application/template-api-modules/src/lib/modules/templates/estate/estate.service.ts
@@ -73,7 +73,10 @@ export class EstateTemplateService extends BaseTemplateApiService {
}
const applicationAnswers = application.answers as unknown as EstateSchema
- const estateData = applicationData.find((estate) => estate.caseNumber)
+ const selectedCaseNumber = applicationAnswers.estateInfoSelection
+ const estateData = applicationData.find(
+ (estate) => estate.caseNumber === selectedCaseNumber,
+ )
if (
!estateData?.caseNumber?.length ||
estateData?.caseNumber.length === 0
@@ -104,12 +107,8 @@ export class EstateTemplateService extends BaseTemplateApiService {
{
title: coreErrorMessages.errorDataProviderEstateValidationFailed,
summary: {
+ values: { message },
...coreErrorMessages.errorDataProviderEstateValidationFailedSummary,
- defaultMessage:
- coreErrorMessages.errorDataProviderEstateValidationFailedSummary.defaultMessage.replace(
- '{message}',
- message,
- ),
},
},
500,
diff --git a/libs/application/template-api-modules/src/lib/modules/templates/estate/utils/fakeData.ts b/libs/application/template-api-modules/src/lib/modules/templates/estate/utils/fakeData.ts
index 582922d42355..ad7247877021 100644
--- a/libs/application/template-api-modules/src/lib/modules/templates/estate/utils/fakeData.ts
+++ b/libs/application/template-api-modules/src/lib/modules/templates/estate/utils/fakeData.ts
@@ -91,7 +91,7 @@ export const getFakeEstateInfo = (
nationalId: '0101304929',
},
],
- caseNumber: `2020-00012${nationalIdOfDeceased.slice(-1)}`,
+ caseNumber: `2020-00012${nationalIdOfDeceased.slice(-4)}`,
dateOfDeath: new Date(Date.now() - 1000 * 3600 * 24 * 100),
nameOfDeceased,
nationalIdOfDeceased,
diff --git a/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-cemetery/financial-statement-cemetery.module.ts b/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-cemetery/financial-statement-cemetery.module.ts
new file mode 100644
index 000000000000..0bd4bb768bc6
--- /dev/null
+++ b/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-cemetery/financial-statement-cemetery.module.ts
@@ -0,0 +1,26 @@
+import { DynamicModule } from '@nestjs/common'
+import { BaseTemplateAPIModuleConfig } from '../../../types'
+import { SharedTemplateAPIModule } from '../../shared'
+import { ConfigModule } from '@nestjs/config'
+import {
+ FinancialStatementsInaoClientConfig,
+ FinancialStatementsInaoClientModule,
+} from '@island.is/clients/financial-statements-inao'
+import { FinancialStatementCemeteryTemplateService } from './financial-statement-cemetery.service'
+
+export class FinancialStatementCemeteryTemplateModule {
+ static register(config: BaseTemplateAPIModuleConfig): DynamicModule {
+ return {
+ module: FinancialStatementCemeteryTemplateModule,
+ imports: [
+ SharedTemplateAPIModule.register(config),
+ ConfigModule.forRoot({
+ load: [FinancialStatementsInaoClientConfig],
+ }),
+ FinancialStatementsInaoClientModule,
+ ],
+ providers: [FinancialStatementCemeteryTemplateService],
+ exports: [FinancialStatementCemeteryTemplateService],
+ }
+ }
+}
diff --git a/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-cemetery/financial-statement-cemetery.service.ts b/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-cemetery/financial-statement-cemetery.service.ts
new file mode 100644
index 000000000000..dbfbf5c9f752
--- /dev/null
+++ b/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-cemetery/financial-statement-cemetery.service.ts
@@ -0,0 +1,163 @@
+import { S3 } from 'aws-sdk'
+import { BaseTemplateApiService } from '../../base-template-api.service'
+import { Inject } from '@nestjs/common'
+import type { Logger } from '@island.is/logging'
+import { LOGGER_PROVIDER } from '@island.is/logging'
+import {
+ CemeteryFinancialStatementValues,
+ FinancialStatementsInaoClientService,
+ ClientRoles,
+ Contact,
+ ContactType,
+ DigitalSignee,
+} from '@island.is/clients/financial-statements-inao'
+import {
+ ApplicationTypes,
+ ApplicationWithAttachments as Application,
+ PerformActionResult,
+} from '@island.is/application/types'
+import { getValueViaPath } from '@island.is/application/core'
+import AmazonS3URI from 'amazon-s3-uri'
+import { TemplateApiModuleActionProps } from '../../../types'
+import * as kennitala from 'kennitala'
+import {
+ DataResponse,
+ getCurrentUserType,
+} from '../financial-statements-inao/financial-statements-inao.service'
+import {
+ BoardMember,
+ FSIUSERTYPE,
+} from '@island.is/application/templates/financial-statements-inao/types'
+import {
+ mapValuesToCemeterytype,
+ getNeededCemeteryValues,
+ mapContactsAnswersToContacts,
+ mapDigitalSignee,
+} from '../financial-statement-cemetery/mappers/mapValuesToUserType'
+import { TemplateApiError } from '@island.is/nest/problem'
+import { ApplicationApiAction } from '../../template-api.service'
+
+export type AttachmentData = {
+ key: string
+ name: string
+}
+
+export class FinancialStatementCemeteryTemplateService extends BaseTemplateApiService {
+ s3: S3
+ constructor(
+ @Inject(LOGGER_PROVIDER) private logger: Logger,
+ private financialStatementClientService: FinancialStatementsInaoClientService,
+ ) {
+ super(ApplicationTypes.FINANCIAL_STATEMENT_CEMETERY)
+ this.s3 = new S3()
+ }
+
+ private async getAttachments(application: Application): Promise {
+ const attachments: Array | undefined = getValueViaPath(
+ application.answers,
+ 'attachments.files',
+ ) as Array<{ key: string; name: string }>
+
+ const attachmentKey = attachments[0].key
+
+ const fileName = (
+ application.attachments as {
+ [key: string]: string
+ }
+ )[attachmentKey]
+
+ if (!fileName) {
+ return Promise.reject({})
+ }
+
+ const { bucket, key } = AmazonS3URI(fileName)
+
+ const uploadBucket = bucket
+ try {
+ const file = await this.s3
+ .getObject({
+ Bucket: uploadBucket,
+ Key: key,
+ })
+ .promise()
+ const fileContent = file.Body as Buffer
+ return fileContent.toString('base64') || ''
+ } catch (error) {
+ throw new Error('Error occurred while fetching attachment')
+ }
+ }
+
+ async getUserType({ auth }: TemplateApiModuleActionProps) {
+ const { nationalId } = auth
+ if (kennitala.isPerson(nationalId)) {
+ return this.financialStatementClientService.getClientType(
+ ClientRoles.Individual,
+ )
+ } else {
+ return this.financialStatementClientService.getUserClientType(nationalId)
+ }
+ }
+
+ async submitApplication({ application, auth }: TemplateApiModuleActionProps) {
+ const { nationalId, actor } = auth
+ const answers = application.answers
+ const externalData = application.externalData
+ const currentUserType = getCurrentUserType(answers, externalData)
+
+ // Todo test before this goes live
+ // if (currentUserType !== FSIUSERTYPE.CEMETRY) {
+ // throw new Error('Application submission failed')
+ // }
+
+ if (!actor) {
+ return new Error('Enginn umboðsmaður fannst')
+ }
+
+ const values: CemeteryFinancialStatementValues =
+ mapValuesToCemeterytype(answers)
+
+ const { year, actorsName, contactsAnswer, clientPhone, clientEmail, file } =
+ getNeededCemeteryValues(answers)
+
+ const fileName = file ? await this.getAttachments(application) : undefined
+
+ const client = { nationalId }
+
+ const contacts = mapContactsAnswersToContacts(
+ actor,
+ actorsName,
+ contactsAnswer,
+ )
+ const digitalSignee = mapDigitalSignee(clientEmail, clientPhone)
+
+ const result: DataResponse = await this.financialStatementClientService
+ .postFinancialStatementForCemetery(
+ client,
+ contacts,
+ digitalSignee,
+ year,
+ '',
+ values,
+ fileName,
+ )
+ .then((data) => {
+ if (data === true) {
+ return { success: true }
+ } else {
+ return { success: false }
+ }
+ })
+ .catch((e) => {
+ return {
+ success: false,
+ errorMessages: e.message,
+ }
+ })
+
+ if (!result.success) {
+ throw new Error('Application submission failed')
+ }
+
+ return { success: result.success }
+ }
+}
diff --git a/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-cemetery/mappers/mapValuesToUserType.ts b/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-cemetery/mappers/mapValuesToUserType.ts
new file mode 100644
index 000000000000..a5d02e9acadb
--- /dev/null
+++ b/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-cemetery/mappers/mapValuesToUserType.ts
@@ -0,0 +1,131 @@
+import { getValueViaPath } from '@island.is/application/core'
+import { BoardMember } from '@island.is/application/templates/financial-statements-inao/types'
+import { FormValue } from '@island.is/application/types'
+import {
+ Contact,
+ ContactType,
+ ClientRoles,
+ DigitalSignee,
+} from '@island.is/clients/financial-statements-inao'
+
+export const mapValuesToCemeterytype = (answers: FormValue) => {
+ return {
+ careIncome: Number(getValueViaPath(answers, 'cemetryIncome.careIncome')),
+ burialRevenue: Number(
+ getValueViaPath(answers, 'cemetryIncome.burialRevenue'),
+ ),
+ grantFromTheCemeteryFund: Number(
+ getValueViaPath(answers, 'cemetryIncome.grantFromTheCemeteryFund'),
+ ),
+ otherIncome: Number(getValueViaPath(answers, 'cemetryIncome.otherIncome')),
+ salaryAndSalaryRelatedExpenses: Number(
+ getValueViaPath(answers, 'cemetryExpense.payroll'),
+ ),
+ operationOfAFuneralChapel: Number(
+ getValueViaPath(answers, 'cemetryExpense.chapelExpense'),
+ ),
+ funeralExpenses: Number(
+ getValueViaPath(answers, 'cemetryExpense.funeralCost'),
+ ),
+ donationsToCemeteryFund: Number(
+ getValueViaPath(answers, 'cemetryExpense.cemeteryFundExpense'),
+ ),
+ contributionsAndGrantsToOthers: Number(
+ getValueViaPath(answers, 'cemetryExpense.donationsToOther'),
+ ),
+ otherOperatingExpenses: Number(
+ getValueViaPath(answers, 'cemetryExpense.otherOperationCost'),
+ ),
+ depreciation: Number(
+ getValueViaPath(answers, 'cemetryExpense.depreciation'),
+ ),
+ financialExpenses: Number(
+ getValueViaPath(answers, 'capitalNumbers.capitalCost'),
+ ),
+ capitalIncome: Number(
+ getValueViaPath(answers, 'capitalNumbers.capitalIncome'),
+ ),
+ fixedAssetsTotal: Number(
+ getValueViaPath(answers, 'cemetryAsset.fixedAssetsTotal'),
+ ),
+ currentAssets: Number(
+ getValueViaPath(answers, 'cemetryAsset.currentAssets'),
+ ),
+ longTermLiabilitiesTotal: Number(
+ getValueViaPath(answers, 'cemetryLiability.longTerm'),
+ ),
+ shortTermLiabilitiesTotal: Number(
+ getValueViaPath(answers, 'cemetryLiability.shortTerm'),
+ ),
+ equityAtTheBeginningOfTheYear: Number(
+ getValueViaPath(answers, 'cemetryEquity.equityAtTheBeginningOfTheYear'),
+ ),
+ revaluationDueToPriceChanges: Number(
+ getValueViaPath(answers, 'cemetryEquity.revaluationDueToPriceChanges'),
+ ),
+ reassessmentOther: Number(
+ getValueViaPath(answers, 'cemetryEquity.reevaluateOther'),
+ ),
+ }
+}
+
+export const getNeededCemeteryValues = (answers: FormValue) => {
+ const year = getValueViaPath(
+ answers,
+ 'conditionalAbout.operatingYear',
+ ) as string
+ const actorsName = getValueViaPath(
+ answers,
+ 'about.powerOfAttorneyName',
+ ) as string
+
+ const contactsAnswer = getValueViaPath(
+ answers,
+ 'cemeteryCaretaker',
+ ) as Array
+ const clientPhone = getValueViaPath(answers, 'about.phoneNumber') as string
+ const clientEmail = getValueViaPath(answers, 'about.email') as string
+
+ const file = getValueViaPath(answers, 'attachments.files')
+
+ return { year, actorsName, contactsAnswer, clientPhone, clientEmail, file }
+}
+
+export const mapContactsAnswersToContacts = (
+ actor: { nationalId: string; scope: Array },
+ actorsName: string,
+ contactsAnswer: Array,
+) => {
+ const contacts: Array = [
+ {
+ nationalId: actor.nationalId,
+ name: actorsName,
+ contactType: ContactType.Actor,
+ },
+ ]
+
+ if (contactsAnswer) {
+ contactsAnswer.map((x) => {
+ const contact: Contact = {
+ nationalId: x.nationalId,
+ name: x.name,
+ contactType:
+ x.role === ClientRoles.BoardMember
+ ? ContactType.BoardMember
+ : ContactType.Inspector,
+ }
+ contacts.push(contact)
+ })
+ }
+
+ return contacts
+}
+
+export const mapDigitalSignee = (clientEmail: string, clientPhone: string) => {
+ const digitalSignee: DigitalSignee = {
+ email: clientEmail,
+ phone: clientPhone,
+ }
+
+ return digitalSignee
+}
diff --git a/libs/application/template-api-modules/src/lib/modules/templates/index.ts b/libs/application/template-api-modules/src/lib/modules/templates/index.ts
index f1946e68169e..b168c989c374 100644
--- a/libs/application/template-api-modules/src/lib/modules/templates/index.ts
+++ b/libs/application/template-api-modules/src/lib/modules/templates/index.ts
@@ -24,6 +24,8 @@ import { ExamplePaymentActionsModule } from './example-payment-actions/examplePa
import { ExamplePaymentActionsService } from './example-payment-actions/examplePaymentActions.service'
import { FinancialAidModule } from './financial-aid/financial-aid.module'
import { FinancialAidService } from './financial-aid/financial-aid.service'
+import { FinancialStatementCemeteryTemplateModule } from './financial-statement-cemetery/financial-statement-cemetery.module'
+import { FinancialStatementCemeteryTemplateService } from './financial-statement-cemetery/financial-statement-cemetery.service'
import { FinancialStatementsInaoTemplateModule } from './financial-statements-inao/financial-statements-inao.module'
import { FinancialStatementsInaoTemplateService } from './financial-statements-inao/financial-statements-inao.service'
import { FundingGovernmentProjectsModule } from './funding-government-projects/funding-government-projects.module'
@@ -162,6 +164,7 @@ export const modules = [
DrivingSchoolConfirmationModule,
PassportModule,
OperatingLicenseModule,
+ FinancialStatementCemeteryTemplateModule,
FinancialStatementsInaoTemplateModule,
NoDebtCertificateModule,
InheritanceReportModule,
@@ -229,6 +232,7 @@ export const services = [
DrivingSchoolConfirmationService,
PassportService,
OperatingLicenseService,
+ FinancialStatementCemeteryTemplateService,
FinancialStatementsInaoTemplateService,
MarriageConditionsSubmissionService,
NoDebtCertificateService,
diff --git a/libs/application/template-api-modules/src/lib/modules/templates/official-journal-of-iceland/official-journal-of-iceland.service.ts b/libs/application/template-api-modules/src/lib/modules/templates/official-journal-of-iceland/official-journal-of-iceland.service.ts
index de39599c3635..0d8c5a82aadd 100644
--- a/libs/application/template-api-modules/src/lib/modules/templates/official-journal-of-iceland/official-journal-of-iceland.service.ts
+++ b/libs/application/template-api-modules/src/lib/modules/templates/official-journal-of-iceland/official-journal-of-iceland.service.ts
@@ -2,7 +2,11 @@ import { Injectable } from '@nestjs/common'
import { ApplicationTypes } from '@island.is/application/types'
import { BaseTemplateApiService } from '../../base-template-api.service'
-import { OfficialJournalOfIcelandService } from '@island.is/api/domains/official-journal-of-iceland'
+import {
+ OfficialJournalOfIcelandService,
+ QueryParams,
+ TypeQueryParams,
+} from '@island.is/api/domains/official-journal-of-iceland'
import { TemplateApiModuleActionProps } from '../../../types'
import { OJOIApplication } from '@island.is/application/templates/official-journal-of-iceland'
import { OfficialJournalOfIcelandApplicationService } from '@island.is/api/domains/official-journal-of-iceland-application'
@@ -20,12 +24,12 @@ export class OfficialJournalOfIcelandTemaplateService extends BaseTemplateApiSer
super(ApplicationTypes.OFFICIAL_JOURNAL_OF_ICELAND)
}
- async departments() {
- return this.ojoiService.departments({})
+ async getDepartments(params: QueryParams) {
+ return this.ojoiService.getDepartments(params)
}
- async types() {
- return this.ojoiService.types({})
+ async getAdvertTypes(params: TypeQueryParams) {
+ return this.ojoiService.getAdvertTypes(params)
}
async postApplication({ application, auth }: Props): Promise {
diff --git a/libs/application/template-loader/src/index.ts b/libs/application/template-loader/src/index.ts
index 427d16460a1f..995b3bc766fe 100644
--- a/libs/application/template-loader/src/index.ts
+++ b/libs/application/template-loader/src/index.ts
@@ -25,9 +25,9 @@ type TemplateLibraryModule = {
}
const loadedTemplateLibs: Record = {}
-async function loadTemplateLib(
+const loadTemplateLib = async (
templateId: ApplicationTypes,
-): Promise {
+): Promise => {
const hasLoadedTemplateLib = Object.prototype.hasOwnProperty.call(
loadedTemplateLibs,
templateId,
@@ -53,6 +53,7 @@ async function loadTemplateLib(
}
}
+// eslint-disable-next-line func-style
export async function getApplicationTemplateByTypeId<
TContext extends ApplicationContext,
TStateSchema extends ApplicationStateSchema,
@@ -68,9 +69,9 @@ export async function getApplicationTemplateByTypeId<
>
}
-export async function getApplicationUIFields(
+export const getApplicationUIFields = async (
templateId: ApplicationTypes,
-): Promise {
+): Promise => {
const templateLib = await loadTemplateLib(templateId)
if (templateLib.getFields) {
return await templateLib.getFields()
@@ -78,9 +79,9 @@ export async function getApplicationUIFields(
return Promise.resolve({})
}
-export async function getApplicationDataProviders(
+export const getApplicationDataProviders = async (
templateId: ApplicationTypes,
-): Promise BasicDataProvider>> {
+): Promise BasicDataProvider>> => {
const templateLib = await loadTemplateLib(templateId)
if (templateLib.getDataProviders) {
return await templateLib.getDataProviders()
@@ -88,9 +89,9 @@ export async function getApplicationDataProviders(
return Promise.resolve({})
}
-export async function getApplicationStateInformation(
+export const getApplicationStateInformation = async (
application: Application,
-): Promise {
+): Promise => {
const template = await getApplicationTemplateByTypeId(application.typeId)
if (!template) {
return null
@@ -99,9 +100,9 @@ export async function getApplicationStateInformation(
return helper.getApplicationStateInformation() || null
}
-export async function getApplicationTranslationNamespaces(
+export const getApplicationTranslationNamespaces = async (
application: Application,
-): Promise {
+): Promise => {
const template = await getApplicationTemplateByTypeId(application.typeId)
// We load the core namespace for the application system + the ones defined in the application template
diff --git a/libs/application/template-loader/src/lib/templateLoaders.ts b/libs/application/template-loader/src/lib/templateLoaders.ts
index 5e8b813cf658..298dfee896f2 100644
--- a/libs/application/template-loader/src/lib/templateLoaders.ts
+++ b/libs/application/template-loader/src/lib/templateLoaders.ts
@@ -63,6 +63,8 @@ const templates: Record Promise> = {
import('@island.is/application/templates/mortgage-certificate'),
[ApplicationTypes.NO_DEBT_CERTIFICATE]: () =>
import('@island.is/application/templates/no-debt-certificate'),
+ [ApplicationTypes.FINANCIAL_STATEMENT_CEMETERY]: () =>
+ import('@island.is/application/templates/financial-statement-cemetery'),
[ApplicationTypes.FINANCIAL_STATEMENTS_INAO]: () =>
import('@island.is/application/templates/financial-statements-inao'),
[ApplicationTypes.OPERATING_LICENSE]: () =>
diff --git a/libs/application/templates/announcement-of-death/src/assets/CoatOfArms.tsx b/libs/application/templates/announcement-of-death/src/assets/CoatOfArms.tsx
index 7c36d2e535ae..43b97eb17c8c 100644
--- a/libs/application/templates/announcement-of-death/src/assets/CoatOfArms.tsx
+++ b/libs/application/templates/announcement-of-death/src/assets/CoatOfArms.tsx
@@ -9,1141 +9,417 @@ const CoatOfArms: React.FC> = () => (
xmlns="http://www.w3.org/2000/svg"
>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
diff --git a/libs/application/templates/announcement-of-death/src/fields/AnswerPopulator/index.tsx b/libs/application/templates/announcement-of-death/src/fields/AnswerPopulator/index.tsx
deleted file mode 100644
index e27e83511476..000000000000
--- a/libs/application/templates/announcement-of-death/src/fields/AnswerPopulator/index.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import React, { FC, useEffect } from 'react'
-import { FieldBaseProps } from '@island.is/application/types'
-import { EstateRegistrant } from '@island.is/clients/syslumenn'
-import { useFormContext } from 'react-hook-form'
-
-export const AnswerPopulator: FC> = ({
- application,
-}) => {
- const { setValue } = useFormContext()
- useEffect(() => {
- const externalData = application.externalData.syslumennOnEntry.data
- const estateData = (externalData as { estate: EstateRegistrant })?.estate
- if (estateData) {
- setValue('caseNumber', estateData.caseNumber)
- setValue('marriageSettlement', estateData.marriageSettlement)
- setValue(
- 'districtCommissionerHasWill',
- estateData.districtCommissionerHasWill,
- )
- }
- }, [])
-
- return <>>
-}
diff --git a/libs/application/templates/announcement-of-death/src/fields/Done/index.tsx b/libs/application/templates/announcement-of-death/src/fields/Done/index.tsx
deleted file mode 100644
index a587cdf4a674..000000000000
--- a/libs/application/templates/announcement-of-death/src/fields/Done/index.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import React from 'react'
-import AOD from '../../assets/AOD'
-import { Box } from '@island.is/island-ui/core'
-
-export const Done = () => {
- return (
-
-
-
- )
-}
diff --git a/libs/application/templates/announcement-of-death/src/fields/ElectPerson/index.tsx b/libs/application/templates/announcement-of-death/src/fields/ElectPerson/index.tsx
deleted file mode 100644
index 967c82aa53c9..000000000000
--- a/libs/application/templates/announcement-of-death/src/fields/ElectPerson/index.tsx
+++ /dev/null
@@ -1,134 +0,0 @@
-import React, { FC, useEffect } from 'react'
-import { FieldErrors, FieldValues, useFormContext } from 'react-hook-form'
-import * as kennitala from 'kennitala'
-import { Box, GridColumn, GridRow, Text } from '@island.is/island-ui/core'
-import { formatText, getErrorViaPath } from '@island.is/application/core'
-import { FieldBaseProps } from '@island.is/application/types'
-import { InputController } from '@island.is/shared/form-fields'
-import { useLocale } from '@island.is/localization'
-import { m } from '../../lib/messages'
-import { useLazyQuery } from '@apollo/client'
-import { IdentityInput, Query } from '@island.is/api/schema'
-import { IDENTITY_QUERY } from '../../graphql'
-
-interface ElectPersonFieldBaseProps extends FieldBaseProps {
- errors: FieldErrors
-}
-
-const prefix = 'pickRole.electPerson'
-
-const fieldNames = {
- roleConfirmation: `${prefix}.roleConfirmation`,
- electedPersonNationalId: `${prefix}.electedPersonNationalId`,
- lookupError: `${prefix}.lookupError`,
- electedPersonName: `${prefix}.electedPersonName`,
-}
-
-export const ElectPerson: FC<
- React.PropsWithChildren
-> = ({ application }) => {
- const { formatMessage } = useLocale()
- const {
- setValue,
- watch,
- clearErrors,
- setError,
-
- formState: { errors },
- } = useFormContext()
- const [getIdentity, { loading: queryLoading }] = useLazyQuery<
- Query,
- { input: IdentityInput }
- >(IDENTITY_QUERY, {
- onError: (error: unknown) => {
- setError(fieldNames.lookupError, {
- type: 'serverError',
- message: m.errorNationalIdNoName.defaultMessage,
- })
- console.log('getIdentity error:', error)
- },
- onCompleted: (data) => {
- if (data.identity?.name) {
- clearErrors(fieldNames.lookupError)
- clearErrors(fieldNames.electedPersonName)
- setValue(fieldNames.electedPersonName, data.identity?.name ?? '')
- } else {
- setError(fieldNames.lookupError, {
- type: 'serverError',
- message: m.errorNationalIdNoName.defaultMessage,
- })
- }
- },
- })
-
- // Clear inital errors on mount
- useEffect(() => {
- clearErrors()
- }, [])
-
- const electedPersonNationalId: string = watch(
- fieldNames.electedPersonNationalId,
- )
- const electedPersonName: string = watch(fieldNames.electedPersonName)
-
- useEffect(() => {
- if (electedPersonNationalId?.length === 10) {
- const isValidSSN = kennitala.isPerson(electedPersonNationalId)
- if (isValidSSN) {
- getIdentity({
- variables: {
- input: {
- nationalId: electedPersonNationalId,
- },
- },
- })
- } else if (electedPersonName !== '') {
- setValue(fieldNames.electedPersonName, '')
- }
- } else if (electedPersonName !== '') {
- setValue(fieldNames.electedPersonName, '')
- }
- }, [electedPersonName, electedPersonNationalId, getIdentity, setValue])
-
- return (
-
-
- {formatText(m.delegateRoleDisclaimer, application, formatMessage)}
-
-
-
-
-
-
-
-
-
-
- )
-}
diff --git a/libs/application/templates/announcement-of-death/src/fields/ElectPerson/styles.css.ts b/libs/application/templates/announcement-of-death/src/fields/ElectPerson/styles.css.ts
deleted file mode 100644
index d6192938cd61..000000000000
--- a/libs/application/templates/announcement-of-death/src/fields/ElectPerson/styles.css.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import { style } from '@vanilla-extract/css'
-
-export const hidden = style({
- visibility: 'hidden',
-})
diff --git a/libs/application/templates/announcement-of-death/src/fields/FirearmApplicant/index.tsx b/libs/application/templates/announcement-of-death/src/fields/FirearmApplicant/index.tsx
index 8f2d5ae6f2d9..7a01732a8e65 100644
--- a/libs/application/templates/announcement-of-death/src/fields/FirearmApplicant/index.tsx
+++ b/libs/application/templates/announcement-of-death/src/fields/FirearmApplicant/index.tsx
@@ -108,10 +108,7 @@ export const FirearmApplicant: FC<
errors,
'pickRole.electPerson.lookupError.message',
) ||
- getErrorViaPath(
- errors,
- 'pickRole.electPerson.electedPersonNationalId',
- ) ||
+ getErrorViaPath(errors, 'pickRole.electPerson.nationalId') ||
undefined
}
/>
diff --git a/libs/application/templates/announcement-of-death/src/fields/index.ts b/libs/application/templates/announcement-of-death/src/fields/index.ts
index 67969902531e..95287d5a1ff5 100644
--- a/libs/application/templates/announcement-of-death/src/fields/index.ts
+++ b/libs/application/templates/announcement-of-death/src/fields/index.ts
@@ -1,11 +1,8 @@
-export { ElectPerson } from './ElectPerson/index'
-export { Done } from './Done'
export { ViewOverviewInDone } from './ViewOverviewInDone'
export { EstateMemberRepeater } from './EstateMemberRepeater'
export { RealEstateRepeater } from './RealEstateRepeater'
export { VehiclesRepeater } from './VehiclesRepeater'
export { FilesRecipientCard } from './FilesRecipientCard'
export { InfoCard } from './InfoCard'
-export { AnswerPopulator } from './AnswerPopulator'
export { LinkExistingApplication } from './ExistingApplication/LinkExistingApplication'
export { FirearmApplicant } from './FirearmApplicant'
diff --git a/libs/application/templates/announcement-of-death/src/forms/delegated.ts b/libs/application/templates/announcement-of-death/src/forms/delegated.ts
index c308285d169e..d10294a11dc1 100644
--- a/libs/application/templates/announcement-of-death/src/forms/delegated.ts
+++ b/libs/application/templates/announcement-of-death/src/forms/delegated.ts
@@ -1,11 +1,12 @@
import {
buildForm,
- buildCustomField,
buildMultiField,
+ buildImageField,
} from '@island.is/application/core'
import { Form, FormModes } from '@island.is/application/types'
import CoatOfArms from '../assets/CoatOfArms'
import { m } from '../lib/messages'
+import AOD from '../assets/AOD'
export const delegated: Form = buildForm({
id: 'delegated',
@@ -20,10 +21,11 @@ export const delegated: Form = buildForm({
description: m.delegatedDescription,
space: 1,
children: [
- buildCustomField({
+ buildImageField({
id: 'completeStepImage',
title: '',
- component: 'Done',
+ image: AOD,
+ imagePosition: 'center',
}),
],
}),
diff --git a/libs/application/templates/announcement-of-death/src/forms/done.ts b/libs/application/templates/announcement-of-death/src/forms/done.ts
index 37fd57524efb..4e93344c49a0 100644
--- a/libs/application/templates/announcement-of-death/src/forms/done.ts
+++ b/libs/application/templates/announcement-of-death/src/forms/done.ts
@@ -5,6 +5,7 @@ import {
buildDescriptionField,
buildSection,
getValueViaPath,
+ buildImageField,
} from '@island.is/application/core'
import { Form, FormModes } from '@island.is/application/types'
import CoatOfArms from '../assets/CoatOfArms'
@@ -19,6 +20,7 @@ import {
theAnnouncer,
theDeceased,
} from './overviewSections'
+import AOD from '../assets/AOD'
export const done: Form = buildForm({
id: 'done',
@@ -42,10 +44,11 @@ export const done: Form = buildForm({
title: '',
component: 'ViewOverviewInDone',
}),
- buildCustomField({
+ buildImageField({
id: 'viewOverview',
title: '',
- component: 'Done',
+ image: AOD,
+ imagePosition: 'center',
condition: (answers) =>
getValueViaPath(answers, 'viewOverview') !== true,
}),
diff --git a/libs/application/templates/announcement-of-death/src/forms/prerequisite/index.ts b/libs/application/templates/announcement-of-death/src/forms/prerequisite/index.ts
index 4dedda320773..bf291e64b226 100644
--- a/libs/application/templates/announcement-of-death/src/forms/prerequisite/index.ts
+++ b/libs/application/templates/announcement-of-death/src/forms/prerequisite/index.ts
@@ -4,12 +4,13 @@ import {
buildExternalDataProvider,
buildDataProviderItem,
buildMultiField,
- buildCustomField,
buildDescriptionField,
buildKeyValueField,
buildSubmitField,
getValueViaPath,
buildRadioField,
+ buildHiddenInput,
+ buildNationalIdWithNameField,
} from '@island.is/application/core'
import {
Form,
@@ -18,6 +19,7 @@ import {
NationalRegistryUserApi,
UserProfileApi,
ExistingApplicationApi,
+ Application,
} from '@island.is/application/types'
import { m } from '../../lib/messages'
import { RoleConfirmationEnum } from '../../types'
@@ -148,15 +150,44 @@ export const prerequisite = (): Form => {
],
width: 'full',
}),
- buildCustomField({
- title: '',
- id: 'misc',
- component: 'AnswerPopulator',
+ buildHiddenInput({
+ id: 'caseNumber',
+ defaultValue: (application: Application) => {
+ return getValueViaPath(
+ application.externalData,
+ 'syslumennOnEntry.data.estate.caseNumber',
+ )
+ },
+ }),
+ buildHiddenInput({
+ id: 'marriageSettlement',
+ defaultValue: (application: Application) => {
+ return getValueViaPath(
+ application.externalData,
+ 'syslumennOnEntry.data.estate.marriageSettlement',
+ )
+ },
}),
- buildCustomField({
+ buildHiddenInput({
+ id: 'districtCommissionerHasWill',
+ defaultValue: (application: Application) => {
+ return getValueViaPath(
+ application.externalData,
+ 'syslumennOnEntry.data.estate.districtCommissionerHasWill',
+ )
+ },
+ }),
+ buildDescriptionField({
+ id: 'delegateRoleDisclaimer',
title: '',
+ description: m.delegateRoleDisclaimer,
+ condition: (answers) =>
+ getValueViaPath(answers, 'pickRole.roleConfirmation') ===
+ RoleConfirmationEnum.DELEGATE,
+ }),
+ buildNationalIdWithNameField({
id: 'pickRole.electPerson',
- component: 'ElectPerson',
+ title: '',
condition: (answers) =>
getValueViaPath(answers, 'pickRole.roleConfirmation') ===
RoleConfirmationEnum.DELEGATE,
diff --git a/libs/application/templates/announcement-of-death/src/lib/dataSchema.ts b/libs/application/templates/announcement-of-death/src/lib/dataSchema.ts
index 09b4fec3bcb0..0676b2e15498 100644
--- a/libs/application/templates/announcement-of-death/src/lib/dataSchema.ts
+++ b/libs/application/templates/announcement-of-death/src/lib/dataSchema.ts
@@ -31,8 +31,8 @@ export const dataSchema = z.object({
RoleConfirmationEnum.DELEGATE,
]),
electPerson: z.object({
- electedPersonNationalId: z.string(),
- electedPersonName: z.string(),
+ nationalId: z.string(),
+ name: z.string(),
}),
})
.partial()
@@ -43,8 +43,7 @@ export const dataSchema = z.object({
.refine(
({ roleConfirmation, electPerson }) =>
roleConfirmation === RoleConfirmationEnum.DELEGATE && !!electPerson
- ? electPerson.electedPersonName !== '' &&
- electPerson.electedPersonNationalId !== ''
+ ? electPerson.name !== '' && electPerson.nationalId !== ''
: !electPerson
? true
: roleConfirmation === RoleConfirmationEnum.CONTINUE
@@ -52,15 +51,15 @@ export const dataSchema = z.object({
: false,
{
message: m.errorNationalIdNoName.defaultMessage,
- path: ['electPerson', 'electedPersonNationalId'],
+ path: ['electPerson', 'nationalId'],
},
)
.refine(
({ roleConfirmation, electPerson }) =>
roleConfirmation === RoleConfirmationEnum.DELEGATE && !!electPerson
- ? electPerson.electedPersonNationalId &&
- nationalId.isPerson(electPerson.electedPersonNationalId) &&
- nationalId.info(electPerson.electedPersonNationalId).age >= 18
+ ? electPerson.nationalId &&
+ nationalId.isPerson(electPerson.nationalId) &&
+ nationalId.info(electPerson.nationalId).age >= 18
: !electPerson
? true
: roleConfirmation === RoleConfirmationEnum.CONTINUE
@@ -68,7 +67,7 @@ export const dataSchema = z.object({
: false,
{
message: m.errorNationalIdIncorrect.defaultMessage,
- path: ['electPerson', 'electedPersonNationalId'],
+ path: ['electPerson', 'nationalId'],
},
),
diff --git a/libs/application/templates/document-provider-onboarding/src/assets/ManOnBenchIllustration.tsx b/libs/application/templates/document-provider-onboarding/src/assets/ManOnBenchIllustration.tsx
new file mode 100644
index 000000000000..7139eb016608
--- /dev/null
+++ b/libs/application/templates/document-provider-onboarding/src/assets/ManOnBenchIllustration.tsx
@@ -0,0 +1,450 @@
+const Man = () => (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+)
+
+export const ManOnBenchIllustration = () => (
+
+)
diff --git a/libs/application/templates/document-provider-onboarding/src/assets/WomanWithLaptopIllustration.tsx b/libs/application/templates/document-provider-onboarding/src/assets/WomanWithLaptopIllustration.tsx
new file mode 100644
index 000000000000..03ebd2ac1f95
--- /dev/null
+++ b/libs/application/templates/document-provider-onboarding/src/assets/WomanWithLaptopIllustration.tsx
@@ -0,0 +1,448 @@
+const Woman = () => (
+
+)
+
+export const WomanWithLaptopIllustration = () => (
+
+)
diff --git a/libs/application/templates/document-provider-onboarding/src/fields/DocumentProvicerApplication/RejectionScreen/index.tsx b/libs/application/templates/document-provider-onboarding/src/fields/DocumentProvicerApplication/RejectionScreen/index.tsx
deleted file mode 100644
index 5e2edcab6acc..000000000000
--- a/libs/application/templates/document-provider-onboarding/src/fields/DocumentProvicerApplication/RejectionScreen/index.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import React, { FC } from 'react'
-import { useLocale } from '@island.is/localization'
-import { Box, Text } from '@island.is/island-ui/core'
-import { getValueViaPath, formatText } from '@island.is/application/core'
-import { FieldBaseProps } from '@island.is/application/types'
-
-import { m } from '../../../forms/messages'
-
-const RejectionScreen: FC> = ({
- application,
-}) => {
- const { formatMessage } = useLocale()
- return (
-
-
- {formatText(m.rejectedSubHeading, application, formatMessage)}
-
-
- {getValueViaPath(application.answers, 'rejectionReason') as string}
-
-
- )
-}
-
-export default RejectionScreen
diff --git a/libs/application/templates/document-provider-onboarding/src/fields/DocumentProvicerApplication/Review/index.tsx b/libs/application/templates/document-provider-onboarding/src/fields/DocumentProvicerApplication/Review/index.tsx
index 42b2e94c0844..28d608a498cd 100644
--- a/libs/application/templates/document-provider-onboarding/src/fields/DocumentProvicerApplication/Review/index.tsx
+++ b/libs/application/templates/document-provider-onboarding/src/fields/DocumentProvicerApplication/Review/index.tsx
@@ -6,7 +6,7 @@ import { Box, GridColumn, GridRow, Input } from '@island.is/island-ui/core'
import { FieldDescription } from '@island.is/shared/form-fields'
import { useLocale } from '@island.is/localization'
-import { m } from '../../../forms/messages'
+import { m } from '../../../lib/messages'
const Review: FC> = ({
field,
diff --git a/libs/application/templates/document-provider-onboarding/src/fields/DocumentProvicerApplication/TermsOfAgreement/index.tsx b/libs/application/templates/document-provider-onboarding/src/fields/DocumentProvicerApplication/TermsOfAgreement/index.tsx
deleted file mode 100644
index 7eb35f58d74f..000000000000
--- a/libs/application/templates/document-provider-onboarding/src/fields/DocumentProvicerApplication/TermsOfAgreement/index.tsx
+++ /dev/null
@@ -1,100 +0,0 @@
-import React, { FC } from 'react'
-import { useFormContext, Controller } from 'react-hook-form'
-import {
- getValueViaPath,
- formatText,
- getErrorViaPath,
-} from '@island.is/application/core'
-import { FieldBaseProps } from '@island.is/application/types'
-import { Box, Checkbox, Button, Link } from '@island.is/island-ui/core'
-import { FieldDescription } from '@island.is/shared/form-fields'
-import { useLocale } from '@island.is/localization'
-
-import { m } from '../../../forms/messages'
-
-//TODO: Finish error messages.
-const TermsOfAgreement: FC> = ({
- application,
-}) => {
- const { formatMessage } = useLocale()
- const { answers: formValue } = application
- const currentUserTerms = getValueViaPath(
- formValue,
- 'termsOfAgreement.userTerms' as string,
- false,
- ) as boolean
-
- const { setValue, formState, getValues } = useFormContext()
- const { errors } = formState
-
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {
- return (
- {
- onChange(e.target.checked)
- setValue(
- 'termsOfAgreement.userTerms' as string,
- e.target.checked,
- )
- }}
- checked={value}
- name="termsOfAgreement.userTerms"
- hasError={
- errors &&
- getErrorViaPath(errors, 'termsOfAgreement.userTerms') !==
- undefined
- }
- errorMessage={formatText(
- m.termsUserAgreementRequiredMessage,
- application,
- formatMessage,
- )}
- label={formatText(
- m.userAgreementOptionLabel,
- application,
- formatMessage,
- )}
- large
- />
- )
- }}
- />
-
-
- )
-}
-
-export default TermsOfAgreement
diff --git a/libs/application/templates/document-provider-onboarding/src/fields/DocumentProvicerApplication/ThankYouScreen/index.tsx b/libs/application/templates/document-provider-onboarding/src/fields/DocumentProvicerApplication/ThankYouScreen/index.tsx
deleted file mode 100644
index d740e888202f..000000000000
--- a/libs/application/templates/document-provider-onboarding/src/fields/DocumentProvicerApplication/ThankYouScreen/index.tsx
+++ /dev/null
@@ -1,101 +0,0 @@
-import React, { FC } from 'react'
-import { formatText } from '@island.is/application/core'
-import { FieldBaseProps } from '@island.is/application/types'
-import { Box, Text, Link } from '@island.is/island-ui/core'
-import { useLocale } from '@island.is/localization'
-import { m } from '../../../forms/messages'
-
-const ThankYouScreen: FC> = ({
- application,
-}) => {
- const { formatMessage } = useLocale()
- return (
-
-
-
-
- {formatText(m.thankYouScreenSubTitle, application, formatMessage)}
-
-
-
-
-
- {formatText(m.thankYouScreenFirstMessage, application, formatMessage)}
-
-
-
-
-
- {formatText(
- m.thankYouScreenSecondMessage,
- application,
- formatMessage,
- )}
-
-
-
-
- {formatText(
- m.thankYouScreenThirdMessage,
- application,
- formatMessage,
- )}
-
-
-
-
- {formatText(m.thankYouScreenLinkText1, application, formatMessage)}
-
-
-
-
- {formatText(m.thankYouScreenLinkText2, application, formatMessage)}
-
-
-
-
- {formatText(m.thankYouScreenLinkText3, application, formatMessage)}
-
-
-
-
- {formatText(
- m.thankYouScreenFooterMessage,
- application,
- formatMessage,
- )}
-
-
-
-
- )
-}
-
-export default ThankYouScreen
diff --git a/libs/application/templates/document-provider-onboarding/src/fields/Illustrations/ManOnBenchIllustration.tsx b/libs/application/templates/document-provider-onboarding/src/fields/Illustrations/ManOnBenchIllustration.tsx
deleted file mode 100644
index 42d4f50007e2..000000000000
--- a/libs/application/templates/document-provider-onboarding/src/fields/Illustrations/ManOnBenchIllustration.tsx
+++ /dev/null
@@ -1,73 +0,0 @@
-import React from 'react'
-
-function ManOnBenchIllustration() {
- return (
- <>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- >
- )
-}
-
-export default ManOnBenchIllustration
diff --git a/libs/application/templates/document-provider-onboarding/src/fields/Illustrations/ManOnBenchIllustrationPeriods.tsx b/libs/application/templates/document-provider-onboarding/src/fields/Illustrations/ManOnBenchIllustrationPeriods.tsx
deleted file mode 100644
index 17213e8c5b96..000000000000
--- a/libs/application/templates/document-provider-onboarding/src/fields/Illustrations/ManOnBenchIllustrationPeriods.tsx
+++ /dev/null
@@ -1,411 +0,0 @@
-import React, { FC } from 'react'
-import { FieldBaseProps } from '@island.is/application/types'
-import { Box } from '@island.is/island-ui/core'
-import ManOnBenchIllustration from './ManOnBenchIllustration'
-
-// TODO this will be moved into a reusable library
-const PeriodsSectionImage: FC> = () => {
- //TODO make responsive when moved into reusable library
- const isMobile = window.innerWidth < 480
- return (
-
-
-
- )
-}
-
-export default PeriodsSectionImage
diff --git a/libs/application/templates/document-provider-onboarding/src/fields/Illustrations/WomanWithLaptopIllustration.tsx b/libs/application/templates/document-provider-onboarding/src/fields/Illustrations/WomanWithLaptopIllustration.tsx
deleted file mode 100644
index 4a1a2da316dd..000000000000
--- a/libs/application/templates/document-provider-onboarding/src/fields/Illustrations/WomanWithLaptopIllustration.tsx
+++ /dev/null
@@ -1,68 +0,0 @@
-import React from 'react'
-
-function WomanWithLaptopIllustration() {
- return (
-
- )
-}
-
-export default WomanWithLaptopIllustration
diff --git a/libs/application/templates/document-provider-onboarding/src/fields/Illustrations/WomanWithLaptopIllustrationPeriods.tsx b/libs/application/templates/document-provider-onboarding/src/fields/Illustrations/WomanWithLaptopIllustrationPeriods.tsx
deleted file mode 100644
index 178954d7b32e..000000000000
--- a/libs/application/templates/document-provider-onboarding/src/fields/Illustrations/WomanWithLaptopIllustrationPeriods.tsx
+++ /dev/null
@@ -1,411 +0,0 @@
-import React, { FC } from 'react'
-import { FieldBaseProps } from '@island.is/application/types'
-import { Box } from '@island.is/island-ui/core'
-import WomanWithLaptopIllustration from './WomanWithLaptopIllustration'
-
-// TODO this will be moved into a reusable library
-const PeriodsSectionImage: FC> = () => {
- //TODO make responsive when moved into reusable library
- const isMobile = window.innerWidth < 480
- return (
-
-
-
- )
-}
-
-export default PeriodsSectionImage
diff --git a/libs/application/templates/document-provider-onboarding/src/fields/TestPhase/AutomatedTests/index.tsx b/libs/application/templates/document-provider-onboarding/src/fields/TestPhase/AutomatedTests/index.tsx
index d56083c9085a..de4e62bd9e14 100644
--- a/libs/application/templates/document-provider-onboarding/src/fields/TestPhase/AutomatedTests/index.tsx
+++ b/libs/application/templates/document-provider-onboarding/src/fields/TestPhase/AutomatedTests/index.tsx
@@ -16,7 +16,7 @@ import {
} from '@island.is/island-ui/core'
import { FieldDescription } from '@island.is/shared/form-fields'
import { useLocale } from '@island.is/localization'
-import { m } from '../../../forms/messages'
+import { m } from '../../../lib/messages'
export const runEndpointTestsMutation = gql`
mutation RunEndpointTests($input: RunEndpointTestsInput!) {
diff --git a/libs/application/templates/document-provider-onboarding/src/fields/TestPhase/InfoScreen.tsx b/libs/application/templates/document-provider-onboarding/src/fields/TestPhase/InfoScreen.tsx
index 1c8a468eb9ec..809010850611 100644
--- a/libs/application/templates/document-provider-onboarding/src/fields/TestPhase/InfoScreen.tsx
+++ b/libs/application/templates/document-provider-onboarding/src/fields/TestPhase/InfoScreen.tsx
@@ -3,7 +3,7 @@ import { formatText } from '@island.is/application/core'
import { FieldBaseProps } from '@island.is/application/types'
import { Box, Link, Text } from '@island.is/island-ui/core'
import { useLocale } from '@island.is/localization'
-import { m } from '../../forms/messages'
+import { m } from '../../lib/messages'
const TestPhaseInfoScreen: FC> = ({
application,
diff --git a/libs/application/templates/document-provider-onboarding/src/fields/TestPhase/ProdEndpoint/index.tsx b/libs/application/templates/document-provider-onboarding/src/fields/TestPhase/ProdEndpoint/index.tsx
index 26af15e10aa7..19146ea2ccab 100644
--- a/libs/application/templates/document-provider-onboarding/src/fields/TestPhase/ProdEndpoint/index.tsx
+++ b/libs/application/templates/document-provider-onboarding/src/fields/TestPhase/ProdEndpoint/index.tsx
@@ -13,7 +13,7 @@ import { FieldDescription } from '@island.is/shared/form-fields'
import { useLocale } from '@island.is/localization'
import CopyToClipboardInput from '../../DocumentProvicerApplication/Components/CopyToClipboardInput/Index'
-import { m } from '../../../forms/messages'
+import { m } from '../../../lib/messages'
export const updateEndpointMutation = gql`
mutation UpdateEndpoint($input: UpdateEndpointInput!) {
diff --git a/libs/application/templates/document-provider-onboarding/src/fields/TestPhase/ProdEnvironment/index.tsx b/libs/application/templates/document-provider-onboarding/src/fields/TestPhase/ProdEnvironment/index.tsx
index 0fb5fbbf32b9..dd5f9ed38e3a 100644
--- a/libs/application/templates/document-provider-onboarding/src/fields/TestPhase/ProdEnvironment/index.tsx
+++ b/libs/application/templates/document-provider-onboarding/src/fields/TestPhase/ProdEnvironment/index.tsx
@@ -8,7 +8,7 @@ import { useLocale } from '@island.is/localization'
import { UPDATE_APPLICATION } from '@island.is/application/graphql'
import CopyToClipboardInput from '../../DocumentProvicerApplication/Components/CopyToClipboardInput/Index'
-import { m } from '../../../forms/messages'
+import { m } from '../../../lib/messages'
export const createProviderMutation = gql`
mutation CreateProvider($input: CreateProviderInput!) {
diff --git a/libs/application/templates/document-provider-onboarding/src/fields/TestPhase/TechnicalImplementation/index.tsx b/libs/application/templates/document-provider-onboarding/src/fields/TestPhase/TechnicalImplementation/index.tsx
index 139940fbe04d..b2ee79568a7f 100644
--- a/libs/application/templates/document-provider-onboarding/src/fields/TestPhase/TechnicalImplementation/index.tsx
+++ b/libs/application/templates/document-provider-onboarding/src/fields/TestPhase/TechnicalImplementation/index.tsx
@@ -5,7 +5,7 @@ import {
getErrorViaPath,
} from '@island.is/application/core'
import { FieldBaseProps } from '@island.is/application/types'
-import { m } from '../../../forms/messages'
+import { m } from '../../../lib/messages'
import { useFormContext, Controller } from 'react-hook-form'
import { Box, Text, Checkbox } from '@island.is/island-ui/core'
import { useLocale } from '@island.is/localization'
diff --git a/libs/application/templates/document-provider-onboarding/src/fields/TestPhase/TestEndPoint/index.tsx b/libs/application/templates/document-provider-onboarding/src/fields/TestPhase/TestEndPoint/index.tsx
index 0d64bb0c5659..a7b0f1611d35 100644
--- a/libs/application/templates/document-provider-onboarding/src/fields/TestPhase/TestEndPoint/index.tsx
+++ b/libs/application/templates/document-provider-onboarding/src/fields/TestPhase/TestEndPoint/index.tsx
@@ -8,7 +8,7 @@ import { FieldDescription } from '@island.is/shared/form-fields'
import { useLocale } from '@island.is/localization'
import CopyToClipboardInput from '../../DocumentProvicerApplication/Components/CopyToClipboardInput/Index'
-import { m } from '../../../forms/messages'
+import { m } from '../../../lib/messages'
import { ErrorMessage } from '@hookform/error-message'
export const updateTestEndpointMutation = gql`
diff --git a/libs/application/templates/document-provider-onboarding/src/fields/TestPhase/TestEnvironment/index.tsx b/libs/application/templates/document-provider-onboarding/src/fields/TestPhase/TestEnvironment/index.tsx
index 5b928487fa65..6f1baf92455a 100644
--- a/libs/application/templates/document-provider-onboarding/src/fields/TestPhase/TestEnvironment/index.tsx
+++ b/libs/application/templates/document-provider-onboarding/src/fields/TestPhase/TestEnvironment/index.tsx
@@ -9,7 +9,7 @@ import { useLocale } from '@island.is/localization'
import { UPDATE_APPLICATION } from '@island.is/application/graphql'
import CopyToClipboardInput from '../../DocumentProvicerApplication/Components/CopyToClipboardInput/Index'
-import { m } from '../../../forms/messages'
+import { m } from '../../../lib/messages'
export const createTestProviderMutation = gql`
mutation CreateTestProvider($input: CreateProviderInput!) {
diff --git a/libs/application/templates/document-provider-onboarding/src/fields/index.ts b/libs/application/templates/document-provider-onboarding/src/fields/index.ts
index 55ef6c454d5b..501dc3ff2b73 100644
--- a/libs/application/templates/document-provider-onboarding/src/fields/index.ts
+++ b/libs/application/templates/document-provider-onboarding/src/fields/index.ts
@@ -1,13 +1,8 @@
export { default as AutomatedTests } from './TestPhase/AutomatedTests'
export { default as TestPhaseInfoScreen } from './TestPhase/InfoScreen'
-export { default as TermsOfAgreement } from './DocumentProvicerApplication/TermsOfAgreement'
export { default as TestEnvironment } from './TestPhase/TestEnvironment'
export { default as TestEndPoint } from './TestPhase/TestEndPoint'
export { default as Review } from './DocumentProvicerApplication/Review'
export { default as ProdEnvironment } from './TestPhase/ProdEnvironment'
export { default as ProdEndPoint } from './TestPhase/ProdEndpoint'
-export { default as ThankYouScreen } from './DocumentProvicerApplication/ThankYouScreen'
export { default as TechnicalImplementation } from './TestPhase/TechnicalImplementation'
-export { default as RejectionScreen } from './DocumentProvicerApplication/RejectionScreen'
-export { default as ManOnBenchIllustrationPeriods } from './Illustrations/ManOnBenchIllustrationPeriods'
-export { default as WomanWithLaptopIllustrationPeriods } from './Illustrations/WomanWithLaptopIllustrationPeriods'
diff --git a/libs/application/templates/document-provider-onboarding/src/forms/DocumentProviderApplication.ts b/libs/application/templates/document-provider-onboarding/src/forms/DocumentProviderApplication.ts
index e99653b94d9e..482f6de7bc2d 100644
--- a/libs/application/templates/document-provider-onboarding/src/forms/DocumentProviderApplication.ts
+++ b/libs/application/templates/document-provider-onboarding/src/forms/DocumentProviderApplication.ts
@@ -4,30 +4,50 @@ import {
buildSection,
buildTextField,
buildSubmitField,
- buildCustomField,
buildDividerField,
+ buildDescriptionField,
+ buildCheckboxField,
+ buildLinkField,
} from '@island.is/application/core'
import { Form, ApplicationTypes, FormModes } from '@island.is/application/types'
-import { m } from './messages'
+import { m } from '../lib/messages'
+import { AnswerOptions } from '../lib/types'
export const DocumentProviderOnboarding: Form = buildForm({
id: ApplicationTypes.DOCUMENT_PROVIDER_ONBOARDING,
title: m.formName,
mode: FormModes.DRAFT,
+ renderLastScreenButton: true,
children: [
buildSection({
id: 'termsOfAgreement',
title: m.termsSection,
children: [
- buildCustomField(
- {
- id: 'termsOfAgreement',
- title: m.termsTitle,
- description: m.termsSubTitle,
- component: 'TermsOfAgreement',
- },
- {},
- ),
+ buildMultiField({
+ id: 'termsOfAgreement',
+ title: m.termsTitle,
+ children: [
+ buildDescriptionField({
+ id: 'description',
+ title: '',
+ description: m.termsSubTitle,
+ marginBottom: 3,
+ }),
+ buildLinkField({
+ id: 'link',
+ title: m.termsUserAgreementTitle,
+ link: m.termsUserAgreementUrl,
+ iconProps: { icon: 'open' },
+ }),
+ buildCheckboxField({
+ id: 'termsOfAgreement.userTerms',
+ title: '',
+ options: [
+ { value: AnswerOptions.YES, label: m.userAgreementOptionLabel },
+ ],
+ }),
+ ],
+ }),
],
}),
buildSection({
@@ -272,14 +292,6 @@ export const DocumentProviderOnboarding: Form = buildForm({
}),
],
}),
- buildCustomField(
- {
- id: 'thankYouScreen',
- title: m.thankYouScreenTitle,
- component: 'ThankYouScreen',
- },
- {},
- ),
],
}),
],
diff --git a/libs/application/templates/document-provider-onboarding/src/forms/Finished.ts b/libs/application/templates/document-provider-onboarding/src/forms/Finished.ts
index 4f1526175d39..b56126a5b0cb 100644
--- a/libs/application/templates/document-provider-onboarding/src/forms/Finished.ts
+++ b/libs/application/templates/document-provider-onboarding/src/forms/Finished.ts
@@ -1,10 +1,11 @@
import {
buildForm,
- buildCustomField,
buildMultiField,
+ buildImageField,
} from '@island.is/application/core'
import { ApplicationTypes, Form, FormModes } from '@island.is/application/types'
-import { m } from './messages'
+import { m } from '../lib/messages'
+import { WomanWithLaptopIllustration } from '../assets/WomanWithLaptopIllustration'
export const Finished: Form = buildForm({
id: ApplicationTypes.DOCUMENT_PROVIDER_ONBOARDING,
@@ -16,10 +17,12 @@ export const Finished: Form = buildForm({
title: m.thankYouImageScreenTitle,
description: m.thankYouImageScreenScreenSubTitle,
children: [
- buildCustomField({
+ buildImageField({
id: 'thankYouImage',
title: m.thankYouScreenTitle,
- component: 'WomanWithLaptopIllustrationPeriods',
+ image: WomanWithLaptopIllustration,
+ imageWidth: ['full', 'full', '50%', '50%'],
+ imagePosition: 'center',
}),
],
}),
diff --git a/libs/application/templates/document-provider-onboarding/src/forms/PendingReview.ts b/libs/application/templates/document-provider-onboarding/src/forms/PendingReview.ts
index 3e1bcd2ffbe0..eda020112048 100644
--- a/libs/application/templates/document-provider-onboarding/src/forms/PendingReview.ts
+++ b/libs/application/templates/document-provider-onboarding/src/forms/PendingReview.ts
@@ -1,17 +1,72 @@
-import { buildCustomField, buildForm } from '@island.is/application/core'
+import {
+ buildCustomField,
+ buildDescriptionField,
+ buildForm,
+ buildMultiField,
+} from '@island.is/application/core'
import { ApplicationTypes, Form, FormModes } from '@island.is/application/types'
-import { m } from './messages'
+import { m } from '../lib/messages'
export const PendingReview: Form = buildForm({
id: ApplicationTypes.DOCUMENT_PROVIDER_ONBOARDING,
- title: m.pendingReviewthankYouScreenTitle,
+ title: '',
mode: FormModes.IN_PROGRESS,
children: [
- buildCustomField({
- id: 'pendingReviewThankYouScreen',
+ buildMultiField({
+ id: 'pendingReview',
title: m.pendingReviewthankYouScreenTitle,
- component: 'ThankYouScreen',
+ children: [
+ buildDescriptionField({
+ id: 'pendingReviewDescription',
+ title: m.thankYouScreenSubTitle,
+ titleVariant: 'h4',
+ marginBottom: 2,
+ }),
+ buildDescriptionField({
+ id: 'pendingReviewDescription',
+ title: '',
+ description: m.thankYouScreenFirstMessage,
+ marginBottom: 1,
+ }),
+ buildDescriptionField({
+ id: 'pendingReviewDescription2',
+ title: '',
+ description: m.thankYouScreenSecondMessage,
+ marginBottom: 1,
+ }),
+ buildDescriptionField({
+ id: 'pendingReviewDescription3',
+ title: '',
+ description: m.thankYouScreenThirdMessage,
+ marginBottom: 1,
+ }),
+ buildDescriptionField({
+ id: 'pendingReviewLink1',
+ title: '',
+ description: m.thankYouScreenLink1,
+ marginTop: 2,
+ marginBottom: 2,
+ }),
+ buildDescriptionField({
+ id: 'pendingReviewLink2',
+ title: '',
+ description: m.thankYouScreenLink2,
+ marginBottom: 2,
+ }),
+ buildDescriptionField({
+ id: 'pendingReviewLink3',
+ title: '',
+ description: m.thankYouScreenLink3,
+ marginBottom: 2,
+ }),
+ buildDescriptionField({
+ id: 'pendingReviewDescription4',
+ title: '',
+ description: m.thankYouScreenFooterMessage,
+ marginBottom: 3,
+ }),
+ ],
}),
],
})
diff --git a/libs/application/templates/document-provider-onboarding/src/forms/Rejected.ts b/libs/application/templates/document-provider-onboarding/src/forms/Rejected.ts
index 3ba8fa6653fe..523ad99e83bc 100644
--- a/libs/application/templates/document-provider-onboarding/src/forms/Rejected.ts
+++ b/libs/application/templates/document-provider-onboarding/src/forms/Rejected.ts
@@ -1,10 +1,18 @@
import {
- buildCustomField,
+ buildDescriptionField,
buildForm,
+ buildImageField,
buildMultiField,
+ getValueViaPath,
} from '@island.is/application/core'
-import { ApplicationTypes, Form, FormModes } from '@island.is/application/types'
-import { m } from './messages'
+import {
+ Application,
+ ApplicationTypes,
+ Form,
+ FormModes,
+} from '@island.is/application/types'
+import { m } from '../lib/messages'
+import { ManOnBenchIllustration } from '../assets/ManOnBenchIllustration'
export const Rejected: Form = buildForm({
id: ApplicationTypes.DOCUMENT_PROVIDER_ONBOARDING,
title: m.rejectedTitle,
@@ -15,15 +23,22 @@ export const Rejected: Form = buildForm({
title: m.rejectedTitle,
description: m.rejectedSubTitle,
children: [
- buildCustomField({
+ buildDescriptionField({
id: 'RejectionScreen',
- title: 'RejectionScreen',
- component: 'RejectionScreen',
+ title: m.rejectedSubHeading,
+ titleVariant: 'h3',
+ description: (application: Application) =>
+ (getValueViaPath(
+ application.answers,
+ 'rejectionReason',
+ ) as string) ?? '',
}),
- buildCustomField({
+ buildImageField({
id: 'ManOnBench',
- title: 'ManOnBench',
- component: 'ManOnBenchIllustrationPeriods',
+ title: '',
+ image: ManOnBenchIllustration,
+ imageWidth: ['full', 'full', '50%', '50%'],
+ imagePosition: 'center',
}),
],
}),
diff --git a/libs/application/templates/document-provider-onboarding/src/forms/ReviewApplication.ts b/libs/application/templates/document-provider-onboarding/src/forms/ReviewApplication.ts
index 3c42f4c800fa..b6f796053bde 100644
--- a/libs/application/templates/document-provider-onboarding/src/forms/ReviewApplication.ts
+++ b/libs/application/templates/document-provider-onboarding/src/forms/ReviewApplication.ts
@@ -13,7 +13,7 @@ import {
Comparators,
FormModes,
} from '@island.is/application/types'
-import { m } from './messages'
+import { m } from '../lib/messages'
export const ReviewApplication: Form = buildForm({
id: ApplicationTypes.DOCUMENT_PROVIDER_ONBOARDING,
diff --git a/libs/application/templates/document-provider-onboarding/src/forms/TestPhase.ts b/libs/application/templates/document-provider-onboarding/src/forms/TestPhase.ts
index 0393f6320491..0d869371bad9 100644
--- a/libs/application/templates/document-provider-onboarding/src/forms/TestPhase.ts
+++ b/libs/application/templates/document-provider-onboarding/src/forms/TestPhase.ts
@@ -6,7 +6,7 @@ import {
buildSubmitField,
} from '@island.is/application/core'
import { ApplicationTypes, Form, FormModes } from '@island.is/application/types'
-import { m } from './messages'
+import { m } from '../lib/messages'
export const TestPhase: Form = buildForm({
id: ApplicationTypes.DOCUMENT_PROVIDER_ONBOARDING,
diff --git a/libs/application/templates/document-provider-onboarding/src/lib/DocumentProviderOnboardingTemplate.ts b/libs/application/templates/document-provider-onboarding/src/lib/DocumentProviderOnboardingTemplate.ts
index b826ababc070..4c02a37fa1d4 100644
--- a/libs/application/templates/document-provider-onboarding/src/lib/DocumentProviderOnboardingTemplate.ts
+++ b/libs/application/templates/document-provider-onboarding/src/lib/DocumentProviderOnboardingTemplate.ts
@@ -1,7 +1,4 @@
import { assign } from 'xstate'
-import { z } from 'zod'
-import * as kennitala from 'kennitala'
-import { parsePhoneNumberFromString } from 'libphonenumber-js'
import { DefaultStateLifeCycle } from '@island.is/application/core'
import {
ApplicationContext,
@@ -14,6 +11,7 @@ import {
defineTemplateApi,
} from '@island.is/application/types'
import { API_MODULE_ACTIONS } from '../../constants'
+import { dataSchema } from './dataSchema'
type Events =
| { type: DefaultEvents.APPROVE }
@@ -37,87 +35,6 @@ enum States {
FINISHED = 'finished',
}
-const contact = z.object({
- name: z.string().nonempty({ message: 'Nafn þarf að vera útfyllt' }),
- email: z.string().email({ message: 'Netfang þarf að vera gilt' }),
- phoneNumber: z.string().refine(
- (p) => {
- const phoneNumber = parsePhoneNumberFromString(p, 'IS')
- return phoneNumber && phoneNumber.isValid()
- },
- { message: 'Símanúmerið þarf að vera gilt' },
- ),
-})
-
-const helpDeskContact = z.object({
- email: z.string().email({ message: 'Netfang þarf að vera gilt' }),
- phoneNumber: z.string().refine(
- (p) => {
- const phoneNumber = parsePhoneNumberFromString(p, 'IS')
- return phoneNumber && phoneNumber.isValid()
- },
- { message: 'Símanúmer þarf að vera gilt' },
- ),
-})
-
-//TODO: extend contact. Couldn't get it to work easily with contact.extend
-const applicant = z.object({
- name: z.string().nonempty({ message: 'Nafn þarf að vera útfyllt' }),
- email: z.string().email({ message: 'Netfang þarf að vera gilt' }),
- phoneNumber: z.string().refine(
- (p) => {
- const phoneNumber = parsePhoneNumberFromString(p, 'IS')
- return phoneNumber && phoneNumber.isValid()
- },
- { message: 'Símanúmer þarf að vera gilt' },
- ),
- nationalId: z.string().refine((k) => kennitala.isValid(k), {
- message: 'Skrá þarf löglega kennitölu, með eða án bandstriks',
- }),
- // .refine((k) => kennitala.isCompany(k), {
- // message: 'Skrá þarf kennitölu fyrirtækis eða stofnunar',
- // }),
-})
-
-const termsOfAgreement = z.object({
- userTerms: z.boolean().refine((v) => v, {}),
-})
-
-const endPoint = z.object({
- endPoint: z.string().url().nonempty(),
- endPointExists: z.string().nonempty({
- message: 'Þú verður að vista endapunkt til að halda áfram',
- }),
-})
-
-const productionEndPoint = z.object({
- prodEndPoint: z.string().url().nonempty(),
- prodEndPointExists: z.string().nonempty({
- message: 'Þú verður að vista endapunkt til að halda áfram',
- }),
-})
-
-const dataSchema = z.object({
- termsOfAgreement: termsOfAgreement,
- applicant: applicant,
- administrativeContact: contact,
- technicalContact: contact,
- helpDesk: helpDeskContact,
- technicalAnswer: z.boolean().refine((v) => v, {
- message: 'Þú verður að samþykkja að forritun og prófunum sé lokið',
- }),
- endPointObject: endPoint,
- testProviderId: z.string().nonempty({
- message: 'Þú verður að stofna aðgang til að halda áfram',
- }),
- prodProviderId: z.string().nonempty({
- message: 'Þú verður að stofna aðgang til að halda áfram',
- }),
- productionEndPointObject: productionEndPoint,
- rejectionReason: z.string(),
- approvedByReviewer: z.enum(['APPROVE', 'REJECT']),
-})
-
const DocumentProviderOnboardingTemplate: ApplicationTemplate<
ApplicationContext,
ApplicationStateSchema,
diff --git a/libs/application/templates/document-provider-onboarding/src/lib/dataSchema.ts b/libs/application/templates/document-provider-onboarding/src/lib/dataSchema.ts
new file mode 100644
index 000000000000..e87b1833112c
--- /dev/null
+++ b/libs/application/templates/document-provider-onboarding/src/lib/dataSchema.ts
@@ -0,0 +1,75 @@
+import { z } from 'zod'
+import * as kennitala from 'kennitala'
+import { parsePhoneNumberFromString } from 'libphonenumber-js'
+import { AnswerOptions } from './types'
+
+const phoneNumberSchema = z.string().refine(
+ (p) => {
+ const phoneNumber = parsePhoneNumberFromString(p, 'IS')
+ return phoneNumber?.isValid()
+ },
+ { message: 'Símanúmer þarf að vera gilt' },
+)
+
+const contact = z.object({
+ name: z.string().nonempty({ message: 'Nafn þarf að vera útfyllt' }),
+ email: z.string().email({ message: 'Netfang þarf að vera gilt' }),
+ phoneNumber: phoneNumberSchema,
+})
+
+const helpDesk = z.object({
+ email: z.string().email({ message: 'Netfang þarf að vera gilt' }),
+ phoneNumber: phoneNumberSchema,
+})
+
+const applicant = z.object({
+ name: z.string().nonempty({ message: 'Nafn þarf að vera útfyllt' }),
+ email: z.string().email({ message: 'Netfang þarf að vera gilt' }),
+ phoneNumber: phoneNumberSchema,
+ nationalId: z.string().refine((k) => kennitala.isValid(k), {
+ message: 'Skrá þarf löglega kennitölu, með eða án bandstriks',
+ }),
+})
+
+const termsOfAgreement = z.object({
+ userTerms: z
+ .array(
+ z.nativeEnum(AnswerOptions).refine((v) => v === AnswerOptions.YES, {}),
+ )
+ .length(1),
+})
+
+const endPointObject = z.object({
+ endPoint: z.string().url().nonempty(),
+ endPointExists: z.string().nonempty({
+ message: 'Þú verður að vista endapunkt til að halda áfram',
+ }),
+})
+
+const productionEndPointObject = z.object({
+ prodEndPoint: z.string().url().nonempty(),
+ prodEndPointExists: z.string().nonempty({
+ message: 'Þú verður að vista endapunkt til að halda áfram',
+ }),
+})
+
+export const dataSchema = z.object({
+ termsOfAgreement,
+ applicant,
+ administrativeContact: contact,
+ technicalContact: contact,
+ helpDesk,
+ technicalAnswer: z.boolean().refine((v) => v, {
+ message: 'Þú verður að samþykkja að forritun og prófunum sé lokið',
+ }),
+ endPointObject,
+ testProviderId: z.string().nonempty({
+ message: 'Þú verður að stofna aðgang til að halda áfram',
+ }),
+ prodProviderId: z.string().nonempty({
+ message: 'Þú verður að stofna aðgang til að halda áfram',
+ }),
+ productionEndPointObject,
+ rejectionReason: z.string(),
+ approvedByReviewer: z.enum(['APPROVE', 'REJECT']),
+})
diff --git a/libs/application/templates/document-provider-onboarding/src/forms/messages.ts b/libs/application/templates/document-provider-onboarding/src/lib/messages.ts
similarity index 96%
rename from libs/application/templates/document-provider-onboarding/src/forms/messages.ts
rename to libs/application/templates/document-provider-onboarding/src/lib/messages.ts
index abcd1dd6a99d..117daec5b07b 100644
--- a/libs/application/templates/document-provider-onboarding/src/forms/messages.ts
+++ b/libs/application/templates/document-provider-onboarding/src/lib/messages.ts
@@ -336,37 +336,22 @@ export const m = defineMessages({
'Til að gerast skjalaveitandi þarf að útfæra tvenn forritunarskil. Annarsvegar eru það skil til að senda skjalatilvísun í pósthólf og hinsvegar eru það skil til að hægt sé að nálgast skjal hjá skjalaveitu. Hlekkirnir hér undir innihalda upplýsingar um tæknilegar útfærslur á þessum skilum. Í þessu ferli færð þú aðgang að prófunarumhverfi til þess að útfæra þjónustuna. Þegar þjónustan er tilbúin og prófunum er lokið, er hægt að framkvæma sjálfvirkar prófanir til að staðfesta virkni.',
description: '',
},
- thankYouScreenLinkUrl1: {
- id: 'dpo.application:thankYouScreen.linkUrl1',
+ thankYouScreenLink1: {
+ id: 'dpo.application:thankYouScreen.link1#markdown',
defaultMessage:
- 'http://assets.ctfassets.net/8k0h54kbe6bj/Cy8xoQ5fX1Cef99GVYH4L/d12d148dace0528d67e59da19e732304/Design-1.0.0-DocumentProviders.pdf',
+ '[Tæknilýsing vegna samskipta skjalaveitu við Pósthólf (aðeins á ensku)](http://assets.ctfassets.net/8k0h54kbe6bj/Cy8xoQ5fX1Cef99GVYH4L/d12d148dace0528d67e59da19e732304/Design-1.0.0-DocumentProviders.pdf)',
description: '',
},
- thankYouScreenLinkText1: {
- id: 'dpo.application:thankYouScreen.linkText1',
+ thankYouScreenLink2: {
+ id: 'dpo.application:thankYouScreen.link2#markdown',
defaultMessage:
- 'Tæknilýsing vegna samskipta skjalaveitu við Pósthólf (aðeins á ensku)',
- description: '',
- },
- thankYouScreenLinkUrl2: {
- id: 'dpo.application:thankYouScreen.linkUrl2',
- defaultMessage: 'https://github.com/digitaliceland/postholf-demo',
- description: '',
- },
- thankYouScreenLinkText2: {
- id: 'dpo.application:thankYouScreen.linkText2',
- defaultMessage: 'Sýnidæmi á Github fyrir samskipti við Pósthólf island.is',
+ '[Sýnidæmi á Github fyrir samskipti við Pósthólf island.is](https://github.com/digitaliceland/postholf-demo)',
description: '',
},
- thankYouScreenLinkUrl3: {
- id: 'dpo.application:thankYouScreen.linkUrl3',
+ thankYouScreenLink3: {
+ id: 'dpo.application:thankYouScreen.link3#markdown',
defaultMessage:
- 'http://assets.ctfassets.net/8k0h54kbe6bj/1MkIyeKtuc7c6BlbmKIOYz/c987f9e6a5d9a5284887869671c178a8/oryggisgatlisti-postholf.pdf',
- description: '',
- },
- thankYouScreenLinkText3: {
- id: 'dpo.application:thankYouScreen.linkText3',
- defaultMessage: 'Öryggiskröfur sem gerðar eru til skjalaveitna',
+ '[Öryggiskröfur sem gerðar eru til skjalaveitna](http://assets.ctfassets.net/8k0h54kbe6bj/1MkIyeKtuc7c6BlbmKIOYz/c987f9e6a5d9a5284887869671c178a8/oryggisgatlisti-postholf.pdf)',
description: '',
},
thankYouScreenFooterMessage: {
diff --git a/libs/application/templates/document-provider-onboarding/src/lib/types.ts b/libs/application/templates/document-provider-onboarding/src/lib/types.ts
new file mode 100644
index 000000000000..ee9e312850c3
--- /dev/null
+++ b/libs/application/templates/document-provider-onboarding/src/lib/types.ts
@@ -0,0 +1,4 @@
+export enum AnswerOptions {
+ YES = 'yes',
+ NO = 'no',
+}
diff --git a/libs/application/templates/driving-license/src/fields/Done/Declined.tsx b/libs/application/templates/driving-license/src/fields/Done/Declined.tsx
index 8a4dedbe6041..53d87aa42330 100644
--- a/libs/application/templates/driving-license/src/fields/Done/Declined.tsx
+++ b/libs/application/templates/driving-license/src/fields/Done/Declined.tsx
@@ -1,5 +1,3 @@
-import React from 'react'
-
import { Box, Text } from '@island.is/island-ui/core'
import { useLocale } from '@island.is/localization'
import { formatText } from '@island.is/application/core'
@@ -7,7 +5,7 @@ import { FieldBaseProps } from '@island.is/application/types'
import { m } from '../../lib/messages'
import WarningSection from './WarningSection'
-export const Declined = ({ application }: FieldBaseProps): JSX.Element => {
+export const Declined = ({ application }: FieldBaseProps) => {
const { formatMessage } = useLocale()
return (
diff --git a/libs/application/templates/driving-license/src/fields/QualityPhoto/Bullets/Bullets.tsx b/libs/application/templates/driving-license/src/fields/QualityPhoto/Bullets/Bullets.tsx
deleted file mode 100644
index 13fc651aecca..000000000000
--- a/libs/application/templates/driving-license/src/fields/QualityPhoto/Bullets/Bullets.tsx
+++ /dev/null
@@ -1,61 +0,0 @@
-import { BulletList, Bullet } from '@island.is/island-ui/core'
-import { formatText } from '@island.is/application/core'
-import { Application } from '@island.is/application/types'
-import { m } from '../../../lib/messages'
-import { useLocale } from '@island.is/localization'
-
-interface BulletsData {
- application: Application
-}
-
-const Bullets = ({ application }: BulletsData) => {
- const { formatMessage } = useLocale()
- return (
-
-
- {formatText(
- m.qualityPhotoInstructionsBulletOne,
- application,
- formatMessage,
- )}
-
-
- {formatText(
- m.qualityPhotoInstructionsBulletTwo,
- application,
- formatMessage,
- )}
-
-
- {formatText(
- m.qualityPhotoInstructionsBulletThree,
- application,
- formatMessage,
- )}
-
-
- {formatText(
- m.qualityPhotoInstructionsBulletFour,
- application,
- formatMessage,
- )}
-
-
- {formatText(
- m.qualityPhotoInstructionsBulletFive,
- application,
- formatMessage,
- )}
-
-
- {formatText(
- m.qualityPhotoInstructionsBulletSix,
- application,
- formatMessage,
- )}
-
-
- )
-}
-
-export { Bullets }
diff --git a/libs/application/templates/driving-license/src/fields/QualityPhoto/index.tsx b/libs/application/templates/driving-license/src/fields/QualityPhoto/index.tsx
index c6d9fafe013f..43a4a218ad41 100644
--- a/libs/application/templates/driving-license/src/fields/QualityPhoto/index.tsx
+++ b/libs/application/templates/driving-license/src/fields/QualityPhoto/index.tsx
@@ -1,2 +1 @@
export { QualityPhoto } from './QualityPhoto'
-export { Bullets } from './Bullets/Bullets'
diff --git a/libs/application/templates/driving-license/src/fields/index.ts b/libs/application/templates/driving-license/src/fields/index.ts
index 3f3b59970559..6f42ecaa4bb4 100644
--- a/libs/application/templates/driving-license/src/fields/index.ts
+++ b/libs/application/templates/driving-license/src/fields/index.ts
@@ -4,5 +4,5 @@ export { EligibilitySummary } from './EligibilitySummary'
export { SubmitAndDecline } from './SubmitAndDecline'
export { LinkExistingApplication } from './LinkExistingApplication'
export { PaymentPending } from './PaymentPending'
-export { QualityPhoto, Bullets } from './QualityPhoto'
+export { QualityPhoto } from './QualityPhoto'
export { default as HealthRemarks } from './HealthRemarks'
diff --git a/libs/application/templates/driving-license/src/forms/done.ts b/libs/application/templates/driving-license/src/forms/done.ts
index c1b5dbb94789..419eab62728d 100644
--- a/libs/application/templates/driving-license/src/forms/done.ts
+++ b/libs/application/templates/driving-license/src/forms/done.ts
@@ -28,7 +28,7 @@ export const done: Form = buildForm({
? m.nextStepsDescriptionBEFull
: needsHealthCertificateCondition(YES)(answers, externalData)
? m.nextStepsDescriptionBFull
- : '',
+ : m.nextStepsInfoLink,
}),
],
})
diff --git a/libs/application/templates/driving-license/src/forms/draft/subSectionQualityPhoto.ts b/libs/application/templates/driving-license/src/forms/draft/subSectionQualityPhoto.ts
index 4887a1199ed0..fbd707d70264 100644
--- a/libs/application/templates/driving-license/src/forms/draft/subSectionQualityPhoto.ts
+++ b/libs/application/templates/driving-license/src/forms/draft/subSectionQualityPhoto.ts
@@ -5,6 +5,7 @@ import {
buildRadioField,
buildSubSection,
getValueViaPath,
+ buildDescriptionField,
} from '@island.is/application/core'
import { m } from '../../lib/messages'
import { HasQualityPhotoData } from '../../lib/types'
@@ -47,10 +48,10 @@ export const subSectionQualityPhoto = buildSubSection({
{ value: YES, label: m.qualityPhotoAcknowledgement },
],
}),
- buildCustomField({
- id: 'photdesc',
+ buildDescriptionField({
+ id: 'photodesc',
title: '',
- component: 'Bullets',
+ description: m.qualityPhotoInstructionBullets,
condition: (answers) =>
getValueViaPath(answers, 'willBringQualityPhoto') === YES,
}),
@@ -71,10 +72,10 @@ export const subSectionQualityPhoto = buildSubSection({
component: 'QualityPhoto',
id: 'qphoto',
}),
- buildCustomField({
- id: 'photodescription',
+ buildDescriptionField({
+ id: 'photodesc',
title: '',
- component: 'Bullets',
+ description: m.qualityPhotoInstructionBullets,
}),
buildCheckboxField({
id: 'willBringQualityPhoto',
diff --git a/libs/application/templates/driving-license/src/lib/messages.ts b/libs/application/templates/driving-license/src/lib/messages.ts
index 0567c433b4ed..9ae2238b273b 100644
--- a/libs/application/templates/driving-license/src/lib/messages.ts
+++ b/libs/application/templates/driving-license/src/lib/messages.ts
@@ -324,46 +324,10 @@ export const m = defineMessages({
`,
description: 'Description of photo requirements',
},
- qualityPhotoInstructionsBulletOne: {
- id: 'dl.application:qualityPhoto.instructionsbulletone',
- defaultMessage: `
- Ljósmynd af umsækjanda þarf að vera tekin beint að framan.
- `,
- description: 'Description of photo requirements',
- },
- qualityPhotoInstructionsBulletTwo: {
- id: 'dl.application:qualityPhoto.instructionsbullettwo',
- defaultMessage: `
- Sýna þarf höfuð (án höfuðfats) og herðar.
- `,
- description: 'Description of photo requirements',
- },
- qualityPhotoInstructionsBulletThree: {
- id: 'dl.application:qualityPhoto.instructionsbulletthree',
- defaultMessage: `
- Lýsing andlits þarf að vera jöfn.
- `,
- description: 'Description of photo requirements',
- },
- qualityPhotoInstructionsBulletFour: {
- id: 'dl.application:qualityPhoto.instructionsbulletfour',
- defaultMessage: `
- Athuga þarf að ekki glampi á gleraugu og skyggi á augu.
- `,
- description: 'Description of photo requirements',
- },
- qualityPhotoInstructionsBulletFive: {
- id: 'dl.application:qualityPhoto.instructionsbulletfive',
- defaultMessage: `
- Bakgrunnur þarf að vera ljós og ekki virka truflandi á myndefni.
- `,
- description: 'Description of photo requirements',
- },
- qualityPhotoInstructionsBulletSix: {
- id: 'dl.application:qualityPhoto.instructionsbulletsix',
- defaultMessage: `
- Ljósmyndin þarf að vera prentuð á ljósmyndapappír og 35x45mm að stærð.
- `,
+ qualityPhotoInstructionBullets: {
+ id: 'dl.application:qualityPhoto.instructionbullets#markdown',
+ defaultMessage:
+ '* Myndin skal vera andlitsmynd, tekin þannig að andlitið snúi beint að myndavél og bæði augu sjáist.\n* Umsækjandi má ekki bera höfuðfat. Þó má heimila slíkt ef umsækjandi fer fram á það af trúarástæðum.\n* Lýsing andlits þarf að vera jöfn og góð.\n* Umsækjandi má ekki bera dökk gleraugu eða gleraugu með speglun.\n* Myndin skal vera jafnlýst, bakgrunnur ljósgrár, hlutlaus og án skugga.\n* Ljósmyndin þarf að vera prentuð á ljósmyndapappír og 35x45mm að stærð.',
description: 'Description of photo requirements',
},
overviewBringAlongTitle: {
@@ -517,17 +481,25 @@ export const m = defineMessages({
nextStepsDescription: {
id: 'dl.application:nextStepsDescription#markdown',
defaultMessage:
- 'Næst þarf umsækjandi að mæta til sýslumanns með mynd og gefa rithandarsýnishorn.',
+ 'Næst þarf umsækjandi að mæta til sýslumanns með mynd og gefa rithandarsýnishorn. \n[Stafræn ökunámsbók - starfsreglur](https://island.is/stafraen-oekunamsbok/upplysingar-um-personuvernd)',
description: 'Next steps',
},
nextStepsDescriptionBFull: {
id: 'dl.application:nextStepsDescriptionBFull#markdown',
- defaultMessage: 'Næst þarf umsækjandi að mæta til sýslumanns',
+ defaultMessage:
+ 'Næst þarf umsækjandi að mæta til sýslumanns. \n[Stafræn ökunámsbók - starfsreglur](https://island.is/stafraen-oekunamsbok/upplysingar-um-personuvernd)',
description: '',
},
nextStepsDescriptionBEFull: {
id: 'dl.application:nextStepsDescriptionBEFull#markdown',
- defaultMessage: 'Næst þarf umsækjandi að mæta til sýslumanns',
+ defaultMessage:
+ 'Næst þarf umsækjandi að mæta til sýslumanns. \n[Stafræn ökunámsbók - starfsreglur](https://island.is/stafraen-oekunamsbok/upplysingar-um-personuvernd)',
+ description: '',
+ },
+ nextStepsInfoLink: {
+ id: 'dl.application:nextStepsInfoLink#markdown',
+ defaultMessage:
+ '[Stafræn ökunámsbók - starfsreglur](https://island.is/stafraen-oekunamsbok/upplysingar-um-personuvernd)',
description: '',
},
congratulationsCertificateTitle: {
diff --git a/libs/application/templates/estate/src/fields/DoneImage/assets/Grieving.tsx b/libs/application/templates/estate/src/components/assets/Grieving.tsx
similarity index 100%
rename from libs/application/templates/estate/src/fields/DoneImage/assets/Grieving.tsx
rename to libs/application/templates/estate/src/components/assets/Grieving.tsx
diff --git a/libs/application/templates/estate/src/fields/Cards/index.tsx b/libs/application/templates/estate/src/fields/Cards/index.tsx
index 44a69b43e3a6..505db09ccd91 100644
--- a/libs/application/templates/estate/src/fields/Cards/index.tsx
+++ b/libs/application/templates/estate/src/fields/Cards/index.tsx
@@ -7,7 +7,7 @@ import {
ProfileCard,
} from '@island.is/island-ui/core'
import { FormatMessage, useLocale } from '@island.is/localization'
-import NotFilledOut from '../NotFilledOut'
+import { m } from '../../lib/messages'
type Props = {
field: {
@@ -28,6 +28,13 @@ export const Cards: FC> = ({
field,
}) => {
const { formatMessage } = useLocale()
+
+ const notFilledOut = (
+
+ {formatMessage(m.notFilledOut)}
+
+ )
+
return (
{field.props.cards(application).length ? (
@@ -47,15 +54,13 @@ export const Cards: FC> = ({
/>
) : (
-
+ notFilledOut
)}
)
})
) : (
-
-
-
+ {notFilledOut}
)}
)
diff --git a/libs/application/templates/estate/src/fields/DoneImage/index.tsx b/libs/application/templates/estate/src/fields/DoneImage/index.tsx
deleted file mode 100644
index 0b057497cd60..000000000000
--- a/libs/application/templates/estate/src/fields/DoneImage/index.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import { Box } from '@island.is/island-ui/core'
-import Grieving from './assets/Grieving'
-
-export const DoneImage = () => {
- return (
-
-
-
- )
-}
-
-export default DoneImage
diff --git a/libs/application/templates/estate/src/fields/NotFilledOut/index.tsx b/libs/application/templates/estate/src/fields/NotFilledOut/index.tsx
deleted file mode 100644
index 44e3b52f53ce..000000000000
--- a/libs/application/templates/estate/src/fields/NotFilledOut/index.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import { useLocale } from '@island.is/localization'
-import { m } from '../../lib/messages'
-import { Box } from '@island.is/island-ui/core'
-
-export const NotFilledOut = () => {
- const { formatMessage } = useLocale()
- return (
-
- {formatMessage(m.notFilledOut)}
-
- )
-}
-
-export default NotFilledOut
diff --git a/libs/application/templates/estate/src/fields/index.ts b/libs/application/templates/estate/src/fields/index.ts
index 18ba0cb09f51..7ddeb4c09e01 100644
--- a/libs/application/templates/estate/src/fields/index.ts
+++ b/libs/application/templates/estate/src/fields/index.ts
@@ -1,5 +1,4 @@
export { Cards } from './Cards'
-export { DoneImage } from './DoneImage'
export { EstateMembersRepeater } from './EstateMembersRepeater'
export { RealEstateRepeater } from './RealEstateRepeater'
export { OtherAssetsRepeater } from './OtherAssetsRepeater'
@@ -7,4 +6,3 @@ export { VehicleRepeater } from './VehicleRepeater'
export { TextFieldsRepeater } from './TextFieldsRepeater'
export { AssetsRepeater } from './AssetsRepeater'
export { LookupPerson } from './LookupPerson'
-export { NotFilledOut } from './NotFilledOut'
diff --git a/libs/application/templates/estate/src/forms/Done.ts b/libs/application/templates/estate/src/forms/Done.ts
index 2805f02e48cf..960effe812aa 100644
--- a/libs/application/templates/estate/src/forms/Done.ts
+++ b/libs/application/templates/estate/src/forms/Done.ts
@@ -1,14 +1,15 @@
import {
buildForm,
- buildCustomField,
buildMultiField,
getValueViaPath,
buildMessageWithLinkButtonField,
coreMessages,
+ buildImageField,
} from '@island.is/application/core'
import { Form, FormModes } from '@island.is/application/types'
import { m } from '../lib/messages'
import { EstateTypes } from '../lib/constants'
+import Grieving from '../components/assets/Grieving'
export const done: Form = buildForm({
id: 'divisionOfEstateDone',
@@ -33,10 +34,13 @@ export const done: Form = buildForm({
: m.divisionOfEstateByHeirsSubtitle
},
children: [
- buildCustomField({
+ buildImageField({
id: 'doneImage',
- component: 'DoneImage',
title: '',
+ image: Grieving,
+ marginBottom: 3,
+ imageWidth: 'auto',
+ imagePosition: 'center',
}),
buildMessageWithLinkButtonField({
id: 'goToServicePortal',
diff --git a/libs/application/templates/estate/src/forms/OverviewSections/assetsAndDebts.ts b/libs/application/templates/estate/src/forms/OverviewSections/assetsAndDebts.ts
index 51534c61c449..6012ab35fa92 100644
--- a/libs/application/templates/estate/src/forms/OverviewSections/assetsAndDebts.ts
+++ b/libs/application/templates/estate/src/forms/OverviewSections/assetsAndDebts.ts
@@ -101,10 +101,12 @@ export const overviewAssetsAndDebts = [
marginBottom: 'gutter',
space: 'gutter',
}),
- buildCustomField({
+ buildDescriptionField({
id: 'inventoryNotFilledOut',
title: '',
- component: 'NotFilledOut',
+ description: m.notFilledOutItalic,
+ marginTop: [3],
+ marginBottom: [3],
condition: (answers) =>
getValueViaPath(answers, 'inventory.value') === '',
}),
@@ -448,10 +450,12 @@ export const overviewAssetsAndDebts = [
condition: (answers) =>
getValueViaPath(answers, 'moneyAndDeposit.value') !== '',
}),
- buildCustomField({
+ buildDescriptionField({
id: 'moneyAndDepositNotFilledOut',
title: '',
- component: 'NotFilledOut',
+ description: m.notFilledOutItalic,
+ marginTop: [3],
+ marginBottom: [3],
condition: (answers) => {
return getValueViaPath(answers, 'moneyAndDeposit.value') === ''
},
diff --git a/libs/application/templates/estate/src/forms/OverviewSections/attachments.ts b/libs/application/templates/estate/src/forms/OverviewSections/attachments.ts
index 04e0b41cdbc6..441bd6dfc2f9 100644
--- a/libs/application/templates/estate/src/forms/OverviewSections/attachments.ts
+++ b/libs/application/templates/estate/src/forms/OverviewSections/attachments.ts
@@ -31,10 +31,11 @@ export const overviewAttachments = [
return files?.attached?.file?.length > 0
},
}),
- buildCustomField({
+ buildDescriptionField({
id: 'attachmentsNotFilledOut',
title: '',
- component: 'NotFilledOut',
+ description: m.notFilledOutItalic,
+ space: 'gutter',
condition: (answers) => {
const files = getValueViaPath(answers, 'estateAttachments') as {
attached: { file: { length: number } }
@@ -42,9 +43,4 @@ export const overviewAttachments = [
return files?.attached?.file?.length === 0
},
}),
- buildDescriptionField({
- id: 'spaceAttachments',
- title: '',
- space: 'gutter',
- }),
]
diff --git a/libs/application/templates/estate/src/forms/OverviewSections/representative.ts b/libs/application/templates/estate/src/forms/OverviewSections/representative.ts
index cf1600b99883..de9e9d125d58 100644
--- a/libs/application/templates/estate/src/forms/OverviewSections/representative.ts
+++ b/libs/application/templates/estate/src/forms/OverviewSections/representative.ts
@@ -63,10 +63,10 @@ export const representativeOverview = [
condition: (answers) =>
!!getValueViaPath(answers, 'representative.email'),
}),
- buildCustomField({
+ buildDescriptionField({
id: 'representativeNotFilledOut',
title: '',
- component: 'NotFilledOut',
+ description: m.notFilledOutItalic,
condition: (answers) =>
!getValueViaPath(answers, 'representative.nationalId'),
}),
diff --git a/libs/application/templates/estate/src/lib/messages.ts b/libs/application/templates/estate/src/lib/messages.ts
index 00c91232c0c0..77f7f2629314 100644
--- a/libs/application/templates/estate/src/lib/messages.ts
+++ b/libs/application/templates/estate/src/lib/messages.ts
@@ -958,10 +958,15 @@ export const m = defineMessages({
description: '',
},
notFilledOut: {
- id: 'es.application:notFilledOut',
+ id: 'es.application:notFilledOut#markdown',
defaultMessage: 'Ekki fyllt út',
description: '',
},
+ notFilledOutItalic: {
+ id: 'es.application:notFilledOut#markdown',
+ defaultMessage: '*Ekki fyllt út*',
+ description: '',
+ },
// Submit
submitApplication: {
diff --git a/libs/application/templates/financial-statement-cemetery/.babelrc b/libs/application/templates/financial-statement-cemetery/.babelrc
new file mode 100644
index 000000000000..1ea870ead410
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/.babelrc
@@ -0,0 +1,12 @@
+{
+ "presets": [
+ [
+ "@nx/react/babel",
+ {
+ "runtime": "automatic",
+ "useBuiltIns": "usage"
+ }
+ ]
+ ],
+ "plugins": []
+}
diff --git a/libs/application/templates/financial-statement-cemetery/.eslintrc.json b/libs/application/templates/financial-statement-cemetery/.eslintrc.json
new file mode 100644
index 000000000000..772a43d27834
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/.eslintrc.json
@@ -0,0 +1,18 @@
+{
+ "extends": ["plugin:@nx/react", "../../../../.eslintrc.json"],
+ "ignorePatterns": ["!**/*"],
+ "overrides": [
+ {
+ "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
+ "rules": {}
+ },
+ {
+ "files": ["*.ts", "*.tsx"],
+ "rules": {}
+ },
+ {
+ "files": ["*.js", "*.jsx"],
+ "rules": {}
+ }
+ ]
+}
diff --git a/libs/application/templates/financial-statement-cemetery/README.md b/libs/application/templates/financial-statement-cemetery/README.md
new file mode 100644
index 000000000000..759b46c0bb58
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/README.md
@@ -0,0 +1,7 @@
+# financial-statement-cemetery
+
+This application turns in financial statements for cemeteries to the The Icelandic National Audit Office (Ríkisendurskoðun, inao for short).
+
+## Running unit tests
+
+Run `nx test financial-statement-cemetery` to execute the unit tests via [Jest](https://jestjs.io).
diff --git a/libs/application/templates/financial-statement-cemetery/jest.config.ts b/libs/application/templates/financial-statement-cemetery/jest.config.ts
new file mode 100644
index 000000000000..d1a9047508d2
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/jest.config.ts
@@ -0,0 +1,12 @@
+/* eslint-disable */
+export default {
+ displayName: 'financial-statement-cemetery',
+ preset: '../../../../jest.preset.js',
+ transform: {
+ '^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nx/react/plugins/jest',
+ '^.+\\.[tj]sx?$': ['babel-jest', { presets: ['@nx/react/babel'] }],
+ },
+ moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
+ coverageDirectory:
+ '../../../../coverage/libs/application/templates/financial-statement-cemetery',
+}
diff --git a/libs/application/templates/financial-statement-cemetery/project.json b/libs/application/templates/financial-statement-cemetery/project.json
new file mode 100644
index 000000000000..cb3b7eecab67
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/project.json
@@ -0,0 +1,26 @@
+{
+ "name": "financial-statement-cemetery",
+ "$schema": "../../../../node_modules/nx/schemas/project-schema.json",
+ "sourceRoot": "libs/application/templates/financial-statement-cemetery/src",
+ "projectType": "library",
+ "tags": ["scope:application-system", "lib:application-system"],
+ "generators": {},
+ "targets": {
+ "lint": {
+ "executor": "@nx/eslint:lint"
+ },
+ "extract-strings": {
+ "executor": "nx:run-commands",
+ "options": {
+ "command": "yarn ts-node -P libs/localization/tsconfig.lib.json libs/localization/scripts/extract 'libs/application/templates/financial-statement-cemetery/src/lib/messages.ts'"
+ }
+ },
+ "test": {
+ "executor": "@nx/jest:jest",
+ "outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
+ "options": {
+ "jestConfig": "libs/application/templates/financial-statement-cemetery/jest.config.ts"
+ }
+ }
+ }
+}
diff --git a/libs/application/templates/financial-statement-cemetery/src/components/Logo.tsx b/libs/application/templates/financial-statement-cemetery/src/components/Logo.tsx
new file mode 100644
index 000000000000..a3fc5fc686a4
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/components/Logo.tsx
@@ -0,0 +1,20 @@
+import { useLocale } from '@island.is/localization'
+import { Box, Text } from '@island.is/island-ui/core'
+import { m } from '../lib/messages'
+
+const Logo = () => {
+ const { formatMessage } = useLocale()
+
+ return (
+
+
+ {formatMessage(m.serviceProvider)}
+
+
+ {formatMessage(m.inao).toUpperCase()}
+
+
+ )
+}
+
+export default Logo
diff --git a/libs/application/templates/financial-statement-cemetery/src/dataProviders/index.ts b/libs/application/templates/financial-statement-cemetery/src/dataProviders/index.ts
new file mode 100644
index 000000000000..91d817999f92
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/dataProviders/index.ts
@@ -0,0 +1,18 @@
+import { defineTemplateApi } from '@island.is/application/types'
+import { UserProfileApi } from '@island.is/application/types'
+
+export {
+ NationalRegistryUserApi,
+ IdentityApi as IndentityApiProvider,
+} from '@island.is/application/types'
+
+export const CurrentUserTypeProvider = defineTemplateApi({
+ action: 'getUserType',
+ externalDataId: 'currentUserType',
+})
+
+export const UserInfoApi = UserProfileApi.configure({
+ params: {
+ catchMock: true,
+ },
+})
diff --git a/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryCareteker/CemeteryCaretaker.css.ts b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryCareteker/CemeteryCaretaker.css.ts
new file mode 100644
index 000000000000..b9419afdce8e
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryCareteker/CemeteryCaretaker.css.ts
@@ -0,0 +1,13 @@
+import { theme, themeUtils } from '@island.is/island-ui/theme'
+import { style } from '@vanilla-extract/css'
+
+export const removeFieldButton = style({
+ top: '-94%',
+ right: -theme.spacing['2'],
+ ...themeUtils.responsiveStyle({
+ md: {
+ top: '50%',
+ right: -theme.spacing['3'],
+ },
+ }),
+})
diff --git a/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryCareteker/CemeteryCaretakerRepeaterItem.tsx b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryCareteker/CemeteryCaretakerRepeaterItem.tsx
new file mode 100644
index 000000000000..b843a538d72d
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryCareteker/CemeteryCaretakerRepeaterItem.tsx
@@ -0,0 +1,154 @@
+import { useState, useEffect } from 'react'
+import { useFormContext } from 'react-hook-form'
+import { IdentityInput, Query } from '@island.is/api/schema'
+import * as kennitala from 'kennitala'
+
+import { RecordObject } from '@island.is/application/types'
+import {
+ Box,
+ Button,
+ GridColumn,
+ GridRow,
+ GridContainer,
+} from '@island.is/island-ui/core'
+import { useLocale } from '@island.is/localization'
+import { m } from '../../lib/messages'
+import { useLazyQuery } from '@apollo/client'
+import { getValueViaPath, getErrorViaPath } from '@island.is/application/core'
+
+import { FinancialStatementCemetery } from '../../lib/dataSchema'
+import * as styles from './CemeteryCaretaker.css'
+import { IdentityQuery } from '../../graphql'
+import { BOARDMEMEBER, CARETAKER } from '../../utils/constants'
+import {
+ InputController,
+ SelectController,
+} from '@island.is/shared/form-fields'
+
+type Props = {
+ id: string
+ index: number
+ answers: FinancialStatementCemetery
+ handleRemoveCaretaker: (index: number) => void
+ errors: RecordObject | undefined
+}
+
+export const CaretakerRepeaterItem = ({
+ id,
+ index,
+ answers,
+ errors,
+ handleRemoveCaretaker,
+}: Props) => {
+ const { formatMessage } = useLocale()
+
+ const [nationalIdInput, setNationalIdInput] = useState('')
+
+ const { clearErrors, setValue } = useFormContext()
+
+ const fieldIndex = `${id}[${index}]`
+ const nameField = `${fieldIndex}.name`
+ const nationalIdField = `${fieldIndex}.nationalId`
+ const roleField = `${fieldIndex}.role`
+
+ const [getIdentity, { loading, error: queryError }] = useLazyQuery<
+ Query,
+ { input: IdentityInput }
+ >(IdentityQuery, {
+ onCompleted: (data) => {
+ setValue(nameField, data.identity?.name ?? '')
+ },
+ })
+
+ useEffect(() => {
+ clearErrors()
+ if (nationalIdInput.length === 10 && kennitala.isValid(nationalIdInput)) {
+ getIdentity({
+ variables: {
+ input: {
+ nationalId: nationalIdInput,
+ },
+ },
+ })
+ }
+ }, [nationalIdInput, getIdentity, clearErrors])
+
+ return (
+
+
+
+
+
+ setNationalIdInput(v.target.value.replace(/\W/g, ''))
+ }
+ error={errors && getErrorViaPath(errors, nationalIdField)}
+ defaultValue={
+ getValueViaPath(answers, nationalIdField, '') as string
+ }
+ />
+
+
+
+
+ {index > 0 && (
+
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryCareteker/index.tsx b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryCareteker/index.tsx
new file mode 100644
index 000000000000..af4434842a2e
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryCareteker/index.tsx
@@ -0,0 +1,156 @@
+import { useEffect, useCallback } from 'react'
+import { useFieldArray, useFormContext } from 'react-hook-form'
+import {
+ Box,
+ Button,
+ GridRow,
+ GridContainer,
+ InputError,
+} from '@island.is/island-ui/core'
+import { useLocale } from '@island.is/localization'
+import { m } from '../../lib/messages'
+import { FieldBaseProps } from '@island.is/application/types'
+
+import { FinancialStatementCemetery } from '../../lib/dataSchema'
+import {
+ APPLICANTASMEMBER,
+ ACTORASCARETAKER,
+ ACTORLONEBOARDMEMBER,
+} from '../../utils/constants'
+
+import { getBoardmembersAndCaretakers } from '../../utils/helpers'
+import { CaretakerRepeaterItem } from './CemeteryCaretakerRepeaterItem'
+import { BoardMember } from '../../types/types'
+
+export const CemeteryCaretaker = ({
+ application,
+ field,
+ errors,
+ setBeforeSubmitCallback,
+}: FieldBaseProps) => {
+ const { formatMessage } = useLocale()
+ const { id } = field
+
+ const { getValues, setError } = useFormContext()
+ const values = getValues()
+
+ const { fields, append, remove } = useFieldArray({
+ name: id ?? '',
+ })
+
+ const handleAddCaretaker = useCallback(() => {
+ append({
+ nationalId: '',
+ name: '',
+ role: '',
+ })
+ }, [append])
+
+ const handleRemoveCaretaker = (index: number) => remove(index)
+
+ useEffect(() => {
+ if (fields.length === 0) handleAddCaretaker()
+ }, [fields, handleAddCaretaker])
+
+ setBeforeSubmitCallback &&
+ setBeforeSubmitCallback(async () => {
+ const actors = application.applicantActors
+ const currentActor: string = actors[actors.length - 1]
+
+ console.log('Values: ', values)
+
+ const allMembers = values.cemeteryCaretaker
+ const { careTakers, boardMembers } =
+ getBoardmembersAndCaretakers(allMembers)
+
+ const caretakersIncludeActor =
+ careTakers.filter((careTaker) => careTaker === currentActor).length > 0
+
+ const boardMembersIncludeActor =
+ boardMembers.filter((boardMember) => boardMember === currentActor)
+ .length > 0
+
+ const includesApplicant =
+ allMembers.filter(
+ (member: BoardMember) => member.nationalId === application.applicant,
+ ).length > 0
+
+ if (caretakersIncludeActor) {
+ setError(ACTORASCARETAKER, {
+ type: 'custom',
+ message: formatMessage(m.errorCaretakerCanNotIncludeActor),
+ })
+ return [false, formatMessage(m.errorCaretakerCanNotIncludeActor)]
+ } else if (boardMembersIncludeActor && boardMembers.length <= 1) {
+ setError(ACTORLONEBOARDMEMBER, {
+ type: 'custom',
+ message: formatMessage(m.errorCaretakerCanNotIncludeActor),
+ })
+ return [false, formatMessage(m.errorCaretakerCanNotIncludeActor)]
+ } else if (includesApplicant) {
+ setError(APPLICANTASMEMBER, {
+ type: 'custom',
+ message: formatMessage(m.errorMemberCanNotIncludeApplicant),
+ })
+ return [false, formatMessage(m.errorMemberCanNotIncludeApplicant)]
+ } else {
+ return [true, null]
+ }
+ })
+
+ return (
+
+ {fields.map((field, index) => (
+
+
+
+ ))}
+
+
+
+
+
+ {errors && errors.cemeteryCaretaker ? (
+
+ ) : null}
+ {errors && errors.applicantasmember ? (
+
+ ) : null}
+ {errors && errors.actorascaretaker ? (
+
+ ) : null}
+ {errors && errors.actorloneboardmember ? (
+
+ ) : null}
+
+ )
+}
diff --git a/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryEquities/index.tsx b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryEquities/index.tsx
new file mode 100644
index 000000000000..e16606e47af3
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryEquities/index.tsx
@@ -0,0 +1,326 @@
+import { useState, useEffect } from 'react'
+import {
+ AlertBanner,
+ Box,
+ GridColumn,
+ GridContainer,
+ GridRow,
+ Text,
+} from '@island.is/island-ui/core'
+import debounce from 'lodash/debounce'
+import { useFormContext } from 'react-hook-form'
+import { useLocale } from '@island.is/localization'
+import { FieldBaseProps } from '@island.is/application/types'
+import { InputController } from '@island.is/shared/form-fields'
+import { m } from '../../lib/messages'
+import { Total } from '../KeyNumbers'
+import { getErrorViaPath, getValueViaPath } from '@island.is/application/core'
+import {
+ CAPITALNUMBERS,
+ CEMETERYEQUITIESANDLIABILITIESIDS,
+ INPUTCHANGEINTERVAL,
+ OPERATINGCOST,
+ VALIDATOR,
+} from '../../utils/constants'
+import { useTotals } from '../../hooks/useTotals'
+import { getTotal } from '../../utils/helpers'
+
+export const CemeteryEquities = ({
+ application,
+ setBeforeSubmitCallback,
+}: FieldBaseProps) => {
+ const answers = application.answers
+ const { formatMessage } = useLocale()
+ const {
+ clearErrors,
+ formState: { errors },
+ setValue,
+ getValues,
+ setError,
+ } = useFormContext()
+
+ const operatingCostTotal = Number(
+ getValueViaPath(answers, OPERATINGCOST.total),
+ )
+
+ const capitalTotal = Number(getValueViaPath(answers, CAPITALNUMBERS.total))
+
+ useEffect(() => {
+ const total = operatingCostTotal + capitalTotal
+ setValue(CEMETERYEQUITIESANDLIABILITIESIDS.operationResult, total)
+ setTotalOperatingCost(total)
+ }, [operatingCostTotal, capitalTotal, setValue])
+
+ const [totalOperatingCost, setTotalOperatingCost] = useState(0)
+ const [equityTotal, setEquityTotal] = useState(0)
+ const [equityAndDebts, setEquityAndDebts] = useState(0)
+
+ const [getTotalAssets, totalAssets] = useTotals(
+ CEMETERYEQUITIESANDLIABILITIESIDS.assetPrefix,
+ )
+ const [getTotalLiabilities, totalLiabilities] = useTotals(
+ CEMETERYEQUITIESANDLIABILITIESIDS.liabilityPrefix,
+ )
+ const [getTotalEquity, totalEquity] = useTotals(
+ CEMETERYEQUITIESANDLIABILITIESIDS.equityPrefix,
+ )
+
+ useEffect(() => {
+ setEquityTotal(totalEquity)
+ }, [totalEquity, totalOperatingCost])
+
+ useEffect(() => {
+ const total = totalEquity + totalLiabilities
+ setEquityAndDebts(total)
+ }, [totalEquity, totalLiabilities])
+
+ useEffect(() => {
+ clearErrors(VALIDATOR)
+ }, [totalEquity, totalLiabilities, totalAssets, clearErrors])
+
+ // we need to validate some info before allowing submission of the current screen data
+ // since we're comparing values from different objects, doing it via zod is not an option
+ setBeforeSubmitCallback &&
+ setBeforeSubmitCallback(async () => {
+ const values = getValues()
+ const assets = getTotal(values, 'cemetryAsset')
+ const liabilties = getTotal(values, 'cemetryLiability')
+ const equities = getTotal(values, 'cemetryEquity')
+
+ // assets should equal liabilties + equities
+ const isValid = liabilties + equities === assets
+ if (!isValid) {
+ setError(VALIDATOR, {
+ type: 'custom',
+ message: formatMessage(m.equityDebtsAssetsValidatorError),
+ })
+ return [false, formatMessage(m.equityDebtsAssetsValidatorError)]
+ }
+ return [true, null]
+ })
+
+ return (
+
+
+
+
+ {formatMessage(m.properties)}
+
+
+ {
+ getTotalAssets()
+ clearErrors(CEMETERYEQUITIESANDLIABILITIESIDS.fixedAssetsTotal)
+ }, INPUTCHANGEINTERVAL)}
+ label={formatMessage(m.fixedAssetsTotal)}
+ backgroundColor="blue"
+ rightAlign
+ currency
+ />
+
+
+ {
+ getTotalAssets()
+ clearErrors(CEMETERYEQUITIESANDLIABILITIESIDS.currentAssets)
+ }, INPUTCHANGEINTERVAL)}
+ label={formatMessage(m.currentAssets)}
+ error={
+ errors &&
+ getErrorViaPath(
+ errors,
+ CEMETERYEQUITIESANDLIABILITIESIDS.currentAssets,
+ )
+ }
+ backgroundColor="blue"
+ rightAlign
+ currency
+ />
+
+
+
+
+
+ {formatMessage(m.debtsAndEquity)}
+
+
+ {
+ getTotalLiabilities()
+ clearErrors(CEMETERYEQUITIESANDLIABILITIESIDS.longTerm)
+ }, INPUTCHANGEINTERVAL)}
+ error={
+ errors &&
+ getErrorViaPath(
+ errors,
+ CEMETERYEQUITIESANDLIABILITIESIDS.longTerm,
+ )
+ }
+ label={formatMessage(m.longTerm)}
+ backgroundColor="blue"
+ rightAlign
+ currency
+ />
+
+
+ {
+ getTotalLiabilities()
+ clearErrors(CEMETERYEQUITIESANDLIABILITIESIDS.shortTerm)
+ }, INPUTCHANGEINTERVAL)}
+ error={
+ errors &&
+ getErrorViaPath(
+ errors,
+ CEMETERYEQUITIESANDLIABILITIESIDS.shortTerm,
+ )
+ }
+ label={formatMessage(m.shortTerm)}
+ backgroundColor="blue"
+ rightAlign
+ currency
+ />
+
+
+
+ {
+ getTotalEquity()
+ clearErrors(
+ CEMETERYEQUITIESANDLIABILITIESIDS.equityAtTheBeginningOfTheYear,
+ )
+ }, INPUTCHANGEINTERVAL)}
+ error={
+ errors &&
+ getErrorViaPath(
+ errors,
+ CEMETERYEQUITIESANDLIABILITIESIDS.equityAtTheBeginningOfTheYear,
+ )
+ }
+ label={formatMessage(m.equityAtTheBeginningOfTheYear)}
+ backgroundColor="blue"
+ rightAlign
+ currency
+ />
+
+
+ {
+ getTotalEquity()
+ clearErrors(
+ CEMETERYEQUITIESANDLIABILITIESIDS.revaluationDueToPriceChanges,
+ )
+ }, INPUTCHANGEINTERVAL)}
+ error={
+ errors &&
+ getErrorViaPath(
+ errors,
+ CEMETERYEQUITIESANDLIABILITIESIDS.revaluationDueToPriceChanges,
+ )
+ }
+ label={formatMessage(m.revaluationDueToPriceChanges)}
+ backgroundColor="blue"
+ rightAlign
+ currency
+ />
+
+
+ {
+ getTotalEquity()
+ clearErrors(CEMETERYEQUITIESANDLIABILITIESIDS.reevaluateOther)
+ }, INPUTCHANGEINTERVAL)}
+ error={
+ errors &&
+ getErrorViaPath(
+ errors,
+ CEMETERYEQUITIESANDLIABILITIESIDS.reevaluateOther,
+ )
+ }
+ label={formatMessage(m.reevaluateOther)}
+ backgroundColor="blue"
+ rightAlign
+ currency
+ />
+
+
+
+
+
+
+
+
+
+
+ {errors && errors.validator ? (
+
+
+
+ ) : null}
+
+ )
+}
diff --git a/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryIncomeLimit/index.tsx b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryIncomeLimit/index.tsx
new file mode 100644
index 000000000000..a76d1ed2d9e0
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryIncomeLimit/index.tsx
@@ -0,0 +1,43 @@
+import { useEffect } from 'react'
+import { AlertMessage, ContentBlock } from '@island.is/island-ui/core'
+import { useLocale } from '@island.is/localization'
+import { useQuery } from '@apollo/client'
+import { useFormContext } from 'react-hook-form'
+import { m } from '../../lib/messages'
+import { financialLimitQuery } from '../../graphql'
+import { CEMETERYOPERATIONIDS } from '../../utils/constants'
+import { FSIUSERTYPE } from '../../types/types'
+
+export const CemeteryIncomeLimit = () => {
+ const { getValues, setValue } = useFormContext()
+ const { formatMessage } = useLocale()
+
+ const values = getValues()
+ const year: string = values?.conditionalAbout?.operatingYear
+
+ const { data, error } = useQuery(financialLimitQuery, {
+ variables: { input: { year, clientType: `${FSIUSERTYPE.CEMETRY}` } },
+ })
+
+ useEffect(() => {
+ const limit =
+ data?.financialStatementCemeteryClientFinancialLimit?.toString()
+ if (limit) {
+ setValue(CEMETERYOPERATIONIDS.incomeLimit, limit)
+ }
+ }, [data, setValue])
+
+ if (error) {
+ return (
+
+
+
+ )
+ }
+
+ return null
+}
diff --git a/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOperation/CemeteryExpenses.tsx b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOperation/CemeteryExpenses.tsx
new file mode 100644
index 000000000000..ef7aa2b9a900
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOperation/CemeteryExpenses.tsx
@@ -0,0 +1,168 @@
+import { useEffect } from 'react'
+import { useLocale } from '@island.is/localization'
+import { Box } from '@island.is/island-ui/core'
+import { InputController } from '@island.is/shared/form-fields'
+import { getErrorViaPath, getValueViaPath } from '@island.is/application/core'
+import { RecordObject } from '@island.is/application/types'
+import debounce from 'lodash/debounce'
+import { useFormContext } from 'react-hook-form'
+import { m } from '../../lib/messages'
+
+import { FinancialStatementsInaoTaxInfo } from '@island.is/api/schema'
+import {
+ CEMETERYOPERATIONIDS,
+ INPUTCHANGEINTERVAL,
+} from '../../utils/constants'
+type Props = {
+ data?: {
+ financialStatementsInaoTaxInfo: FinancialStatementsInaoTaxInfo[]
+ } | null
+ loading: boolean
+ getSum: () => void
+ errors: RecordObject | undefined
+}
+
+export const CemeteryExpenses = ({ data, loading, errors, getSum }: Props) => {
+ const { formatMessage } = useLocale()
+ const { clearErrors, setValue, getValues } = useFormContext()
+ const values = getValues()
+
+ const donationsToCemeteryFund = getValueViaPath(
+ values,
+ CEMETERYOPERATIONIDS.donationsToCemeteryFund,
+ )
+
+ useEffect(() => {
+ if (data?.financialStatementsInaoTaxInfo) {
+ if (!donationsToCemeteryFund) {
+ setValue(
+ CEMETERYOPERATIONIDS.donationsToCemeteryFund,
+ data.financialStatementsInaoTaxInfo
+ ?.find((x) => x.key === 334)
+ ?.value?.toString() ?? '',
+ )
+ }
+ }
+ getSum()
+ }, [data, getSum, setValue])
+
+ const onInputChange = debounce((fieldId: string) => {
+ getSum()
+ clearErrors(fieldId)
+ }, INPUTCHANGEINTERVAL)
+
+ return (
+ <>
+
+ onInputChange(CEMETERYOPERATIONIDS.payroll)}
+ error={
+ errors && getErrorViaPath(errors, CEMETERYOPERATIONIDS.payroll)
+ }
+ backgroundColor="blue"
+ rightAlign
+ currency
+ />
+
+
+ onInputChange(CEMETERYOPERATIONIDS.funeralCost)}
+ error={
+ errors && getErrorViaPath(errors, CEMETERYOPERATIONIDS.funeralCost)
+ }
+ backgroundColor="blue"
+ rightAlign
+ currency
+ />
+
+
+ onInputChange(CEMETERYOPERATIONIDS.chapelExpense)}
+ error={
+ errors &&
+ getErrorViaPath(errors, CEMETERYOPERATIONIDS.chapelExpense)
+ }
+ backgroundColor="blue"
+ rightAlign
+ currency
+ />
+
+
+
+ onInputChange(CEMETERYOPERATIONIDS.donationsToCemeteryFund)
+ }
+ error={
+ errors &&
+ getErrorViaPath(
+ errors,
+ CEMETERYOPERATIONIDS.donationsToCemeteryFund,
+ )
+ }
+ backgroundColor="blue"
+ rightAlign
+ currency
+ />
+
+
+ onInputChange(CEMETERYOPERATIONIDS.donationsToOther)}
+ error={
+ errors &&
+ getErrorViaPath(errors, CEMETERYOPERATIONIDS.donationsToOther)
+ }
+ backgroundColor="blue"
+ rightAlign
+ currency
+ />
+
+
+
+ onInputChange(CEMETERYOPERATIONIDS.otherOperationCost)
+ }
+ error={
+ errors &&
+ getErrorViaPath(errors, CEMETERYOPERATIONIDS.otherOperationCost)
+ }
+ backgroundColor="blue"
+ rightAlign
+ currency
+ />
+
+
+ onInputChange(CEMETERYOPERATIONIDS.depreciation)}
+ error={
+ errors && getErrorViaPath(errors, CEMETERYOPERATIONIDS.depreciation)
+ }
+ backgroundColor="blue"
+ rightAlign
+ currency
+ />
+
+ >
+ )
+}
diff --git a/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOperation/CemeteryIncome.tsx b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOperation/CemeteryIncome.tsx
new file mode 100644
index 000000000000..46179f7371da
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOperation/CemeteryIncome.tsx
@@ -0,0 +1,147 @@
+import { useEffect } from 'react'
+import { Box } from '@island.is/island-ui/core'
+import { RecordObject } from '@island.is/application/types'
+import debounce from 'lodash/debounce'
+import { InputController } from '@island.is/shared/form-fields'
+import { useLocale } from '@island.is/localization'
+import { useFormContext } from 'react-hook-form'
+import { getErrorViaPath, getValueViaPath } from '@island.is/application/core'
+import { m } from '../../lib/messages'
+import { FinancialStatementsInaoTaxInfo } from '@island.is/api/schema'
+import {
+ CEMETERYOPERATIONIDS,
+ INPUTCHANGEINTERVAL,
+ TaxInfoTypes,
+} from '../../utils/constants'
+
+type Props = {
+ data?: {
+ financialStatementsInaoTaxInfo: FinancialStatementsInaoTaxInfo[]
+ } | null
+ loading: boolean
+ getSum: () => void
+ errors: RecordObject | undefined
+}
+
+export const CemetryIncome = ({ data, loading, errors, getSum }: Props) => {
+ const { formatMessage } = useLocale()
+ const { clearErrors, getValues, setValue } = useFormContext()
+
+ useEffect(() => {
+ const values = getValues()
+
+ const careIncome = getValueViaPath(values, CEMETERYOPERATIONIDS.careIncome)
+ const burialRevenue = getValueViaPath(
+ values,
+ CEMETERYOPERATIONIDS.burialRevenue,
+ )
+ const grantFromTheCemeteryFund = getValueViaPath(
+ values,
+ CEMETERYOPERATIONIDS.grantFromTheCemeteryFund,
+ )
+
+ if (data?.financialStatementsInaoTaxInfo) {
+ if (!careIncome) {
+ setValue(
+ CEMETERYOPERATIONIDS.careIncome,
+ data.financialStatementsInaoTaxInfo
+ ?.find((x) => x.key === TaxInfoTypes.CARE_INCOME)
+ ?.value?.toString() ?? '',
+ )
+ }
+ if (!burialRevenue) {
+ setValue(
+ CEMETERYOPERATIONIDS.burialRevenue,
+ data.financialStatementsInaoTaxInfo
+ ?.find((x) => x.key === TaxInfoTypes.BURIAL_REVENUE)
+ ?.value?.toString() ?? '',
+ )
+ }
+ if (!grantFromTheCemeteryFund) {
+ setValue(
+ CEMETERYOPERATIONIDS.grantFromTheCemeteryFund,
+ data.financialStatementsInaoTaxInfo
+ ?.find((x) => x.key === TaxInfoTypes.GRANT_FROM_THE_CEMETERY_FUND)
+ ?.value?.toString() ?? '',
+ )
+ }
+ getSum()
+ }
+ }, [data, getSum, setValue])
+
+ const onInputChange = debounce((fieldId: string) => {
+ getSum()
+ clearErrors(fieldId)
+ }, INPUTCHANGEINTERVAL)
+
+ return (
+ <>
+
+ onInputChange(CEMETERYOPERATIONIDS.careIncome)}
+ backgroundColor="blue"
+ currency
+ rightAlign
+ error={
+ errors && getErrorViaPath(errors, CEMETERYOPERATIONIDS.careIncome)
+ }
+ />
+
+
+ onInputChange(CEMETERYOPERATIONIDS.burialRevenue)}
+ backgroundColor="blue"
+ currency
+ rightAlign
+ error={
+ errors &&
+ getErrorViaPath(errors, CEMETERYOPERATIONIDS.burialRevenue)
+ }
+ />
+
+
+
+ onInputChange(CEMETERYOPERATIONIDS.grantFromTheCemeteryFund)
+ }
+ backgroundColor="blue"
+ currency
+ rightAlign
+ error={
+ errors &&
+ getErrorViaPath(
+ errors,
+ CEMETERYOPERATIONIDS.grantFromTheCemeteryFund,
+ )
+ }
+ />
+
+
+ onInputChange(CEMETERYOPERATIONIDS.otherIncome)}
+ backgroundColor="blue"
+ currency
+ rightAlign
+ error={
+ errors && getErrorViaPath(errors, CEMETERYOPERATIONIDS.otherIncome)
+ }
+ />
+
+ >
+ )
+}
diff --git a/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOperation/index.tsx b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOperation/index.tsx
new file mode 100644
index 000000000000..424169cccdfa
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOperation/index.tsx
@@ -0,0 +1,95 @@
+import { useFormContext } from 'react-hook-form'
+import {
+ GridColumn,
+ GridContainer,
+ GridRow,
+ Text,
+} from '@island.is/island-ui/core'
+import { Application } from '@island.is/application/types'
+import { useLocale } from '@island.is/localization'
+import { m } from '../../lib/messages'
+import { Total } from '../KeyNumbers'
+import { CemetryIncome } from './CemeteryIncome'
+import { CemeteryExpenses } from './CemeteryExpenses'
+import { CemeteryIncomeLimit } from '../CemeteryIncomeLimit/index'
+import { useQuery } from '@apollo/client'
+import { getValueViaPath } from '@island.is/application/core'
+import { taxInfoQuery } from '../../graphql'
+import { CEMETERYOPERATIONIDS, OPERATINGCOST } from '../../utils/constants'
+import { useTotals } from '../../hooks/useTotals'
+
+export const CemeteryOperation = ({
+ application,
+}: {
+ application: Application
+}) => {
+ const { answers } = application
+
+ const operatingYear =
+ getValueViaPath(answers, 'conditionalAbout.operatingYear') ?? ''
+
+ const { data, loading } = useQuery(taxInfoQuery, {
+ variables: { year: operatingYear },
+ })
+
+ const {
+ formState: { errors },
+ } = useFormContext()
+ const { formatMessage } = useLocale()
+ const [getTotalIncome, totalIncome] = useTotals(
+ CEMETERYOPERATIONIDS.prefixIncome,
+ )
+ const [getTotalExpense, totalExpense] = useTotals(
+ CEMETERYOPERATIONIDS.prefixExpense,
+ )
+
+ return (
+
+
+
+
+
+ {formatMessage(m.income)}
+
+
+
+
+
+
+ {formatMessage(m.expenses)}
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOverview/AboutOverview.tsx b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOverview/AboutOverview.tsx
new file mode 100644
index 000000000000..926d2038faba
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOverview/AboutOverview.tsx
@@ -0,0 +1,63 @@
+import { GridColumn, GridRow } from '@island.is/island-ui/core'
+import { formatPhoneNumber } from '@island.is/application/ui-components'
+
+import { format as formatNationalId } from 'kennitala'
+import { m } from '../../lib/messages'
+import { sectionColumn } from './overviewStyles.css'
+import { FinancialStatementCemetery } from '../../lib/dataSchema'
+import { ValueLine } from './ValueLine'
+
+export const AboutOverview = ({
+ answers,
+}: {
+ answers: FinancialStatementCemetery
+}) => {
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+ {answers.about.powerOfAttorneyName ? (
+
+
+
+ ) : null}
+ {answers.about.powerOfAttorneyNationalId ? (
+
+
+
+ ) : null}
+
+
+
+
+
+
+
+
+
+ >
+ )
+}
diff --git a/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOverview/BottomBar.tsx b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOverview/BottomBar.tsx
new file mode 100644
index 000000000000..a014701fc18c
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOverview/BottomBar.tsx
@@ -0,0 +1,37 @@
+import { Box, Button, Divider } from '@island.is/island-ui/core'
+import { useLocale } from '@island.is/localization'
+import { m } from '../../lib/messages'
+
+type Props = {
+ onBackButtonClick: () => void
+ onSendButtonClick: () => void
+ loading?: boolean
+ sendText?: string
+}
+
+const BottomBar = ({
+ onBackButtonClick,
+ onSendButtonClick,
+ loading = false,
+ sendText,
+}: Props) => {
+ const { formatMessage } = useLocale()
+
+ return (
+ <>
+
+
+
+
+
+
+
+ >
+ )
+}
+
+export default BottomBar
diff --git a/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOverview/CapitalNumbersOverview.tsx b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOverview/CapitalNumbersOverview.tsx
new file mode 100644
index 000000000000..30f7f0a71bf7
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOverview/CapitalNumbersOverview.tsx
@@ -0,0 +1,53 @@
+import { Box, GridColumn, GridRow, Text } from '@island.is/island-ui/core'
+
+import { m } from '../../lib/messages'
+import { ValueLine } from '../CemeteryOverview/ValueLine'
+import {
+ sectionColumn,
+ starterColumnStyle,
+} from '../CemeteryOverview/overviewStyles.css'
+import { useLocale } from '@island.is/localization'
+import { FinancialStatementCemetery } from '../../lib/dataSchema'
+import { formatCurrency } from '../../utils/helpers'
+
+export const CapitalNumberOverview = ({
+ answers,
+}: {
+ answers: FinancialStatementCemetery
+}) => {
+ const { formatMessage } = useLocale()
+ return (
+ <>
+
+
+ {formatMessage(m.capitalNumbers)}
+
+
+
+
+
+
+ {answers.capitalNumbers?.capitalCost ? (
+
+
+
+ ) : null}
+
+
+
+
+
+
+ >
+ )
+}
diff --git a/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOverview/FileValueLine.tsx b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOverview/FileValueLine.tsx
new file mode 100644
index 000000000000..54ff41ae2139
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOverview/FileValueLine.tsx
@@ -0,0 +1,30 @@
+import { ActionCard, Box, Text } from '@island.is/island-ui/core'
+import { useLocale } from '@island.is/localization'
+import { m } from '../../lib/messages'
+
+type Props = {
+ label?: string
+}
+
+export const FileValueLine = ({ label = '' }: Props) => {
+ const { formatMessage } = useLocale()
+
+ return (
+
+ {formatMessage(m.files)}
+
+
+
+
+ )
+}
diff --git a/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOverview/ValueLine.tsx b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOverview/ValueLine.tsx
new file mode 100644
index 000000000000..e52d48763b63
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOverview/ValueLine.tsx
@@ -0,0 +1,29 @@
+import { Box, Text } from '@island.is/island-ui/core'
+import { useLocale } from '@island.is/localization'
+import { MessageDescriptor } from 'react-intl'
+
+type Props = {
+ label: string | MessageDescriptor
+ value?: string | MessageDescriptor
+ isTotal?: boolean
+}
+
+export const ValueLine = ({ label, value = '-', isTotal = false }: Props) => {
+ const { formatMessage } = useLocale()
+
+ return (
+
+
+ {formatMessage(label)}
+
+
+
+ {formatMessage(value)}
+
+
+ )
+}
diff --git a/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOverview/index.tsx b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOverview/index.tsx
new file mode 100644
index 000000000000..57040fecba5d
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOverview/index.tsx
@@ -0,0 +1,378 @@
+import { useState } from 'react'
+import { DefaultEvents, FieldBaseProps } from '@island.is/application/types'
+import { getErrorViaPath, getValueViaPath } from '@island.is/application/core'
+
+import {
+ AlertBanner,
+ Box,
+ Checkbox,
+ Divider,
+ GridColumn,
+ GridRow,
+ InputError,
+ Text,
+} from '@island.is/island-ui/core'
+import { Controller, useFormContext } from 'react-hook-form'
+import { useLocale } from '@island.is/localization'
+import { format as formatNationalId } from 'kennitala'
+import { useSubmitApplication } from '../../hooks/useSubmitApplication'
+import { m } from '../../lib/messages'
+import { FinancialStatementCemetery } from '../../lib/dataSchema'
+import { currencyStringToNumber, formatCurrency } from '../../utils/helpers'
+import { AboutOverview } from './AboutOverview'
+import { ValueLine } from './ValueLine'
+import { CapitalNumberOverview } from './CapitalNumbersOverview'
+import { BOARDMEMEBER } from '../../utils/constants'
+import { FileValueLine } from './FileValueLine'
+import BottomBar from './BottomBar'
+import {
+ columnStyle,
+ sectionColumn,
+ starterColumnStyle,
+} from './overviewStyles.css'
+
+export const CemeteryOverview = ({
+ application,
+ goToScreen,
+ refetch,
+}: FieldBaseProps) => {
+ const {
+ formState: { errors },
+ setError,
+ setValue,
+ } = useFormContext()
+ const { formatMessage } = useLocale()
+ const [approveOverview, setApproveOverview] = useState(false)
+
+ const [submitApplication, { error: submitError, loading }] =
+ useSubmitApplication({
+ application,
+ refetch,
+ event: DefaultEvents.SUBMIT,
+ })
+
+ const answers = application.answers as FinancialStatementCemetery
+ const fileName = answers.attachments?.file?.[0]?.name
+ const careTakerLimit = answers.cemeteryOperation?.incomeLimit ?? '0'
+ const cemeteryIncome = currencyStringToNumber(answers.cemeteryIncome?.total)
+ const fixedAssetsTotal = answers.cemeteryAsset?.fixedAssetsTotal
+ const longTermDebt = answers.cemeteryLiability?.longTerm
+ const email = getValueViaPath(answers, 'about.email')
+ const cemeteryCaretakers = answers.cemeteryCaretaker
+
+ const onBackButtonClick = () => {
+ if (
+ Number(cemeteryIncome) < Number(careTakerLimit) &&
+ fixedAssetsTotal === '0' &&
+ longTermDebt === '0'
+ ) {
+ goToScreen && goToScreen('caretakers')
+ } else {
+ goToScreen && goToScreen('attachments.file')
+ }
+ }
+
+ const onSendButtonClick = () => {
+ if (approveOverview) {
+ submitApplication()
+ } else {
+ setError('applicationApprove', {
+ type: 'error',
+ })
+ }
+ }
+
+ return (
+
+
+
+
+
+
+
+
+
+ {formatMessage(m.expensesIncome)}
+
+
+
+
+
+
+ {formatMessage(m.income)}
+
+
+
+
+
+
+
+
+
+
+
+ {formatMessage(m.expenses)}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {formatMessage(m.propertiesAndDebts)}
+
+
+
+
+
+
+ {formatMessage(m.properties)}
+
+
+
+
+
+
+
+
+
+
+
+ {formatMessage(m.debts)}
+
+
+
+
+
+
+
+ {formatMessage(m.equity)}
+
+
+
+
+
+
+
+
+
+
+
+
+ {parseInt(answers.cemeteryIncome?.total, 10) < Number(careTakerLimit) &&
+ cemeteryCaretakers?.length > 0 ? (
+ <>
+
+
+ {formatMessage(m.cemeteryBoardmembers)}
+
+
+ {cemeteryCaretakers.map((careTaker) => (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ ))}
+ >
+ ) : null}
+ {fileName ? (
+ <>
+
+
+ >
+ ) : null}
+
+
+ {formatMessage(m.overview)}
+
+
+
+
+ {
+ return (
+ {
+ onChange(e.target.checked)
+ setApproveOverview(e.target.checked)
+ setValue('applicationApprove' as string, e.target.checked)
+ }}
+ checked={value}
+ name="applicationApprove"
+ id="applicationApprove"
+ label={formatMessage(m.overviewCorrect)}
+ large
+ />
+ )
+ }}
+ />
+
+ {Number(cemeteryIncome) < Number(careTakerLimit) &&
+ fixedAssetsTotal === '0' &&
+ longTermDebt === '0' ? (
+
+
+
+ ) : null}
+ {errors && getErrorViaPath(errors, 'applicationApprove') ? (
+
+ ) : null}
+ {submitError ? (
+
+
+
+ ) : null}
+
+
+ )
+}
diff --git a/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOverview/overviewStyles.css.ts b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOverview/overviewStyles.css.ts
new file mode 100644
index 000000000000..02636c43d839
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/fields/CemeteryOverview/overviewStyles.css.ts
@@ -0,0 +1,26 @@
+import { style } from '@vanilla-extract/css'
+
+export const columnStyle = style({
+ paddingTop: '0px',
+ paddingBottom: '0px',
+ '@media': {
+ 'screen and (min-width: 576px)': {
+ paddingTop: '0.5rem',
+ paddingBottom: '0.5rem',
+ },
+ },
+})
+
+export const starterColumnStyle = style({
+ paddingTop: '1.5rem',
+ paddingBottom: '1rem',
+})
+
+export const sectionColumn = style({
+ '@media': {
+ print: {
+ flexBasis: '50%',
+ maxWidth: '50%',
+ },
+ },
+})
diff --git a/libs/application/templates/financial-statement-cemetery/src/fields/DelegationCheck/index.tsx b/libs/application/templates/financial-statement-cemetery/src/fields/DelegationCheck/index.tsx
new file mode 100644
index 000000000000..7c31e9fd9672
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/fields/DelegationCheck/index.tsx
@@ -0,0 +1,43 @@
+import { FieldBaseProps } from '@island.is/application/types'
+import { AlertBanner, Box } from '@island.is/island-ui/core'
+import { useLocale } from '@island.is/localization'
+import { useFormContext } from 'react-hook-form'
+import { FinancialStatementCemetery } from '../../lib/dataSchema'
+import { m } from '../../lib/messages'
+import { VALIDATOR } from '../../utils/constants'
+
+export const DelegationCheck = ({
+ application,
+ setBeforeSubmitCallback,
+}: FieldBaseProps) => {
+ const { formatMessage } = useLocale()
+ const {
+ formState: { errors },
+ setError,
+ } = useFormContext()
+ setBeforeSubmitCallback &&
+ setBeforeSubmitCallback(async () => {
+ const userType = application.externalData.getUserType?.data
+ const hasUserType = !!userType
+
+ if (hasUserType) {
+ setError(VALIDATOR, {
+ type: 'custom',
+ message: formatMessage(m.wrongDelegation),
+ })
+ return [false, formatMessage(m.wrongDelegation)]
+ } else {
+ return [true, null]
+ }
+ })
+
+ return errors && errors.validator ? (
+
+
+
+ ) : null
+}
diff --git a/libs/application/templates/financial-statement-cemetery/src/fields/KeyNumbers/index.tsx b/libs/application/templates/financial-statement-cemetery/src/fields/KeyNumbers/index.tsx
new file mode 100644
index 000000000000..d565106e5e7b
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/fields/KeyNumbers/index.tsx
@@ -0,0 +1,34 @@
+import { useEffect } from 'react'
+import { Box, Text } from '@island.is/island-ui/core'
+import { InputController } from '@island.is/shared/form-fields'
+import { useFormContext } from 'react-hook-form'
+
+type PropTypes = { name: string; total: number; label: string; title?: string }
+
+export const Total = ({ name, total, label, title }: PropTypes) => {
+ const { setValue } = useFormContext()
+
+ useEffect(() => {
+ setValue(name, total.toString())
+ }, [total])
+
+ return (
+
+ {title ? (
+
+ {title}
+
+ ) : null}
+
+
+
+ )
+}
diff --git a/libs/application/templates/financial-statement-cemetery/src/fields/KeyNumbersCapital/index.tsx b/libs/application/templates/financial-statement-cemetery/src/fields/KeyNumbersCapital/index.tsx
new file mode 100644
index 000000000000..23ce3e66e903
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/fields/KeyNumbersCapital/index.tsx
@@ -0,0 +1,94 @@
+import React, { useState, useEffect } from 'react'
+import {
+ Box,
+ GridColumn,
+ GridContainer,
+ GridRow,
+} from '@island.is/island-ui/core'
+import { getValueViaPath } from '@island.is/application/core'
+import debounce from 'lodash/debounce'
+import { useFormContext } from 'react-hook-form'
+import { useLocale } from '@island.is/localization'
+import { InputController } from '@island.is/shared/form-fields'
+import { m } from '../../lib/messages'
+import { Total } from '../KeyNumbers'
+
+import { getErrorViaPath } from '@island.is/application/core'
+import { CAPITALNUMBERS, INPUTCHANGEINTERVAL } from '../../utils/constants'
+
+export const KeyNumbersCapital = () => {
+ const { formatMessage } = useLocale()
+ const [totalCapital, setTotalCapital] = useState(0)
+ const {
+ clearErrors,
+ formState: { errors },
+ getValues,
+ } = useFormContext()
+
+ const getTotalCapital = () => {
+ const values = getValues()
+
+ const income = getValueViaPath(values, CAPITALNUMBERS.capitalIncome) || '0'
+ const expense = getValueViaPath(values, CAPITALNUMBERS.capitalCost) || '0'
+ const total = Number(income) - Number(expense)
+ setTotalCapital(total)
+ }
+
+ useEffect(() => {
+ getTotalCapital()
+ }, [getTotalCapital])
+
+ return (
+
+
+
+
+ {
+ getTotalCapital()
+ clearErrors(CAPITALNUMBERS.capitalIncome)
+ }, INPUTCHANGEINTERVAL)}
+ label={formatMessage(m.capitalIncome)}
+ backgroundColor="blue"
+ rightAlign
+ currency
+ />
+
+
+
+
+ {
+ getTotalCapital()
+ clearErrors(CAPITALNUMBERS.capitalCost)
+ }, INPUTCHANGEINTERVAL)}
+ label={formatMessage(m.capitalCost)}
+ error={
+ errors && getErrorViaPath(errors, CAPITALNUMBERS.capitalCost)
+ }
+ backgroundColor="blue"
+ rightAlign
+ currency
+ />
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/libs/application/templates/financial-statement-cemetery/src/fields/OperatingYear/index.tsx b/libs/application/templates/financial-statement-cemetery/src/fields/OperatingYear/index.tsx
new file mode 100644
index 000000000000..87dfb926490b
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/fields/OperatingYear/index.tsx
@@ -0,0 +1,84 @@
+import {
+ AlertMessage,
+ Box,
+ ContentBlock,
+ SkeletonLoader,
+} from '@island.is/island-ui/core'
+import { useLocale } from '@island.is/localization'
+import { m } from '../../lib/messages'
+
+import * as styles from './styles.css'
+import { useFormContext } from 'react-hook-form'
+import { getErrorViaPath } from '@island.is/application/core'
+import { SelectController } from '@island.is/shared/form-fields'
+import { useQuery } from '@apollo/client'
+
+import { getAuditConfig } from '../../graphql'
+import {
+ getConfigInfoForKey,
+ possibleOperatingYears,
+} from '../../utils/helpers'
+import {
+ ABOUTIDS,
+ CemeteriesBackwardLimit,
+ CemeteriesYearAllowed,
+} from '../../utils/constants'
+
+export const OperatingYear = () => {
+ const { data, loading, error } = useQuery(getAuditConfig)
+ const { formatMessage } = useLocale()
+ const {
+ formState: { errors },
+ } = useFormContext()
+
+ if (loading) {
+ return (
+
+
+
+ )
+ }
+
+ if (error || data?.financialStatementsInaoConfig?.length <= 0) {
+ return (
+
+
+
+ )
+ }
+
+ const { financialStatementsInaoConfig } = data
+
+ const backwardsYearLimit = getConfigInfoForKey(
+ financialStatementsInaoConfig,
+ CemeteriesBackwardLimit,
+ )
+
+ const countYearBackwardsFrom = getConfigInfoForKey(
+ financialStatementsInaoConfig,
+ CemeteriesYearAllowed,
+ )
+
+ const operatingYear = possibleOperatingYears(
+ backwardsYearLimit,
+ countYearBackwardsFrom,
+ )
+
+ return (
+
+
+
+ )
+}
diff --git a/libs/application/templates/financial-statement-cemetery/src/fields/OperatingYear/styles.css.ts b/libs/application/templates/financial-statement-cemetery/src/fields/OperatingYear/styles.css.ts
new file mode 100644
index 000000000000..c5dd8724f088
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/fields/OperatingYear/styles.css.ts
@@ -0,0 +1,5 @@
+import { style } from '@vanilla-extract/css'
+
+export const selectSpace = style({
+ paddingRight: '10px',
+})
diff --git a/libs/application/templates/financial-statement-cemetery/src/fields/PowerOfAttorney/index.tsx b/libs/application/templates/financial-statement-cemetery/src/fields/PowerOfAttorney/index.tsx
new file mode 100644
index 000000000000..cdf31e9ad78f
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/fields/PowerOfAttorney/index.tsx
@@ -0,0 +1,98 @@
+import { useEffect } from 'react'
+import { useFormContext } from 'react-hook-form'
+import { useLazyQuery } from '@apollo/client'
+import {
+ Box,
+ GridColumn,
+ GridContainer,
+ GridRow,
+ InputError,
+} from '@island.is/island-ui/core'
+import { InputController } from '@island.is/shared/form-fields'
+import { useLocale } from '@island.is/localization'
+import { IdentityInput, Query } from '@island.is/api/schema'
+
+import { m } from '../../lib/messages'
+
+import { FieldBaseProps } from '@island.is/application/types'
+import { getErrorViaPath } from '@island.is/application/core'
+import { IdentityQuery } from '../../graphql'
+import { ABOUTIDS } from '../../utils/constants'
+
+export const PowerOfAttorneyFields = ({ application }: FieldBaseProps) => {
+ const { formatMessage } = useLocale()
+ const {
+ formState: { errors },
+ setValue,
+ } = useFormContext()
+
+ const currentActor =
+ application.applicantActors[application.applicantActors.length - 1]
+
+ const [getIdentity, { loading, error: queryError }] = useLazyQuery<
+ Query,
+ { input: IdentityInput }
+ >(IdentityQuery, {
+ onCompleted: (data) => {
+ setValue(ABOUTIDS.powerOfAttorneyName, data.identity?.name ?? '')
+ },
+ })
+
+ useEffect(() => {
+ if (currentActor) {
+ getIdentity({
+ variables: {
+ input: {
+ nationalId: currentActor,
+ },
+ },
+ })
+ }
+ }, [])
+
+ if (application.applicantActors.length === 0) {
+ return null
+ }
+
+ return (
+
+
+
+
+
+
+
+
+
+
+ {queryError ? (
+
+ ) : null}
+
+
+
+
+ )
+}
diff --git a/libs/application/templates/financial-statement-cemetery/src/fields/Success/index.tsx b/libs/application/templates/financial-statement-cemetery/src/fields/Success/index.tsx
new file mode 100644
index 000000000000..381aa88a1499
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/fields/Success/index.tsx
@@ -0,0 +1,74 @@
+import {
+ Box,
+ ContentBlock,
+ ActionCard,
+ AlertMessage,
+} from '@island.is/island-ui/core'
+import { useLocale } from '@island.is/localization'
+import { CustomField, FieldBaseProps } from '@island.is/application/types'
+import format from 'date-fns/format'
+import { m } from '../../lib/messages'
+import { FinancialStatementCemetery } from '../../lib/dataSchema'
+import {
+ getCurrentUserType,
+ isCemetryUnderFinancialLimit,
+} from '../../utils/helpers'
+
+interface PropTypes extends FieldBaseProps {
+ field: CustomField
+}
+
+export const Success = ({ application }: PropTypes) => {
+ const { answers, externalData } = application
+ const applicationAnswers = application.answers as FinancialStatementCemetery
+ const userType = getCurrentUserType(answers, externalData)
+ const { formatMessage } = useLocale()
+
+ const getDescriptionText = () => {
+ const currentDate = format(new Date(), "dd.MM.yyyy 'kl.' kk:mm")
+ return `${formatMessage(m.operatingYearMsgFirst)} ${
+ applicationAnswers.conditionalAbout.operatingYear
+ }
+ ${formatMessage(m.individualReceivedMsgSecond)} ${currentDate}`
+ }
+
+ const shouldShowDigitalSigningMessage = () => {
+ return isCemetryUnderFinancialLimit(answers, externalData)
+ }
+
+ return (
+
+
+
+
+
+ {shouldShowDigitalSigningMessage() && (
+
+
+
+ )}
+
+ window.open('/minarsidur/postholf', '_blank'),
+ }}
+ backgroundColor="blue"
+ />
+
+
+
+ )
+}
diff --git a/libs/application/templates/financial-statement-cemetery/src/fields/index.ts b/libs/application/templates/financial-statement-cemetery/src/fields/index.ts
new file mode 100644
index 000000000000..a3db9a6b56c7
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/fields/index.ts
@@ -0,0 +1,9 @@
+export { CemeteryCaretaker } from './CemeteryCareteker'
+export { CemeteryOperation } from './CemeteryOperation'
+export { KeyNumbersCapital } from './KeyNumbersCapital'
+export { CemeteryEquities } from './CemeteryEquities'
+export { OperatingYear } from './OperatingYear'
+export { PowerOfAttorneyFields } from './PowerOfAttorney'
+export { DelegationCheck } from './DelegationCheck'
+export { CemeteryOverview } from './CemeteryOverview'
+export { Success } from './Success'
diff --git a/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/cemeteryCaretakerSection/caretakerMultiField.ts b/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/cemeteryCaretakerSection/caretakerMultiField.ts
new file mode 100644
index 000000000000..21b59e7439fe
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/cemeteryCaretakerSection/caretakerMultiField.ts
@@ -0,0 +1,17 @@
+import { buildCustomField, buildMultiField } from '@island.is/application/core'
+import { m } from '../../../lib/messages'
+import { CEMETERYCARETAKER } from '../../../utils/constants'
+
+export const caretakerMultiField = buildMultiField({
+ id: 'caretakers',
+ title: m.cemeteryBoardmembers,
+ description: m.cemeteryRegisterCaretakers,
+ children: [
+ buildCustomField({
+ id: 'cemeteryCaretaker',
+ title: m.cemeteryBoardmembers,
+ component: 'CemeteryCaretaker',
+ childInputIds: Object.values(CEMETERYCARETAKER),
+ }),
+ ],
+})
diff --git a/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/cemeteryCaretakerSection/index.ts b/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/cemeteryCaretakerSection/index.ts
new file mode 100644
index 000000000000..a5805af6e458
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/cemeteryCaretakerSection/index.ts
@@ -0,0 +1,9 @@
+import { buildSection } from '@island.is/application/core'
+import { m } from '../../../lib/messages'
+import { caretakerMultiField } from './caretakerMultiField'
+
+export const cemeteryCaretekerSection = buildSection({
+ id: 'cemeteryCaretekerSection',
+ title: m.cemeteryCaretakers,
+ children: [caretakerMultiField],
+})
diff --git a/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/cemeteryFinancialStatementSection/index.ts b/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/cemeteryFinancialStatementSection/index.ts
new file mode 100644
index 000000000000..8df2c99ea9cd
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/cemeteryFinancialStatementSection/index.ts
@@ -0,0 +1,38 @@
+import { buildFileUploadField, buildSection } from '@island.is/application/core'
+import { m } from '../../../lib/messages'
+import { currencyStringToNumber } from '../../../utils/helpers'
+import { FinancialStatementCemetery } from '../../../lib/dataSchema'
+
+export const cemeteryFinancialStatementSection = buildSection({
+ id: 'documents',
+ title: m.financialStatement,
+ children: [
+ buildFileUploadField({
+ id: 'attachments.file',
+ title: m.upload,
+ condition: (answers) => {
+ const applicationAnswers = answers as FinancialStatementCemetery
+ const careTakerLimit =
+ applicationAnswers.cemeteryOperation?.incomeLimit ?? '0'
+ const fixedAssetsTotal =
+ applicationAnswers.cemeteryAsset?.fixedAssetsTotal
+ const totalIncome = applicationAnswers.cemeteryIncome?.total
+ const longTermDebt = applicationAnswers.cemeteryLiability?.longTerm
+ const isUnderLimit =
+ currencyStringToNumber(totalIncome) < careTakerLimit
+ if (isUnderLimit && fixedAssetsTotal === '0' && longTermDebt === '0') {
+ return false
+ }
+ return true
+ },
+ introduction: m.uploadIntro,
+ description: m.uploadDescription,
+ uploadHeader: m.uploadHeader,
+ uploadAccept: '.pdf',
+ uploadDescription: m.uploadAccept,
+ uploadButtonLabel: m.uploadButtonLabel,
+ uploadMultiple: false,
+ forImageUpload: false,
+ }),
+ ],
+})
diff --git a/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/cemeteryKeyNumbersSection/capitalNumberSubSection.ts b/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/cemeteryKeyNumbersSection/capitalNumberSubSection.ts
new file mode 100644
index 000000000000..549bf3b78658
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/cemeteryKeyNumbersSection/capitalNumberSubSection.ts
@@ -0,0 +1,28 @@
+import {
+ buildCustomField,
+ buildMultiField,
+ buildSubSection,
+} from '@island.is/application/core'
+import { m } from '../../../lib/messages'
+import { CAPITALNUMBERS } from '../../../utils/constants'
+
+export const capitalNumberSubSection = buildSubSection({
+ id: 'keynumbers.capitalNumbers',
+ title: m.capitalNumbers,
+ children: [
+ buildMultiField({
+ id: 'capitalNumber',
+ title: m.capitalNumbersSectionTitle,
+ description: m.fillOutAppopriate,
+ children: [
+ buildCustomField({
+ id: 'capitalNumberField',
+ title: '',
+ description: '',
+ component: 'KeyNumbersCapital',
+ childInputIds: Object.values(CAPITALNUMBERS),
+ }),
+ ],
+ }),
+ ],
+})
diff --git a/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/cemeteryKeyNumbersSection/equityAndLiabilitySubSection.ts b/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/cemeteryKeyNumbersSection/equityAndLiabilitySubSection.ts
new file mode 100644
index 000000000000..f5cb6fdf8f6e
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/cemeteryKeyNumbersSection/equityAndLiabilitySubSection.ts
@@ -0,0 +1,28 @@
+import {
+ buildCustomField,
+ buildMultiField,
+ buildSubSection,
+} from '@island.is/application/core'
+import { m } from '../../../lib/messages'
+import { CEMETERYEQUITIESANDLIABILITIESIDS } from '../../../utils/constants'
+
+export const equityAndLiabilitiesSubSection = buildSubSection({
+ id: 'keyNumbers.cemetryEquitiesAndLiabilities',
+ title: m.propertiesAndDebts,
+ children: [
+ buildMultiField({
+ id: 'cemetryEquitiesAndLiabilities',
+ title: m.keyNumbersDebt,
+ description: m.fillOutAppopriate,
+ children: [
+ buildCustomField({
+ id: 'cemeteryEquitiesAndLiabilities',
+ title: m.keyNumbersDebt,
+ description: m.fillOutAppopriate,
+ component: 'CemeteryEquities',
+ childInputIds: Object.values(CEMETERYEQUITIESANDLIABILITIESIDS),
+ }),
+ ],
+ }),
+ ],
+})
diff --git a/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/cemeteryKeyNumbersSection/index.ts b/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/cemeteryKeyNumbersSection/index.ts
new file mode 100644
index 000000000000..0125b6327d17
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/cemeteryKeyNumbersSection/index.ts
@@ -0,0 +1,15 @@
+import { buildSection } from '@island.is/application/core'
+import { m } from '../../../lib/messages'
+import { opperatingCostSubSection } from './opperatingCostSubSection'
+import { capitalNumberSubSection } from './capitalNumberSubSection'
+import { equityAndLiabilitiesSubSection } from './equityAndLiabilitySubSection'
+
+export const cemeteryKeyNumbersSection = buildSection({
+ id: 'cemeteryKeyNumbers',
+ title: m.keynumbers,
+ children: [
+ opperatingCostSubSection,
+ capitalNumberSubSection,
+ equityAndLiabilitiesSubSection,
+ ],
+})
diff --git a/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/cemeteryKeyNumbersSection/opperatingCostSubSection.ts b/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/cemeteryKeyNumbersSection/opperatingCostSubSection.ts
new file mode 100644
index 000000000000..66ef7c08bc52
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/cemeteryKeyNumbersSection/opperatingCostSubSection.ts
@@ -0,0 +1,27 @@
+import {
+ buildCustomField,
+ buildMultiField,
+ buildSubSection,
+} from '@island.is/application/core'
+import { CEMETERYOPERATIONIDS } from '../../../utils/constants'
+import { m } from '../../../lib/messages'
+
+export const opperatingCostSubSection = buildSubSection({
+ id: 'operatingCost',
+ title: m.expensesIncome,
+ children: [
+ buildMultiField({
+ id: 'cemetryIncomeAndExpense',
+ title: m.keyNumbersIncomeAndExpenses,
+ description: m.fillOutAppopriate,
+ children: [
+ buildCustomField({
+ id: 'cemetryKeyNumbers',
+ title: '',
+ component: 'CemeteryOperation',
+ childInputIds: Object.values(CEMETERYOPERATIONIDS),
+ }),
+ ],
+ }),
+ ],
+})
diff --git a/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/clientInfoSection/index.ts b/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/clientInfoSection/index.ts
new file mode 100644
index 000000000000..9846bfef640e
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/clientInfoSection/index.ts
@@ -0,0 +1,105 @@
+import {
+ buildCustomField,
+ buildDescriptionField,
+ buildMultiField,
+ buildSection,
+ buildTextField,
+} from '@island.is/application/core'
+import { getCurrentUserType } from '../../../utils/helpers'
+import { Application, UserProfile } from '@island.is/application/types'
+import { m } from '../../../lib/messages'
+import { ABOUTIDS } from '../../../utils/constants'
+import { Identity } from '@island.is/api/schema'
+import { FSIUSERTYPE } from '../../../types/types'
+
+export const clientInfoSection = buildSection({
+ id: 'info',
+ title: m.info,
+ children: [
+ buildMultiField({
+ id: 'about',
+ title: m.info,
+ description: (application: Application) => {
+ const answers = application.answers
+ const externalData = application.externalData
+ const userType = getCurrentUserType(answers, externalData)
+ return userType === FSIUSERTYPE.INDIVIDUAL
+ ? m.reviewInfo
+ : m.reviewContact
+ },
+ children: [
+ buildDescriptionField({
+ id: ABOUTIDS.operatingYear,
+ title: '',
+ }),
+ buildCustomField({
+ id: 'OperatingYear',
+ childInputIds: [ABOUTIDS.operatingYear],
+ title: '',
+ component: 'OperatingYear',
+ }),
+ buildTextField({
+ id: 'about.nationalId',
+ title: m.clientNationalId,
+ width: 'half',
+ readOnly: true,
+ format: '######-####',
+ defaultValue: (application: Application) => application.applicant,
+ }),
+ buildTextField({
+ id: 'about.fullName',
+ title: m.clientName,
+ width: 'half',
+ readOnly: true,
+ defaultValue: (application: Application) => {
+ const nationalRegistry = application.externalData.identity
+ .data as Identity
+ return nationalRegistry.name
+ },
+ }),
+ buildDescriptionField({
+ id: ABOUTIDS.powerOfAttorneyName,
+ title: '',
+ }),
+ buildCustomField({
+ id: 'powerOfAttorney',
+ title: '',
+ description: '',
+ component: 'PowerOfAttorneyFields',
+ childInputIds: [
+ ABOUTIDS.powerOfAttorneyNationalId,
+ ABOUTIDS.powerOfAttorneyName,
+ ],
+ }),
+
+ buildTextField({
+ id: 'about.email',
+ title: m.email,
+ width: 'half',
+ variant: 'email',
+ defaultValue: (application: Application) => {
+ const userProfile = application.externalData.userProfile
+ .data as UserProfile
+ return userProfile.email
+ },
+ }),
+ buildTextField({
+ id: 'about.phoneNumber',
+ title: m.phoneNumber,
+ width: 'half',
+ variant: 'tel',
+ defaultValue: (application: Application) => {
+ const userProfile = application.externalData.userProfile
+ .data as UserProfile
+ return userProfile.mobilePhoneNumber
+ },
+ }),
+ buildCustomField({
+ id: 'delegation check',
+ component: 'DelegationCheck',
+ title: '',
+ }),
+ ],
+ }),
+ ],
+})
diff --git a/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/index.ts b/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/index.ts
new file mode 100644
index 000000000000..bf4875117557
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/index.ts
@@ -0,0 +1,24 @@
+import { buildForm } from '@island.is/application/core'
+import { Form, FormModes } from '@island.is/application/types'
+import { m } from '../../lib/messages'
+import { cemeteryKeyNumbersSection } from './cemeteryKeyNumbersSection'
+import { cemeteryCaretekerSection } from './cemeteryCaretakerSection'
+import { cemeteryFinancialStatementSection } from './cemeteryFinancialStatementSection'
+import Logo from '../../components/Logo'
+import { clientInfoSection } from './clientInfoSection'
+import { overviewSection } from './overviewSection'
+
+export const FinancialStatementCemeteryForm: Form = buildForm({
+ id: 'FinancialStatementCemeteryForm',
+ title: m.applicationTitle,
+ mode: FormModes.DRAFT,
+ renderLastScreenButton: false,
+ logo: Logo,
+ children: [
+ clientInfoSection,
+ cemeteryKeyNumbersSection,
+ cemeteryCaretekerSection,
+ cemeteryFinancialStatementSection,
+ overviewSection,
+ ],
+})
diff --git a/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/overviewSection/index.ts b/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/overviewSection/index.ts
new file mode 100644
index 000000000000..3d1cb64989b8
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/overviewSection/index.ts
@@ -0,0 +1,9 @@
+import { buildSection } from '@island.is/application/core'
+import { m } from '../../../lib/messages'
+import { overviewMultiField } from './oveviewMultiField'
+
+export const overviewSection = buildSection({
+ id: 'overviewSection',
+ title: m.overviewSectionTitle,
+ children: [overviewMultiField],
+})
diff --git a/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/overviewSection/oveviewMultiField.ts b/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/overviewSection/oveviewMultiField.ts
new file mode 100644
index 000000000000..4f93c70dd20a
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/forms/applicationForm/overviewSection/oveviewMultiField.ts
@@ -0,0 +1,16 @@
+import { buildCustomField, buildMultiField } from '@island.is/application/core'
+import { m } from '../../../lib/messages'
+
+export const overviewMultiField = buildMultiField({
+ id: 'overview',
+ title: m.yearlyOverview,
+ description: m.review,
+ children: [
+ buildCustomField({
+ id: 'overviewCemetryField',
+ title: '',
+ doesNotRequireAnswer: true,
+ component: 'CemeteryOverview',
+ }),
+ ],
+})
diff --git a/libs/application/templates/financial-statement-cemetery/src/forms/done/conclusionSection.ts b/libs/application/templates/financial-statement-cemetery/src/forms/done/conclusionSection.ts
new file mode 100644
index 000000000000..532136f509bc
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/forms/done/conclusionSection.ts
@@ -0,0 +1,24 @@
+import {
+ buildCustomField,
+ buildMultiField,
+ buildSection,
+} from '@island.is/application/core'
+import { m } from '../../lib/messages'
+
+export const conclusionSection = buildSection({
+ id: 'conclusionSection',
+ title: '',
+ children: [
+ buildMultiField({
+ id: 'conclusion',
+ title: m.received,
+ children: [
+ buildCustomField({
+ id: 'overview',
+ component: 'Success',
+ title: m.applicationAccept,
+ }),
+ ],
+ }),
+ ],
+})
diff --git a/libs/application/templates/financial-statement-cemetery/src/forms/done/index.ts b/libs/application/templates/financial-statement-cemetery/src/forms/done/index.ts
new file mode 100644
index 000000000000..e4ea0c21bc77
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/forms/done/index.ts
@@ -0,0 +1,11 @@
+import { buildForm } from '@island.is/application/core'
+import { Form, FormModes } from '@island.is/application/types'
+import { conclusionSection } from './conclusionSection'
+import { m } from '../../lib/messages'
+
+export const done: Form = buildForm({
+ id: 'done',
+ title: m.applicationAccept,
+ mode: FormModes.COMPLETED,
+ children: [conclusionSection],
+})
diff --git a/libs/application/templates/financial-statement-cemetery/src/forms/prerequisites/index.ts b/libs/application/templates/financial-statement-cemetery/src/forms/prerequisites/index.ts
new file mode 100644
index 000000000000..e8f8d9631b70
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/forms/prerequisites/index.ts
@@ -0,0 +1,13 @@
+import { buildForm } from '@island.is/application/core'
+import { Form, FormModes } from '@island.is/application/types'
+import Logo from '../../components/Logo'
+import { prerequisitesSection } from './prerequsitesSection'
+
+export const PrerequisitesForm: Form = buildForm({
+ id: 'PrerequisitesForm',
+ title: '',
+ mode: FormModes.NOT_STARTED,
+ renderLastScreenButton: true,
+ logo: Logo,
+ children: [prerequisitesSection],
+})
diff --git a/libs/application/templates/financial-statement-cemetery/src/forms/prerequisites/prerequsitesSection.ts b/libs/application/templates/financial-statement-cemetery/src/forms/prerequisites/prerequsitesSection.ts
new file mode 100644
index 000000000000..6b9bed52110a
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/forms/prerequisites/prerequsitesSection.ts
@@ -0,0 +1,56 @@
+import {
+ buildDataProviderItem,
+ buildExternalDataProvider,
+ buildSection,
+ buildSubmitField,
+ coreMessages,
+} from '@island.is/application/core'
+import { m } from '../../lib/messages'
+import {
+ CurrentUserTypeProvider,
+ IndentityApiProvider,
+ UserInfoApi,
+} from '../../dataProviders'
+import { DefaultEvents } from '@island.is/application/types'
+
+export const prerequisitesSection = buildSection({
+ id: 'ExternalDataSection',
+ title: '',
+ children: [
+ buildExternalDataProvider({
+ id: 'approveExternalData',
+ title: m.dataCollectionTitleUserCemetry,
+ checkboxLabel: m.dataCollectionCheckboxLabel,
+ dataProviders: [
+ buildDataProviderItem({
+ provider: IndentityApiProvider,
+ title: m.dataCollectionNationalRegistryTitle,
+ subTitle: m.dataCollectionNationalRegistrySubtitle,
+ }),
+ buildDataProviderItem({
+ provider: UserInfoApi,
+ title: m.dataCollectionUserProfileTitle,
+ subTitle: m.dataCollectionUserProfileSubtitle,
+ }),
+ buildDataProviderItem({
+ provider: CurrentUserTypeProvider,
+ title: m.dataCollectionUserFinancialInfoTitle,
+ subTitle: m.dataCollectionUserFinancialInfo,
+ }),
+ ],
+ submitField: buildSubmitField({
+ id: 'submit',
+ placement: 'footer',
+ title: '',
+ refetchApplicationAfterSubmit: true,
+ actions: [
+ {
+ event: DefaultEvents.SUBMIT,
+ name: coreMessages.buttonNext,
+ type: 'primary',
+ },
+ ],
+ }),
+ }),
+ ],
+})
diff --git a/libs/application/templates/financial-statement-cemetery/src/graphql/index.ts b/libs/application/templates/financial-statement-cemetery/src/graphql/index.ts
new file mode 100644
index 000000000000..a8772bef2253
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/graphql/index.ts
@@ -0,0 +1,36 @@
+import { gql } from '@apollo/client'
+
+export const IdentityQuery = gql`
+ query IdentityQuery($input: IdentityInput!) {
+ identity(input: $input) {
+ name
+ nationalId
+ }
+ }
+`
+
+export const taxInfoQuery = gql`
+ query TaxInfoQuery($year: String!) {
+ financialStatementsInaoTaxInfo(year: $year) {
+ key
+ value
+ }
+ }
+`
+
+export const financialLimitQuery = gql`
+ query FinancialStatementsInaoClientFinancialLimit(
+ $input: InaoClientFinancialLimitInput!
+ ) {
+ financialStatementsInaoClientFinancialLimit(input: $input)
+ }
+`
+
+export const getAuditConfig = gql`
+ query FinancialStatementsInaoConfig {
+ financialStatementsInaoConfig {
+ value
+ key
+ }
+ }
+`
diff --git a/libs/application/templates/financial-statement-cemetery/src/hooks/useSubmitApplication.ts b/libs/application/templates/financial-statement-cemetery/src/hooks/useSubmitApplication.ts
new file mode 100644
index 000000000000..de5e2838cb93
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/hooks/useSubmitApplication.ts
@@ -0,0 +1,43 @@
+import { MutationTuple, useMutation } from '@apollo/client'
+import { DefaultEvents, Application } from '@island.is/application/types'
+import { SUBMIT_APPLICATION } from '@island.is/application/graphql'
+
+export interface UseSubmitApplication {
+ (params: {
+ application: Application
+ refetch: (() => void) | undefined
+ event: DefaultEvents
+ }): MutationTuple<
+ void,
+ {
+ input: {
+ id: Application['id']
+ event: DefaultEvents
+ answers: Application['answers']
+ }
+ }
+ >
+}
+
+export const useSubmitApplication: UseSubmitApplication = ({
+ application,
+ refetch,
+ event,
+}) => {
+ return useMutation(SUBMIT_APPLICATION, {
+ onError: (e) => {
+ console.error(e.message)
+ return
+ },
+ onCompleted: () => {
+ refetch?.()
+ },
+ variables: {
+ input: {
+ id: application.id,
+ event,
+ answers: application.answers,
+ },
+ },
+ })
+}
diff --git a/libs/application/templates/financial-statement-cemetery/src/hooks/useTotals.ts b/libs/application/templates/financial-statement-cemetery/src/hooks/useTotals.ts
new file mode 100644
index 000000000000..15a5873fdd5e
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/hooks/useTotals.ts
@@ -0,0 +1,21 @@
+import { useCallback, useEffect, useState } from 'react'
+import { useFormContext } from 'react-hook-form'
+import { getTotal } from '../utils/helpers'
+
+const useTotals = (key: string): [() => void, number] => {
+ const [total, setTotal] = useState(0)
+ const { getValues } = useFormContext()
+ const getSum = useCallback(() => {
+ const values = getValues()
+ const sum = getTotal(values, key)
+ setTotal(sum)
+ }, [key, getValues, setTotal])
+
+ useEffect(() => {
+ getSum()
+ }, [getSum])
+
+ return [getSum, total]
+}
+
+export { useTotals }
diff --git a/libs/application/templates/financial-statement-cemetery/src/index.ts b/libs/application/templates/financial-statement-cemetery/src/index.ts
new file mode 100644
index 000000000000..3c37391dec2c
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/index.ts
@@ -0,0 +1,6 @@
+import FinancialStatementCemeteryTemplate from './lib/financialStatementCemeteryTemplate'
+
+export const getDataProviders = () => import('./dataProviders/')
+export const getFields = () => import('./fields/')
+
+export default FinancialStatementCemeteryTemplate
diff --git a/libs/application/templates/financial-statement-cemetery/src/lib/dataSchema.ts b/libs/application/templates/financial-statement-cemetery/src/lib/dataSchema.ts
new file mode 100644
index 000000000000..b177ee8daac2
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/lib/dataSchema.ts
@@ -0,0 +1,231 @@
+import { z } from 'zod'
+import { m } from './messages'
+import * as kennitala from 'kennitala'
+import { parsePhoneNumberFromString } from 'libphonenumber-js'
+import { BOARDMEMEBER, CARETAKER } from '../utils/constants'
+import { getBoardmembersAndCaretakers } from '../utils/helpers'
+
+const FileSchema = z.object({
+ name: z.string(),
+ key: z.string(),
+ url: z.string().optional(),
+})
+
+const checkIfNegative = (inputNumber: string) => {
+ if (Number(inputNumber) < 0) {
+ return false
+ } else {
+ return true
+ }
+}
+
+const conditionalAbout = z.object({
+ operatingYear: z.string().refine((x) => !!x, { params: m.required }),
+})
+
+const cemeteryOperation = z.object({
+ incomeLimit: z.string().optional(),
+})
+
+const cemeteryLiability = z.object({
+ longTerm: z
+ .string()
+ .refine((x) => !!x, { params: m.required })
+ .refine((x) => checkIfNegative(x), { params: m.negativeNumberError }),
+ shortTerm: z
+ .string()
+ .refine((x) => !!x, { params: m.required })
+ .refine((x) => checkIfNegative(x), { params: m.negativeNumberError }),
+ total: z.string().refine((x) => !!x, { params: m.required }),
+})
+
+const cemeteryAsset = z.object({
+ currentAssets: z
+ .string()
+ .refine((x) => !!x, { params: m.required })
+ .refine((x) => checkIfNegative(x), { params: m.negativeNumberError }),
+ fixedAssetsTotal: z
+ .string()
+ .refine((x) => !!x, { params: m.required })
+ .refine((x) => checkIfNegative(x), { params: m.negativeNumberError }),
+ total: z.string(),
+})
+
+const cemeteryIncome = z.object({
+ careIncome: z
+ .string()
+ .refine((x) => !!x, { params: m.required })
+ .refine((x) => checkIfNegative(x), { params: m.negativeNumberError }),
+ burialRevenue: z
+ .string()
+ .refine((x) => !!x, { params: m.required })
+ .refine((x) => checkIfNegative(x), { params: m.negativeNumberError }),
+ grantFromTheCemeteryFund: z
+ .string()
+ .refine((x) => !!x, { params: m.required })
+ .refine((x) => checkIfNegative(x), { params: m.negativeNumberError }),
+ otherIncome: z
+ .string()
+ .refine((x) => !!x, { params: m.required })
+ .refine((x) => checkIfNegative(x), { params: m.negativeNumberError }),
+ total: z.string(),
+})
+
+const cemeteryExpense = z.object({
+ payroll: z
+ .string()
+ .refine((x) => !!x, { params: m.required })
+ .refine((x) => checkIfNegative(x), { params: m.negativeNumberError }),
+ funeralCost: z
+ .string()
+ .refine((x) => !!x, { params: m.required })
+ .refine((x) => checkIfNegative(x), { params: m.negativeNumberError }),
+ chapelExpense: z
+ .string()
+ .refine((x) => !!x, { params: m.required })
+ .refine((x) => checkIfNegative(x), { params: m.negativeNumberError }),
+ donationsToOther: z
+ .string()
+ .refine((x) => !!x, { params: m.required })
+ .refine((x) => checkIfNegative(x), { params: m.negativeNumberError }),
+ cemeteryFundExpense: z
+ .string()
+ .refine((x) => !!x, { params: m.required })
+ .refine((x) => checkIfNegative(x), { params: m.negativeNumberError }),
+ otherOperationCost: z
+ .string()
+ .refine((x) => !!x, { params: m.required })
+ .refine((x) => checkIfNegative(x), { params: m.negativeNumberError }),
+ depreciation: z
+ .string()
+ .refine((x) => !!x, { params: m.required })
+ .refine((x) => checkIfNegative(x), { params: m.negativeNumberError }),
+ total: z.string(),
+})
+
+const about = z.object({
+ nationalId: z
+ .string()
+ .refine((val) => (val ? kennitala.isValid(val) : false), {
+ params: m.nationalIdError,
+ }),
+ fullName: z.string().refine((x) => !!x, { params: m.required }),
+ powerOfAttorneyNationalId: z.string().optional(),
+ powerOfAttorneyName: z.string().optional(),
+ phoneNumber: z.string().refine(
+ (p) => {
+ const phoneNumber = parsePhoneNumberFromString(p, 'IS')
+ return phoneNumber && phoneNumber.isValid()
+ },
+ { params: m.dataSchemePhoneNumber },
+ ),
+ email: z.string().email(),
+})
+
+const cemeteryCaretaker = z
+ .array(
+ z.object({
+ // name: z.string().refine((x) => !!x, { params: m.required }),
+ name: z.string(),
+ nationalId: z
+ .string()
+ .refine((val) => (val ? kennitala.isPerson(val) : false), {
+ params: m.nationalIdError,
+ })
+ .refine((val) => {
+ return (
+ val ? kennitala.info(val).age < 18 : false,
+ {
+ params: m.nationalIdAgeError,
+ }
+ )
+ }),
+ role: z.string().refine((x) => !!x, { params: m.required }),
+ }),
+ )
+ .refine(
+ (x) => {
+ if (x.length <= 0) {
+ return false
+ }
+ const careTakers = x.filter((member) => member.role === CARETAKER)
+ const boardMembers = x.filter((member) => member.role === BOARDMEMEBER)
+ if (careTakers.length < 1 || boardMembers.length < 1) {
+ return false
+ } else {
+ return true
+ }
+ },
+ { params: m.errorMembersMissing },
+ )
+ .refine(
+ (x) => {
+ const { careTakers, boardMembers } = getBoardmembersAndCaretakers(x)
+
+ const careTakersUnique = careTakers.filter((member) =>
+ boardMembers.includes(member),
+ )
+ const boardMembersUnique = boardMembers.filter((member) =>
+ careTakers.includes(member),
+ )
+
+ if (careTakersUnique.length > 0 || boardMembersUnique.length > 0) {
+ return false
+ } else {
+ return true
+ }
+ },
+ { params: m.errormemberNotUnique },
+ )
+
+const cemeteryEquity = z.object({
+ equityAtTheBeginningOfTheYear: z
+ .string()
+ .refine((x) => !!x, { params: m.required }),
+ operationResult: z.string(),
+ revaluationDueToPriceChanges: z
+ .string()
+ .refine((x) => !!x, { params: m.required })
+ .refine((x) => checkIfNegative(x), { params: m.negativeNumberError }),
+ reevaluateOther: z
+ .string()
+ .refine((x) => !!x, { params: m.required })
+ .refine((x) => checkIfNegative(x), { params: m.negativeNumberError }),
+ total: z.string(),
+})
+
+const equityAndLiabilities = z.object({
+ total: z.string(),
+})
+
+const capitalNumbers = z.object({
+ capitalIncome: z
+ .string()
+ .refine((x) => !!x, { params: m.required })
+ .refine((x) => checkIfNegative(x), { params: m.negativeNumberError }),
+ capitalCost: z
+ .string()
+ .refine((x) => !!x, { params: m.required })
+ .refine((x) => checkIfNegative(x), { params: m.negativeNumberError }),
+ total: z.string(),
+})
+
+export const dataSchema = z.object({
+ conditionalAbout,
+ about,
+ approveExternalData: z.boolean().refine((v) => v),
+ cemeteryOperation,
+ cemeteryAsset,
+ cemeteryLiability,
+ cemeteryIncome,
+ cemeteryExpense,
+ attachments: z.object({
+ file: z.array(FileSchema).nonempty(),
+ }),
+ cemeteryCaretaker,
+ cemeteryEquity,
+ equityAndLiabilities,
+ capitalNumbers,
+})
+
+export type FinancialStatementCemetery = z.TypeOf
diff --git a/libs/application/templates/financial-statement-cemetery/src/lib/financialStatementCemeteryTemplate.ts b/libs/application/templates/financial-statement-cemetery/src/lib/financialStatementCemeteryTemplate.ts
new file mode 100644
index 000000000000..ebd0fc224d5f
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/lib/financialStatementCemeteryTemplate.ts
@@ -0,0 +1,149 @@
+import {
+ DefaultStateLifeCycle,
+ pruneAfterDays,
+} from '@island.is/application/core'
+
+import {
+ ApplicationTemplate,
+ ApplicationTypes,
+ ApplicationContext,
+ ApplicationRole,
+ ApplicationStateSchema,
+ Application,
+ DefaultEvents,
+ ApplicationConfigurations,
+ defineTemplateApi,
+} from '@island.is/application/types'
+import { m } from './messages'
+import { AuthDelegationType } from '@island.is/shared/types'
+import { dataSchema } from './dataSchema'
+
+import {
+ CurrentUserTypeProvider,
+ IndentityApiProvider,
+ NationalRegistryUserApi,
+ UserInfoApi,
+} from '../dataProviders'
+import { ApiActions, Events, Roles, States } from '../types/types'
+import { Features } from '@island.is/feature-flags'
+
+const configuration =
+ ApplicationConfigurations[ApplicationTypes.FINANCIAL_STATEMENTS_INAO]
+
+const FinancialStatementCemeteryTemplate: ApplicationTemplate<
+ ApplicationContext,
+ ApplicationStateSchema,
+ Events
+> = {
+ type: ApplicationTypes.FINANCIAL_STATEMENT_CEMETERY,
+ name: m.applicationTitle,
+ institution: m.institutionName,
+ translationNamespaces: [configuration.translation],
+ featureFlag: Features.FinancialStatementCemetery,
+ dataSchema,
+ allowedDelegations: [{ type: AuthDelegationType.ProcurationHolder }],
+ stateMachineConfig: {
+ initial: States.PREREQUISITES,
+ states: {
+ [States.PREREQUISITES]: {
+ meta: {
+ name: States.PREREQUISITES,
+ progress: 0,
+ status: 'draft',
+ actionCard: {
+ pendingAction: {
+ title: '',
+ displayStatus: 'success',
+ },
+ },
+ lifecycle: pruneAfterDays(60),
+ roles: [
+ {
+ id: Roles.APPLICANT,
+ formLoader: () =>
+ import('../forms/prerequisites').then((val) =>
+ Promise.resolve(val.PrerequisitesForm),
+ ),
+ actions: [
+ {
+ event: DefaultEvents.SUBMIT,
+ name: 'Submit',
+ type: 'primary',
+ },
+ ],
+ write: 'all',
+ delete: true,
+ api: [
+ CurrentUserTypeProvider,
+ IndentityApiProvider,
+ NationalRegistryUserApi,
+ UserInfoApi,
+ ],
+ },
+ ],
+ },
+ on: {
+ [DefaultEvents.SUBMIT]: [{ target: States.DRAFT }],
+ },
+ },
+ [States.DRAFT]: {
+ meta: {
+ name: 'Draft',
+ actionCard: {
+ title: m.applicationTitle,
+ },
+ status: 'draft',
+ lifecycle: pruneAfterDays(60),
+ roles: [
+ {
+ id: Roles.APPLICANT,
+ formLoader: () =>
+ import('../forms/applicationForm').then((val) =>
+ Promise.resolve(val.FinancialStatementCemeteryForm),
+ ),
+ actions: [
+ { event: 'SUBMIT', name: 'Staðfesta', type: 'primary' },
+ ],
+ write: 'all',
+ delete: true,
+ api: [NationalRegistryUserApi, UserInfoApi],
+ },
+ ],
+ },
+ on: {
+ [DefaultEvents.SUBMIT]: { target: States.DONE },
+ },
+ },
+ [States.DONE]: {
+ meta: {
+ name: 'Done',
+ status: 'completed',
+ progress: 1,
+ lifecycle: DefaultStateLifeCycle,
+ onEntry: defineTemplateApi({
+ action: ApiActions.submitApplication,
+ throwOnError: true,
+ }),
+ roles: [
+ {
+ id: Roles.APPLICANT,
+ formLoader: () => import('../forms/done').then((val) => val.done),
+ read: 'all',
+ },
+ ],
+ },
+ },
+ },
+ },
+ mapUserToRole(
+ nationalId: string,
+ application: Application,
+ ): ApplicationRole | undefined {
+ if (application.applicant === nationalId) {
+ return Roles.APPLICANT
+ }
+ return undefined
+ },
+}
+
+export default FinancialStatementCemeteryTemplate
diff --git a/libs/application/templates/financial-statement-cemetery/src/lib/messages.ts b/libs/application/templates/financial-statement-cemetery/src/lib/messages.ts
new file mode 100644
index 000000000000..2cf2aa890850
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/lib/messages.ts
@@ -0,0 +1,673 @@
+import { defineMessages } from 'react-intl'
+
+export const m = defineMessages({
+ applicationTitle: {
+ id: 'fsc.application:title',
+ defaultMessage: 'Skil ársreikninga kirkjugarða',
+ description: 'Title of the application',
+ },
+ institutionName: {
+ id: 'fsc.application:institution',
+ defaultMessage: 'Ríkisendurskoðun',
+ description: `Institution's name`,
+ },
+ keynumbers: {
+ id: 'fsc.application:keynumbers',
+ defaultMessage: 'Lykiltölur',
+ description: 'Key numbers',
+ },
+ cemeteryCaretakers: {
+ id: 'fsc.application:cemeteryCaretakers',
+ defaultMessage: 'Umsjónaraðilar',
+ description: 'Cemetry caretakers',
+ },
+ cemeteryBoardmembers: {
+ id: 'fsc.application:cemeteryBoardmembers',
+ defaultMessage: 'Stjórnar- og skoðunarmenn',
+ description: 'Cemetries board and caretakers',
+ },
+ cemeteryRegisterCaretakers: {
+ id: 'fsc.application:cemeteryRegisterCaretakers',
+ defaultMessage:
+ 'Vinsamlegast skráið inn stjórnar- og skoðunarmenn kirkjugarðsins',
+ description: 'Cemetries board and caretakers',
+ },
+ expensesIncome: {
+ id: 'fsc.application:keyNumbers.expensesIncome',
+ defaultMessage: 'Tekjur og gjöld',
+ description: 'Expenses and income',
+ },
+ keyNumbersIncomeAndExpenses: {
+ id: 'fsc.application:keyNumbersIncomeAndExpenses',
+ defaultMessage: 'Lykiltölur - Tekjur og gjöld',
+ description: 'income and expenses of keynumbers',
+ },
+ fillOutAppopriate: {
+ id: 'fsc.application:fillOutAppopriate',
+ defaultMessage: 'Vinsamlegast fylltu út þá reiti sem eiga við',
+ description: 'Fill out fields',
+ },
+ capitalNumbers: {
+ id: 'fsc.application:income.capitalNumbers',
+ defaultMessage: 'Fjármagnsliðir',
+ description: 'capital numbers',
+ },
+ capitalNumbersSectionTitle: {
+ id: 'fsc.application:income.capitalNumbersSectionTitle',
+ defaultMessage: 'Lykiltölur Fjármagnsliðir',
+ description: 'capital numbers',
+ },
+ propertiesAndDebts: {
+ id: 'fsc.application:keyNumbers.properties',
+ defaultMessage: 'Eignir, skuldir og eigið fé',
+ description: 'Statement property numbers',
+ },
+ keyNumbersDebt: {
+ id: 'fsc.application:keyNumbers.debt',
+ defaultMessage: 'Lykiltölur - Eignir, Skuldir og eigið fé',
+ description: 'Statement debts',
+ },
+ required: {
+ id: 'fsc.application:error.required',
+ defaultMessage: 'Reitur má ekki vera tómur',
+ description: 'Error message when a required field has not been filled',
+ },
+ negativeNumberError: {
+ id: 'fsc.application:error.negativeNumberError',
+ defaultMessage: 'Ekki er leyfilegt að setja inn neikvæðar tölur',
+ description: 'Error message when a required field has not been filled',
+ },
+ nationalId: {
+ id: 'fsc.application:nationalId',
+ defaultMessage: 'Kennitala',
+ description: 'National id',
+ },
+ fullName: {
+ id: 'fsc.application:fullName',
+ defaultMessage: 'Fullt nafn',
+ description: 'Full name',
+ },
+ errorNationalIdIncorrect: {
+ id: 'fsc.application:error.nationalIdIncorrect',
+ defaultMessage: 'Þessi kennitala virðist ekki vera rétt',
+ description: 'National id is invalid',
+ },
+ role: {
+ id: 'fsc.application:role',
+ defaultMessage: 'Hlutverk',
+ description: 'Role in board fx.',
+ },
+ selectRole: {
+ id: 'fsc.application:selectRole',
+ defaultMessage: 'Veldu hlutverk',
+ description: 'role select',
+ },
+ cemeteryInspector: {
+ id: 'fsc.application:cemeteryInspector',
+ defaultMessage: 'Skoðunarmaður',
+ description: 'inspector',
+ },
+ cemeteryBoardMember: {
+ id: 'fsc.application:cemeteryBoardMember',
+ defaultMessage: 'Stjórnarmaður',
+ description: 'Boardmember',
+ },
+ errorCaretakerCanNotIncludeActor: {
+ id: 'fsc.application:error.errorcaretakerCanNotIncludeActor',
+ defaultMessage: 'Innskráður aðili má ekki vera skráður sem skoðunarmaður',
+ description: 'error, applicant regsitered as caretaker',
+ },
+ errorMemberCanNotIncludeApplicant: {
+ id: 'fsc.application:error.errormemberCanNotIncludeApplicant',
+ defaultMessage:
+ 'Umsækjandi má ekki vera skráður sem stjórnarmaður eða skoðunarmaður',
+ description: 'error, applicant regsitered as caretaker/boardmember',
+ },
+ errorBoardmembersCanNotJustIncludeActor: {
+ id: 'fsc.application:error.errorBoardmembersCanNotJustIncludeActor',
+ defaultMessage:
+ 'Innskráður aðili má ekki vera skráður einn sem stjórnarmaður',
+ description: 'error, applicant regsitered as caretaker',
+ },
+ add: {
+ id: 'fsc.application:add',
+ defaultMessage: 'Bæta við línu',
+ description: 'Cemetries board and caretakers',
+ },
+ payroll: {
+ id: 'fsc.application:income.payroll',
+ defaultMessage: 'Laun og launatengd gjöld',
+ description: 'Payroll expense',
+ },
+ chapelExpense: {
+ id: 'fsc.application:income.chapelExpense',
+ defaultMessage: 'Rekstur útfararkapellu',
+ description: 'chapel Operation expenses',
+ },
+ funeralCost: {
+ id: 'fsc.application:income.funeralCost',
+ defaultMessage: 'Útfarakostnaður',
+ description: 'funerals expenses',
+ },
+ donationsToOther: {
+ id: 'fsc.application:income.donationsToOther',
+ defaultMessage: 'Framlög og styrkir til annarra',
+ description: 'Donations made to others',
+ },
+ donationsToCemeteryFund: {
+ id: 'fsc.application:income.donationsToCemeteryFund',
+ defaultMessage: 'Framlög til kirkjugarðasjóðs',
+ description: 'donations from cemetry fund',
+ },
+ otherOperationCost: {
+ id: 'fsc.application:income.otherOperationCost',
+ defaultMessage: 'Annar rekstrarkostnaður',
+ description: 'other operations cost',
+ },
+ depreciation: {
+ id: 'fsc.application:income.depreciation',
+ defaultMessage: 'Afskriftir',
+ description: 'Depreciation',
+ },
+ careIncome: {
+ id: 'fsc.application:income.careIncome',
+ defaultMessage: 'Umhirðutekjur',
+ description: 'caretaking income',
+ },
+ burialRevenue: {
+ id: 'fsc.application:income.burialRevenue',
+ defaultMessage: 'Grafartekjur',
+ description: 'burial revenue',
+ },
+ grantFromTheCemeteryFund: {
+ id: 'fsc.application:income.grantFromTheCemeteryFund',
+ defaultMessage: 'Styrkur frá kirkjugarðasjóði',
+ description: 'Income from cemetry fund',
+ },
+ otherIncome: {
+ id: 'fsc.application:income.other',
+ defaultMessage: 'Aðrar tekjur',
+ description: 'Other income',
+ },
+ income: {
+ id: 'fsc.application:income',
+ defaultMessage: 'Tekjur',
+ description: 'Applicants income',
+ },
+ totalIncome: {
+ id: 'fsc.application:income.totalIncome',
+ defaultMessage: 'Tekjur samtals:',
+ description: 'Total income',
+ },
+ expenses: {
+ id: 'fsc.application:keyNumbers.expenses',
+ defaultMessage: 'Gjöld',
+ description: 'expenses',
+ },
+ totalExpenses: {
+ id: 'fsc.application:income.totalExpenses',
+ defaultMessage: 'Gjöld samtals:',
+ description: 'Total expenses',
+ },
+ operatingCost: {
+ id: 'fsc.application:keyNumbers.operatingCost',
+ defaultMessage: 'Rekstrarniðurstaða alls',
+ description: 'Operating Cost',
+ },
+ operatingCostBefore: {
+ id: 'fsc.application:keyNumbers.operatingCostBeforeCapital',
+ defaultMessage: 'Rekstrarniðurstaða fyrir fjármagnsliði',
+ description: 'Operating Cost Capital',
+ },
+ fetchErrorTitle: {
+ id: 'fsc.application:fetchErrorMsg',
+ defaultMessage: 'Eitthvað fór úrskeiðiðs',
+ description: 'Error msg title when fetching data fails',
+ },
+ fetchCemetryLimitErrorMsg: {
+ id: 'fsc.application:fetchCemetryLimitErrorMsg',
+ defaultMessage:
+ 'Ef skil falla undir lög um ársreikninga sem þarfnast ekki skila, reynið aftur síðar',
+ description: 'Error msg when fetching data fails',
+ },
+ capitalIncome: {
+ id: 'fsc.application:income.capital',
+ defaultMessage: 'Fjármagnstekjur',
+ description: 'capital income',
+ },
+ capitalCost: {
+ id: 'fsc.application:income.capitalCost',
+ defaultMessage: 'Fjármagnsgjöld',
+ description: 'capital costs',
+ },
+ totalCapital: {
+ id: 'fsc.application:totalCapital',
+ defaultMessage: 'Fjármagnsliðir samtals',
+ description: 'Total capital',
+ },
+ equityDebtsAssetsValidatorError: {
+ id: 'fsc.application:equityValidatorError',
+ defaultMessage: 'Skuldir og eigið fé þarf að vera jafnt og eignir samtals',
+ description: 'Equity + debts shout equal assets',
+ },
+ properties: {
+ id: 'fsc.application:properties',
+ defaultMessage: 'Eignir',
+ description: 'List of applicants properties',
+ },
+ fixedAssetsTotal: {
+ id: 'fsc.application:keyNumbers.fixedAssetsTotal',
+ defaultMessage: 'Fastafjármunir samtals',
+ description: 'Fixed assets',
+ },
+ currentAssets: {
+ id: 'fsc.application:keyNumbers.currentAssets',
+ defaultMessage: 'Veltufjármunir samtals',
+ description: 'Current assets',
+ },
+ totalAssets: {
+ id: 'fsc.application:totalAssets',
+ defaultMessage: 'Eignir samtals',
+ description: 'Total assets',
+ },
+ debtsAndEquity: {
+ id: 'fsc.application:keyNumbers.debtsAndEquity',
+ defaultMessage: 'Skuldir og eigið fé',
+ description: 'debts and equity',
+ },
+ longTerm: {
+ id: 'fsc.application:keyNumbers.longTermdebt',
+ defaultMessage: 'Langtímaskuldir samtals',
+ description: 'Long term debt',
+ },
+ shortTerm: {
+ id: 'fsc.application:keyNumbers.shortTermDebt',
+ defaultMessage: 'Skammtímaskuldir samtals',
+ description: 'Short term debt',
+ },
+ totalDebts: {
+ id: 'fsc.application:income.totalDebts',
+ defaultMessage: 'Skuldir samtals:',
+ description: 'Total debts',
+ },
+ equityAtTheBeginningOfTheYear: {
+ id: 'fsc.application:keyNumbers.equityAtTheBeginningOfTheYear',
+ defaultMessage: 'Eigið fé 1. Janúar',
+ description: 'equity january first',
+ },
+ revaluationDueToPriceChanges: {
+ id: 'fsc.application:keyNumbers.reevaluatePrice',
+ defaultMessage: 'Endurmat vegna verðbreytinga',
+ description: 'Revaluation because of price change',
+ },
+ reevaluateOther: {
+ id: 'fsc.application:keyNumbers.reevaluateOther',
+ defaultMessage: 'Endurmat, annað',
+ description: 'Revaluation other',
+ },
+ operationResult: {
+ id: 'fsc.application:keyNumbers.operationResult',
+ defaultMessage: 'Rekstrarafkoma',
+ description: 'Result of operation',
+ },
+ totalEquity: {
+ id: 'fsc.application:totalEquity',
+ defaultMessage: 'Samtals eigið fé',
+ description: 'Total equity',
+ },
+ debtsAndCash: {
+ id: 'fsc.application:keyNumbers.debtsAndCash',
+ defaultMessage: 'Skuldir og eigið fé samtals',
+ description: 'Debts and cash',
+ },
+ equityErrorTitle: {
+ id: 'fsc.application:equityErrorTitle',
+ defaultMessage: 'Ósamræmi í tölum',
+ description: 'Error msg title when E = S+E.fé is incorrect',
+ },
+ financialStatement: {
+ id: 'fsc.application:financial.statment',
+ defaultMessage: 'Ársreikningur',
+ description: 'financial statements',
+ },
+ upload: {
+ id: 'fsc.application:upload',
+ defaultMessage: 'Hlaða upp ársreikningi',
+ description: 'Upload financial statements',
+ },
+ uploadHeader: {
+ id: 'fsc.application:uploadHeader',
+ defaultMessage: 'Dragðu skjöl hingað til að hlaða upp',
+ description: 'Upload here',
+ },
+ uploadIntro: {
+ id: 'fsc.application:upload.intro',
+ defaultMessage: 'Vinsamlegast hlaðið upp ársreikning hér að neðan.',
+ description: 'Upload financial statements intro',
+ },
+ uploadDescription: {
+ id: 'fsc.application:upload.description',
+ defaultMessage: 'Vinsamlegast hlaðið upp ársreikning hér að neðan.',
+ description: 'Upload financial statements intro',
+ },
+ uploadAccept: {
+ id: 'fsc.application:upload.accept',
+ defaultMessage: 'Eingöngu er tekið við skjölum á PDF formi',
+ description: 'Upload financial statements intro',
+ },
+ uploadButtonLabel: {
+ id: 'fsc.application:upload.buttonlabel',
+ defaultMessage: 'Velja skjöl til að hlaða upp',
+ description: 'Upload button label',
+ },
+ serviceProvider: {
+ id: 'fsc.application:serviceProvider',
+ defaultMessage: 'Þjónustuaðili',
+ description: 'service provider',
+ },
+ inao: {
+ id: 'fsc.application:inao',
+ defaultMessage: 'Ríkisendurskoðun',
+ description: 'icelandic national audit',
+ },
+ dataCollectionTitle: {
+ id: 'fsc.application:applicationDataCollectionTitle',
+ defaultMessage: 'Gagnaöflun',
+ description: 'Title for data collection section',
+ },
+ dataCollectionTitleUserCemetry: {
+ id: 'fsc.application:applicationDataCollectionTitleUserCemetry',
+ defaultMessage: 'Gagnaöflun vegna skila ársreiknings kirkjugarðs',
+ description: 'Title for data collection section',
+ },
+ dataCollectionNationalRegistryTitle: {
+ id: 'fsc.application:dataCollectionNationalRegistryTitle',
+ defaultMessage: 'Persónuupplýsingar',
+ description: 'National registry title',
+ },
+ dataCollectionNationalRegistrySubtitle: {
+ id: 'fsc.application:dataCollectionNationalRegistrySubtitle',
+ defaultMessage: 'Fullt nafn, kennitala, heimilisfang.',
+ description: 'National registry subtitle',
+ },
+ dataCollectionUserProfileTitle: {
+ id: 'fsc.application:dataCollectionUserProfileTitle',
+ defaultMessage: 'Mínar síður á Ísland.is/stillingar',
+ description: 'Your user profile information',
+ },
+ dataCollectionUserFinancialInfoTitle: {
+ id: 'fsc.application:dataCollectionUserFinancialInfoTitle',
+ defaultMessage: 'Fjárhagsupplýsingar',
+ description: 'Financial info',
+ },
+ dataCollectionUserFinancialInfo: {
+ id: 'fsc.application:dataCollectionUserFinancialInfo',
+ defaultMessage:
+ 'Til þess að auðvelda fyrir sækjum við fjárhagsupplýsingar til Ríkisendurskoðunar, sem embættið aflar frá viðeigandi aðilum á grundvelli aðgangs- og skoðunarheimilda sem það hefur, og forskráum þær.',
+ description: 'Financial info',
+ },
+ dataCollectionUserProfileSubtitle: {
+ id: 'fsc.application:dataCollectionUserProfileSubtitle',
+ defaultMessage:
+ 'Ef þú ert með skráðar upplýsingar um síma og netfang inni á Mínar síður á Ísland.is þá verða þær sjálfkrafa settar inn í umsóknina.',
+ description:
+ 'In order to apply for this application we need your email and phone number',
+ },
+ dataCollectionCheckboxLabel: {
+ id: 'fsc.application:dataCollectionCheckboxLabel',
+ defaultMessage:
+ 'Ég skil að ofangreindra gagna verður aflað við vinnslu innsendingarinnar',
+ description: 'Checkbox label for data collection section',
+ },
+ received: {
+ id: 'fsc.application:received',
+ defaultMessage: 'Ársreikningur mótekinn',
+ description: 'financial statement received',
+ },
+ applicationAccept: {
+ id: 'fsc.application:applicationAccept',
+ defaultMessage: 'Umsókn móttekin',
+ description: 'application accept',
+ },
+ reviewContact: {
+ id: 'fsc.application:reviewContact',
+ defaultMessage: 'Vinsamlega yfirfarið upplýsingar um tengilið hér að neðan',
+ description: 'Review contact info',
+ },
+ reviewInfo: {
+ id: 'fsc.application:reviewInfo',
+ defaultMessage: 'Vinsamlega yfirfarið upplýsingarnar hér að neðan',
+ description: 'Review info',
+ },
+ info: {
+ id: 'fsc.application:info',
+ defaultMessage: 'Upplýsingar',
+ description: 'info',
+ },
+ clientNationalId: {
+ id: 'fsc.application:clientNationalId',
+ defaultMessage: 'Kennitala viðskiptavinar',
+ description: 'client national id',
+ },
+ clientName: {
+ id: 'fsc.application:clientName',
+ defaultMessage: 'Nafn viðskiptavinar',
+ description: 'client name',
+ },
+ email: {
+ id: 'fsc.application:person.email',
+ defaultMessage: 'Netfang',
+ description: 'email',
+ },
+ phoneNumber: {
+ id: 'fsc.application:about.phoneNumber',
+ defaultMessage: 'Símanúmer',
+ description: 'phone number',
+ },
+ fetchErrorMsg: {
+ id: 'fsc.application:fetchError',
+ defaultMessage: 'Ekki tókst að sækja gögn, reyndur aftur seinna',
+ description: 'Error msg when fetching data fails',
+ },
+ operatingYear: {
+ id: 'fsc.application:keyNumbers.operatingYear',
+ defaultMessage: 'Rekstrarár',
+ description: 'Operating year',
+ },
+ selectOperatingYear: {
+ id: 'fsc.application:keyNumbers.selectOperatingYear',
+ defaultMessage: 'Veldu rekstrarár',
+ description: 'Select operating year',
+ },
+ powerOfAttorneyNationalId: {
+ id: 'fsc.application:powerOfAttorneyNationalId',
+ defaultMessage: 'Kennitala umboðsmanns',
+ description: `national id for power of attorney`,
+ },
+ powerOfAttorneyName: {
+ id: 'fsc.application:powerOfAttorneyName',
+ defaultMessage: 'Nafn umboðsmanns',
+ description: `name for power of attorney`,
+ },
+ errorFetchingName: {
+ id: 'fsc.application:error.errorFetchingName',
+ defaultMessage: 'Tókst ekki að sækja nafn umboðsmanns',
+ description: 'Could not fetch powerofattorney name',
+ },
+ wrongDelegation: {
+ id: 'fsc.application:wrongDelegation',
+ defaultMessage: 'Eingöngu er hægt að skila fyrir hönd Kirkjugarða',
+ description: 'Logged in user with incorrect delegation type',
+ },
+ genericError: {
+ id: 'fsc.application:error.genericError',
+ defaultMessage: 'Eitthvað fór úrskeiðis',
+ description: 'Generic error message',
+ },
+ statement: {
+ id: 'fsc.application:statement',
+ defaultMessage: 'Yfirlýsing',
+ description: 'statement',
+ },
+ overviewSectionTitle: {
+ id: 'fsc.application:overview.general.sectionTitle',
+ defaultMessage: 'Yfirlit',
+ description: 'Overview section title',
+ },
+ overviewReview: {
+ id: 'fsc.application:overview.general.review',
+ defaultMessage: 'Yfitlit uppgjörs',
+ description: 'Overview review',
+ },
+ yearlyOverview: {
+ id: 'fsc.application:overview.general.yearly',
+ defaultMessage: 'Yfirlit ársreiknings',
+ description: 'Yearly overview',
+ },
+ overviewDescription: {
+ id: 'fsc.application:overview.general.description',
+ defaultMessage: 'Farðu vel yfir efnið áður en þú sendir inn umsóknina.',
+ description: 'Overview description',
+ },
+ review: {
+ id: 'fsc.application:review',
+ defaultMessage:
+ 'Endilega lestu yfir til að vera viss um að allar upplýsingar hafi verið gefnar',
+ description: 'financial statements',
+ },
+ files: {
+ id: 'fsc.application:files',
+ defaultMessage: 'Skjöl',
+ description: 'files',
+ },
+ overview: {
+ id: 'fsc.application:overview.general.overview',
+ defaultMessage: 'Yfirferð',
+ description: 'Overview section title',
+ },
+ overviewCorrect: {
+ id: 'fsc.application:overview.overViewCorrect',
+ defaultMessage: 'Ég samþykki að ofangreindar upplýsingar séu réttar',
+ description: 'Overview correct',
+ },
+ errorApproval: {
+ id: 'fsc.application:error.errorApproval',
+ defaultMessage: 'Samþykkja þarf yfirlit',
+ description: 'Approval missing',
+ },
+ submitErrorTitle: {
+ id: 'fsc.application:submitErrorTitle',
+ defaultMessage: 'Móttaka ársreiknings tókst ekki',
+ description:
+ 'Title that shows up when an error occurs while submitting the application',
+ },
+ submitErrorMessage: {
+ id: 'fsc.application:submitErrorMessage',
+ defaultMessage:
+ 'Eitthvað fór úrskeiðis við að senda inn ársreikning. Reyndu aftur síðar.',
+ description:
+ 'Text that shows up when an error occurs while submitting the application',
+ },
+ goBack: {
+ id: 'fsc.application:overview.goBack',
+ defaultMessage: 'Til Baka',
+ description: 'Go back btn text',
+ },
+ send: {
+ id: 'fsc.application:send',
+ defaultMessage: 'Senda umsókn',
+ description: 'Send application',
+ },
+ nationalIdError: {
+ id: 'fsc.application:error.nationalIdError',
+ defaultMessage: 'Kennitala er ekki á réttu formi',
+ description: 'Error message when nationalid is wrong',
+ },
+ dataSchemePhoneNumber: {
+ id: 'fsc.application:dataSchema.phoneNumber',
+ defaultMessage: 'Símanúmerið þarf að vera gilt.',
+ description: 'Error message when phone number is invalid.',
+ },
+ totalLiabilities: {
+ id: 'fsc.application:keyNumbers.totalLiabilities',
+ defaultMessage: 'Skuldir samtals',
+ description: 'total liabilities',
+ },
+ equity: {
+ id: 'fsc.application:keyNumbers.equity',
+ defaultMessage: 'Eigið fé',
+ description: 'total equity',
+ },
+ nationalIdAgeError: {
+ id: 'fsc.application:error.nationalIdAgeError',
+ defaultMessage: 'Skoðunar- og Stjórnunarmenn þurfa að vera eldri en 18 ára',
+ description:
+ 'Error message when attempting to register younger then 18 caretaker',
+ },
+ errorMembersMissing: {
+ id: 'fsc.application:error.errorMembersMissing',
+ defaultMessage: 'Skrá þarf bæði skoðunarmann og stjórnarmann',
+ description: 'Members missing',
+ },
+ errormemberNotUnique: {
+ id: 'fsc.application:error.errormemberNotUnique',
+ defaultMessage:
+ 'Ekki er hægt að skrá sama aðila sem Stjórnarmann og Skoðunarmann',
+ description: 'Members missing',
+ },
+ debts: {
+ id: 'fsc.application:keyNumbers.debts',
+ defaultMessage: 'Skuldir',
+ description: 'debts',
+ },
+ SignatureMessage: {
+ id: 'fsc.application:SignatureMessage',
+ defaultMessage:
+ 'Eftir að þú hefur sent inn umsókn mun rafræn undirritun verða send á netfangið',
+ description: 'Signature message',
+ },
+ SignaturePossible: {
+ id: 'fsc.application:SignaturePossible',
+ defaultMessage: 'svo hægt sé að undirrita hana með rafrænum skilríkjum.',
+ description: 'Signature possible message',
+ },
+ operatingYearMsgFirst: {
+ id: 'fsc.application:operatingYearMsgFirst',
+ defaultMessage: 'Ársreikningi fyrir rekstrarárið',
+ description: 'First part of audit received message',
+ },
+ individualReceivedMsgSecond: {
+ id: 'fsc.application:individualReceivedMsgSecond',
+ defaultMessage: 'hefur verið skilað þann',
+ description: 'Second part of audit received message',
+ },
+ returned: {
+ id: 'fsc.application:returned',
+ defaultMessage: 'Skilað',
+ description: 'Returned',
+ },
+ digitalSignatureTitle: {
+ id: 'fsc.application:digitalSignatureTitle',
+ defaultMessage: 'Rafræn undirritun',
+ description:
+ 'Reminder of digital signature after the application is returned',
+ },
+ digitalSignatureMessage: {
+ id: 'fsc.application:digitalSignatureMessage',
+ defaultMessage:
+ 'Það bíður þín skjal sem á eftir að undirrita með rafrænum skilríkjum. Hlekkur á skjalið hefur verið sendur í tölvupósti á netfangið þitt: {email}',
+ description:
+ 'Reminder of digital signature after the application is returned',
+ },
+ myPagesLinkText: {
+ id: 'fsc.application:myPagesLinkText',
+ defaultMessage:
+ 'Á Mínum síðum Ísland.is hefur þú aðgang að marvíslegum upplýsingum s.s stafrænt pósthólf, þínar upplýsingar, fjármál, umsóknir, menntun, fasteignir, ökutæki, skírteini, starfsleyfi ofl. ',
+ description: 'island.is my pages info',
+ },
+ continue: {
+ id: 'fsc.application:continue',
+ defaultMessage: 'Áfram',
+ description: 'continue',
+ },
+})
diff --git a/libs/application/templates/financial-statement-cemetery/src/types/types.ts b/libs/application/templates/financial-statement-cemetery/src/types/types.ts
new file mode 100644
index 000000000000..5d9619eecf6c
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/types/types.ts
@@ -0,0 +1,37 @@
+import { DefaultEvents } from '@island.is/application/types'
+
+export type Options = {
+ label: string
+ value: string
+}[]
+
+export type Config = { key: string; value: string }
+
+export enum FSIUSERTYPE {
+ INDIVIDUAL = 150000000,
+ PARTY = 150000001,
+ CEMETRY = 150000002,
+}
+
+export type BoardMember = {
+ nationalId: string
+ name: string
+ role: string
+}
+
+export enum ApiActions {
+ getUserType = 'getUserType',
+ submitApplication = 'submitApplication',
+}
+
+export type Events = { type: DefaultEvents.SUBMIT }
+
+export enum States {
+ PREREQUISITES = 'prerequisites',
+ DRAFT = 'draft',
+ DONE = 'done',
+}
+
+export enum Roles {
+ APPLICANT = 'applicant',
+}
diff --git a/libs/application/templates/financial-statement-cemetery/src/utils/constants.ts b/libs/application/templates/financial-statement-cemetery/src/utils/constants.ts
new file mode 100644
index 000000000000..87efecc3fb85
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/utils/constants.ts
@@ -0,0 +1,86 @@
+export const CEMETERYCARETAKER = {
+ nationalId: 'cemeteryCaretaker.nationalId',
+ name: 'cemeteryCaretaker.name',
+ role: 'cemeteryCaretaker.role',
+}
+
+export const CARETAKER = 'Skoðunarmaður'
+export const BOARDMEMEBER = 'Stjórnarmaður'
+export const INPUTCHANGEINTERVAL = 300
+export const TOTAL = 'total'
+export const GREATER = 'greater'
+export const LESS = 'less'
+export const PartiesBackwardLimit = 'PartiesBackwardLimit'
+export const CemeteriesBackwardLimit = 'CemeteriesBackwardLimit'
+export const PartiesYearAllowed = 'PartiesYearAllowed'
+export const CemeteriesYearAllowed = 'CemeteriesYearAllowed'
+
+// error helpers
+export const VALIDATOR = 'validator'
+export const APPLICANTASMEMBER = 'applicantasmember'
+export const ACTORASCARETAKER = 'actorascaretaker'
+export const ACTORLONEBOARDMEMBER = 'actorloneboardmember'
+
+export enum TaxInfoTypes {
+ CARE_INCOME = 300,
+ BURIAL_REVENUE = 301,
+ GRANT_FROM_THE_CEMETERY_FUND = 302,
+}
+
+export const CEMETERYOPERATIONIDS = {
+ prefixIncome: 'cemeteryIncome',
+ prefixExpense: 'cemeteryExpense',
+ incomeLimit: 'cemeteryOperation.incomeLimit',
+ applicationType: 'cemeteryIncome.applicationType',
+ careIncome: 'cemeteryIncome.careIncome',
+ burialRevenue: 'cemeteryIncome.burialRevenue',
+ grantFromTheCemeteryFund: 'cemeteryIncome.grantFromTheCemeteryFund',
+ capitalIncome: 'cemeteryIncome.capitalIncome',
+ otherIncome: 'cemeteryIncome.otherIncome',
+ totalIncome: 'cemeteryIncome.total',
+ totalOperation: 'cemeteryRunningCost.totalOperation',
+ totalExpense: 'cemeteryExpense.total',
+ payroll: 'cemeteryExpense.payroll',
+ funeralCost: 'cemeteryExpense.funeralCost',
+ chapelExpense: 'cemeteryExpense.chapelExpense',
+ donationsToCemeteryFund: 'cemeteryExpense.cemeteryFundExpense',
+ donationsToOther: 'cemeteryExpense.donationsToOther',
+ otherOperationCost: 'cemeteryExpense.otherOperationCost',
+ depreciation: 'cemeteryExpense.depreciation',
+}
+
+export const CAPITALNUMBERS = {
+ capitalPrefix: 'capitalNumbers',
+ capitalIncome: 'capitalNumbers.capitalIncome',
+ capitalCost: 'capitalNumbers.capitalCost',
+ total: 'capitalNumbers.total',
+}
+
+export const CEMETERYEQUITIESANDLIABILITIESIDS = {
+ assetPrefix: 'cemeteryAsset',
+ liabilityPrefix: 'cemeteryLiability',
+ equityPrefix: 'cemeteryEquity',
+ currentAssets: 'cemeteryAsset.currentAssets',
+ fixedAssetsTotal: 'cemeteryAsset.fixedAssetsTotal',
+ assetTotal: 'cemeteryAsset.total',
+ longTerm: 'cemeteryLiability.longTerm',
+ shortTerm: 'cemeteryLiability.shortTerm',
+ liabilityTotal: 'cemeteryLiability.total',
+ equityAtTheBeginningOfTheYear: 'cemeteryEquity.equityAtTheBeginningOfTheYear',
+ revaluationDueToPriceChanges: 'cemeteryEquity.revaluationDueToPriceChanges',
+ reevaluateOther: 'cemeteryEquity.reevaluateOther',
+ operationResult: 'cemeteryEquity.operationResult',
+ equityTotal: 'cemeteryEquity.total',
+ totalEquityAndLiabilities: 'equityAndLiabilities.total',
+}
+
+export const OPERATINGCOST = {
+ total: 'operatingCost.total',
+}
+
+export const ABOUTIDS = {
+ operatingYear: 'conditionalAbout.operatingYear',
+ applicationType: 'conditionalAbout.applicationType',
+ powerOfAttorneyNationalId: 'about.powerOfAttorneyNationalId',
+ powerOfAttorneyName: 'about.powerOfAttorneyName',
+}
diff --git a/libs/application/templates/financial-statement-cemetery/src/utils/helpers.ts b/libs/application/templates/financial-statement-cemetery/src/utils/helpers.ts
new file mode 100644
index 000000000000..c7b382ede33f
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/src/utils/helpers.ts
@@ -0,0 +1,105 @@
+import { ExternalData, FormValue } from '@island.is/application/types'
+import { getValueViaPath } from '@island.is/application/core'
+import { BOARDMEMEBER, CARETAKER, TOTAL } from './constants'
+import { FinancialStatementCemetery } from '../lib/dataSchema'
+import getYear from 'date-fns/getYear'
+import subYears from 'date-fns/subYears'
+import { BoardMember, Config, FSIUSERTYPE } from '../types/types'
+
+export const getTotal = (values: Record, key: string) => {
+ if (!values[key]) {
+ return 0
+ }
+ const total = Object.entries(values[key])
+ .filter(([k, v]) => k !== TOTAL && !isNaN(Number(v)))
+ .map(([_k, v]) => Number(v))
+ .reduce((prev, current) => {
+ return (prev += current)
+ }, 0)
+ return total
+}
+
+export const currencyStringToNumber = (str: string) => {
+ if (!str) {
+ return str
+ }
+ const cleanString = str.replace(/[,\s]+|[.\s]+/g, '')
+ return parseInt(cleanString, 10)
+}
+
+export const getCurrentUserType = (
+ answers: FormValue,
+ externalData: ExternalData,
+) => {
+ const fakeUserType: FSIUSERTYPE | undefined = getValueViaPath(
+ answers,
+ 'fakeData.options',
+ )
+
+ const currentUserType: FSIUSERTYPE | undefined = getValueViaPath(
+ externalData,
+ 'getUserType.data.value',
+ )
+
+ return fakeUserType ? fakeUserType : currentUserType
+}
+
+export const getBoardmembersAndCaretakers = (members: Array) => {
+ const careTakers = members
+ ?.filter((member) => member.role === CARETAKER)
+ .map((member) => member.nationalId)
+ const boardMembers = members
+ ?.filter((member) => member.role === BOARDMEMEBER)
+ ?.map((member) => member.nationalId)
+
+ return { careTakers, boardMembers }
+}
+
+export const isCemetryUnderFinancialLimit = (
+ answers: FormValue,
+ externalData: ExternalData,
+) => {
+ const userType = getCurrentUserType(answers, externalData)
+ const applicationAnswers = answers as FinancialStatementCemetery
+ const careTakerLimit =
+ applicationAnswers.cemeteryOperation?.incomeLimit ?? '0'
+ const fixedAssetsTotal = applicationAnswers.cemeteryAsset?.fixedAssetsTotal
+ const isCemetry = userType === FSIUSERTYPE.CEMETRY
+ const totalIncome = isCemetry ? applicationAnswers.cemeteryIncome?.total : '0'
+ const longTermDebt = applicationAnswers.cemeteryLiability?.longTerm
+ const isUnderLimit = currencyStringToNumber(totalIncome) < careTakerLimit
+ if (
+ isCemetry &&
+ isUnderLimit &&
+ fixedAssetsTotal === '0' &&
+ longTermDebt === '0'
+ ) {
+ return true
+ }
+ return false
+}
+
+export const possibleOperatingYears = (
+ yearLimit: string,
+ countYearBackwardsFrom: string,
+) => {
+ const countFromYear = new Date(countYearBackwardsFrom)
+ const backwardsYearLimit = Number(yearLimit)
+ const operationYears = Array(backwardsYearLimit)
+ .fill('')
+ .map((_, index) => {
+ const dateDiff = subYears(countFromYear, index)
+ const yearsFromNow = getYear(dateDiff).toString()
+ return { label: yearsFromNow, value: yearsFromNow }
+ })
+ return operationYears
+}
+
+export const getConfigInfoForKey = (config: Config[], configKey: string) => {
+ return config?.filter((config: Config) => config.key === configKey)[0].value
+}
+
+export const formatCurrency = (answer?: string) => {
+ if (!answer) return '0. kr'
+ return answer.replace(/\B(?=(\d{3})+(?!\d))/g, '.') + ' kr.'
+}
diff --git a/libs/application/templates/financial-statement-cemetery/tsconfig.json b/libs/application/templates/financial-statement-cemetery/tsconfig.json
new file mode 100644
index 000000000000..52f7c83105fc
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "extends": "../../../../tsconfig.base.json",
+ "compilerOptions": {
+ "jsx": "react-jsx",
+ "allowJs": false
+ },
+ "files": [],
+ "include": [],
+ "references": [
+ {
+ "path": "./tsconfig.lib.json"
+ },
+ {
+ "path": "./tsconfig.spec.json"
+ }
+ ]
+}
diff --git a/libs/application/templates/financial-statement-cemetery/tsconfig.lib.json b/libs/application/templates/financial-statement-cemetery/tsconfig.lib.json
new file mode 100644
index 000000000000..1547ea009d18
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/tsconfig.lib.json
@@ -0,0 +1,23 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "outDir": "../../../../dist/out-tsc",
+ "types": ["node"]
+ },
+ "files": [
+ "../../../../node_modules/@nx/react/typings/cssmodule.d.ts",
+ "../../../../node_modules/@nx/react/typings/image.d.ts"
+ ],
+ "exclude": [
+ "jest.config.ts",
+ "src/**/*.spec.ts",
+ "src/**/*.test.ts",
+ "src/**/*.spec.tsx",
+ "src/**/*.test.tsx",
+ "src/**/*.spec.js",
+ "src/**/*.test.js",
+ "src/**/*.spec.jsx",
+ "src/**/*.test.jsx"
+ ],
+ "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]
+}
diff --git a/libs/application/templates/financial-statement-cemetery/tsconfig.spec.json b/libs/application/templates/financial-statement-cemetery/tsconfig.spec.json
new file mode 100644
index 000000000000..1033686367b0
--- /dev/null
+++ b/libs/application/templates/financial-statement-cemetery/tsconfig.spec.json
@@ -0,0 +1,20 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "outDir": "../../../../dist/out-tsc",
+ "module": "commonjs",
+ "types": ["jest", "node"]
+ },
+ "include": [
+ "jest.config.ts",
+ "src/**/*.test.ts",
+ "src/**/*.spec.ts",
+ "src/**/*.test.tsx",
+ "src/**/*.spec.tsx",
+ "src/**/*.test.js",
+ "src/**/*.spec.js",
+ "src/**/*.test.jsx",
+ "src/**/*.spec.jsx",
+ "src/**/*.d.ts"
+ ]
+}
diff --git a/libs/application/templates/healthcare-work-permit/src/fields/CustomFormConclusionSectionField/index.tsx b/libs/application/templates/healthcare-work-permit/src/fields/CustomFormConclusionSectionField/index.tsx
index ed8863c14900..657d43a0143a 100644
--- a/libs/application/templates/healthcare-work-permit/src/fields/CustomFormConclusionSectionField/index.tsx
+++ b/libs/application/templates/healthcare-work-permit/src/fields/CustomFormConclusionSectionField/index.tsx
@@ -17,6 +17,7 @@ import { confirmation } from '../../lib/messages'
import { conclusionMessages } from '@island.is/application/ui-forms'
import { PermitProgram } from '../../lib'
import { HealthcareWorkPermitAnswers } from '../..'
+import format from 'date-fns/format'
interface PdfFile {
base64: string
@@ -111,6 +112,7 @@ export const CustomFormConclusionSectionField = (props: FieldBaseProps) => {
const data = application.externalData.submitApplication.data as {
base64String: string
}[]
+ const formattedDate = format(new Date(), 'yyyy-MM-dd')
// This should only ever be at most 2 files, in order license -> license number (when license number is applicable)
return data.map((x, index) => ({
base64: x.base64String,
@@ -121,7 +123,10 @@ export const CustomFormConclusionSectionField = (props: FieldBaseProps) => {
: `Leyfisnúmer`,
en: index === 0 ? `License to practice` : `License number`,
},
- filename: index === 0 ? `starfsleyfi_.pdf` : `leyfisnumer_.pdf`,
+ filename:
+ index === 0
+ ? `starfsleyfi_${formattedDate}.pdf`
+ : `leyfisnumer_${formattedDate}.pdf`,
}))
},
setViewPdfFile: (file: PdfFile) => {
diff --git a/libs/application/templates/healthcare-work-permit/src/lib/messages/error.ts b/libs/application/templates/healthcare-work-permit/src/lib/messages/error.ts
index a901adaef7d0..4fc8cec85887 100644
--- a/libs/application/templates/healthcare-work-permit/src/lib/messages/error.ts
+++ b/libs/application/templates/healthcare-work-permit/src/lib/messages/error.ts
@@ -13,9 +13,9 @@ export const error = defineMessages({
description: 'Empty career response',
},
emptyCareerResponseMessage: {
- id: 'hwp.application:error.emptyCareerResponseMessage',
+ id: 'hwp.application:error.emptyCareerResponseMessage#markdown',
defaultMessage:
- 'Samkvæmt þjónustu Háskóla Íslands ertu ekki með brautskráningu á skrá',
+ '* Ekki eru upplýsingar um brautskráningu frá HÍ eða HA úr löggildri heilbrigðsstétt \n* Brautskráning úr HÍ eða HA fyrir 1. janúar 2024 \n* Starfsleyfi nú þegar til staðar \n\n### Vinsamlega skoðið https://island.is/starfsleyfi-heilbrigdisstarfsmanna',
description: 'Empty career response',
},
noResponseEducationInfoTitle: {
@@ -76,7 +76,7 @@ export const error = defineMessages({
description: 'No graduated programs found that are valid form work permit',
},
noPermitValidGraduationFoundMessage: {
- id: 'hwp.application:error.noPermitValidGraduationFoundMessage',
+ id: 'hwp.application:error.noPermitValidGraduationFoundMessage#markdown',
defaultMessage: 'Ekki fundust brautskráningar sem gefa starfsleyfi',
description: 'No graduated programs found that are valid form work permit',
},
@@ -87,7 +87,7 @@ export const error = defineMessages({
description: 'No graduated programs found that can go through self service',
},
noPermitValidForSelfServiceMessage: {
- id: 'hwp.application:error.noPermitValidForSelfServiceMessage',
+ id: 'hwp.application:error.noPermitValidForSelfServiceMessage#markdown',
defaultMessage:
'Ekki fundust brautskráningar sem geta farið í gegnum sjálfsafgreiðslu, vinsamlega hafðu samband við Embætti Landlæknis',
description: 'No graduated programs found that can go through self service',
diff --git a/libs/application/templates/login-service/src/fields/FieldTitle/FieldTitle.tsx b/libs/application/templates/login-service/src/fields/FieldTitle/FieldTitle.tsx
deleted file mode 100644
index 9b61260133b3..000000000000
--- a/libs/application/templates/login-service/src/fields/FieldTitle/FieldTitle.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import React from 'react'
-import { formatText } from '@island.is/application/core'
-import { FieldBaseProps } from '@island.is/application/types'
-import { ResponsiveSpace, Text } from '@island.is/island-ui/core'
-import { useLocale } from '@island.is/localization'
-
-type Props = FieldBaseProps & {
- field: {
- props: {
- marginTop?: ResponsiveSpace
- }
- }
-}
-
-export const FieldTitle = ({ field, application }: Props) => {
- const { formatMessage } = useLocale()
- return (
- <>
-
- {formatText(field.title, application, formatMessage)}
-
- {field.description && (
- {formatText(field.description, application, formatMessage)}
- )}
- >
- )
-}
diff --git a/libs/application/templates/login-service/src/fields/Illustrations/CompanyIllustration.tsx b/libs/application/templates/login-service/src/fields/Illustrations/CompanyIllustration.tsx
deleted file mode 100644
index 957cce4aced4..000000000000
--- a/libs/application/templates/login-service/src/fields/Illustrations/CompanyIllustration.tsx
+++ /dev/null
@@ -1,3733 +0,0 @@
-import React, { FC } from 'react'
-
-// TODO: Use illustration for library when available
-export const CompanyIllustration: FC> = () => {
- return (
-
- )
-}
diff --git a/libs/application/templates/login-service/src/fields/Overview/Overview.tsx b/libs/application/templates/login-service/src/fields/Overview/Overview.tsx
index 814d2b7e2ab3..be46f4e1418f 100644
--- a/libs/application/templates/login-service/src/fields/Overview/Overview.tsx
+++ b/libs/application/templates/login-service/src/fields/Overview/Overview.tsx
@@ -3,7 +3,6 @@ import { formatText } from '@island.is/application/core'
import { FieldBaseProps } from '@island.is/application/types'
import { Box, Divider, Text } from '@island.is/island-ui/core'
import { useLocale } from '@island.is/localization'
-import React from 'react'
import { LoginService } from '../../lib/dataSchema'
import { applicant, technicalAnnouncements, terms } from '../../lib/messages'
diff --git a/libs/application/templates/login-service/src/fields/TermsOfAgreement/TermsOfAgreement.tsx b/libs/application/templates/login-service/src/fields/TermsOfAgreement/TermsOfAgreement.tsx
deleted file mode 100644
index 3589268ec3ff..000000000000
--- a/libs/application/templates/login-service/src/fields/TermsOfAgreement/TermsOfAgreement.tsx
+++ /dev/null
@@ -1,32 +0,0 @@
-import React, { FC } from 'react'
-import { formatText } from '@island.is/application/core'
-import { FieldBaseProps } from '@island.is/application/types'
-import { Box, Button, Link } from '@island.is/island-ui/core'
-import { useLocale } from '@island.is/localization'
-import { terms } from '../../lib/messages'
-
-export const TermsOfAgreement: FC> = ({
- application,
-}) => {
- const { formatMessage } = useLocale()
-
- return (
-
-
-
-
-
- )
-}
diff --git a/libs/application/templates/login-service/src/fields/index.ts b/libs/application/templates/login-service/src/fields/index.ts
index bab37f44f957..6dc522854c80 100644
--- a/libs/application/templates/login-service/src/fields/index.ts
+++ b/libs/application/templates/login-service/src/fields/index.ts
@@ -1,3 +1 @@
-export * from './TermsOfAgreement/TermsOfAgreement'
-export * from './FieldTitle/FieldTitle'
export * from './Overview/Overview'
diff --git a/libs/application/templates/login-service/src/forms/LoginServiceForm.ts b/libs/application/templates/login-service/src/forms/LoginServiceForm.ts
index b781c3f53fd1..2da39dd3f46c 100644
--- a/libs/application/templates/login-service/src/forms/LoginServiceForm.ts
+++ b/libs/application/templates/login-service/src/forms/LoginServiceForm.ts
@@ -8,6 +8,8 @@ import {
buildCheckboxField,
buildCompanySearchField,
getValueViaPath,
+ buildDescriptionField,
+ buildLinkField,
} from '@island.is/application/core'
import {
Form,
@@ -42,11 +44,11 @@ export const LoginServiceForm: Form = buildForm({
title: terms.general.pageTitle,
description: terms.general.pageDescription,
children: [
- buildCustomField({
- id: 'termsAgreement',
- title: terms.general.pageTitle,
- doesNotRequireAnswer: true,
- component: 'TermsOfAgreement',
+ buildLinkField({
+ id: 'termsOfAgreementLink',
+ title: terms.labels.termsAgreementLinkTitle,
+ link: terms.values.termsAgreementUrl,
+ iconProps: { icon: 'open' },
}),
buildCheckboxField({
id: 'termsOfAgreement',
@@ -72,11 +74,10 @@ export const LoginServiceForm: Form = buildForm({
title: selectCompany.general.pageTitle,
description: selectCompany.general.pageDescription,
children: [
- buildCustomField({
+ buildDescriptionField({
id: 'selectCompany.nameFieldTitle',
title: selectCompany.labels.nameDescription,
- doesNotRequireAnswer: true,
- component: 'FieldTitle',
+ titleVariant: 'h5',
}),
buildCompanySearchField({
id: 'selectCompany.searchField',
@@ -96,11 +97,10 @@ export const LoginServiceForm: Form = buildForm({
title: applicant.general.pageTitle,
description: applicant.general.pageDescription,
children: [
- buildCustomField({
+ buildDescriptionField({
id: 'applicant.nameFieldTitle',
title: applicant.labels.nameDescription,
- doesNotRequireAnswer: true,
- component: 'FieldTitle',
+ titleVariant: 'h5',
}),
buildTextField({
id: 'applicant.name',
@@ -147,18 +147,13 @@ export const LoginServiceForm: Form = buildForm({
)
},
}),
- buildCustomField(
- {
- id: 'applicant.responsibleParty',
- title: applicant.labels.responsiblePartyTitle,
- description: applicant.labels.responsiblePartyDescription,
- doesNotRequireAnswer: true,
- component: 'FieldTitle',
- },
- {
- marginTop: [3, 5],
- },
- ),
+ buildDescriptionField({
+ id: 'applicant.responsibleParty',
+ title: applicant.labels.responsiblePartyTitle,
+ titleVariant: 'h5',
+ description: applicant.labels.responsiblePartyDescription,
+ marginTop: [3, 5],
+ }),
buildTextField({
id: 'applicant.responsiblePartyName',
title: applicant.labels.responsiblePartyName,
diff --git a/libs/application/templates/official-journal-of-iceland/src/fields/Preview.tsx b/libs/application/templates/official-journal-of-iceland/src/fields/Preview.tsx
index 9afb2f4d42c7..c018afad1301 100644
--- a/libs/application/templates/official-journal-of-iceland/src/fields/Preview.tsx
+++ b/libs/application/templates/official-journal-of-iceland/src/fields/Preview.tsx
@@ -13,11 +13,11 @@ import {
} from '../lib/types'
import { useLocale } from '@island.is/localization'
import { useQuery } from '@apollo/client'
-import { TYPE_QUERY } from '../graphql/queries'
+import { PDF_QUERY, PDF_URL_QUERY, TYPE_QUERY } from '../graphql/queries'
export const Preview = (props: OJOIFieldBaseProps) => {
const { formatMessage: f } = useLocale()
- const { answers } = props.application
+ const { answers, id } = props.application
const { advert, signature } = answers
const { data, loading } = useQuery(TYPE_QUERY, {
@@ -30,31 +30,68 @@ export const Preview = (props: OJOIFieldBaseProps) => {
const type = data?.officialJournalOfIcelandType?.type?.title
+ const { data: pdfUrlData } = useQuery(PDF_URL_QUERY, {
+ variables: {
+ id: id,
+ },
+ })
+
+ const { data: pdfData } = useQuery(PDF_QUERY, {
+ variables: {
+ id: id,
+ },
+ })
+
if (loading) {
return (
)
}
+ const onCopyPreviewLink = () => {
+ if (!pdfData) {
+ return
+ }
+
+ const url = pdfData.officialJournalOfIcelandApplicationGetPdfUrl.url
+
+ navigator.clipboard.writeText(url)
+ }
+
+ const onOpenPdfPreview = () => {
+ if (!pdfData) {
+ return
+ }
+
+ window.open(
+ `data:application/pdf,${pdfData.officialJournalOfIcelandApplicationGetPdf.pdf}`,
+ '_blank',
+ )
+ }
+
return (
<>
-
-
+ {!!pdfUrlData && (
+
+ )}
+ {!!pdfData && (
+
+ )}
export enum TemplateApiActions {
- departments = 'departments',
- types = 'types',
+ departments = 'getDepartments',
+ types = 'getAdvertTypes',
postApplication = 'postApplication',
}
diff --git a/libs/application/templates/parental-leave/README.md b/libs/application/templates/parental-leave/README.md
index 965f6aeb6d6d..a4c4247e45f0 100644
--- a/libs/application/templates/parental-leave/README.md
+++ b/libs/application/templates/parental-leave/README.md
@@ -160,7 +160,7 @@ Once you have everything running you can navigate to [http://localhost:4200/umso
By setting up the application-system you'll have created a local postgres database on a docker image, if you haven't already you should setup a tool to interact with your database. For example [pgAdmin](https://www.pgadmin.org/download/).
-You’ll find the relevant connection information in [the docker-compose file](../../../../apps/application-system/api/docker-compose.base.yml).
+You’ll find the relevant connection information in [the docker compose file](../../../../apps/application-system/api/docker-compose.base.yml).
## Investigating errors
diff --git a/libs/application/templates/parental-leave/src/forms/EmployerApproval.ts b/libs/application/templates/parental-leave/src/forms/EmployerApproval.ts
index 4fcc3268f412..69124e4e35be 100644
--- a/libs/application/templates/parental-leave/src/forms/EmployerApproval.ts
+++ b/libs/application/templates/parental-leave/src/forms/EmployerApproval.ts
@@ -112,13 +112,13 @@ export const EmployerApproval: Form = buildForm({
}),
],
}),
+ buildDescriptionField({
+ id: 'final.approve',
+ title: coreMessages.thanks,
+ description: coreMessages.thanksDescription,
+ }),
],
}),
- buildDescriptionField({
- id: 'final.approve',
- title: coreMessages.thanks,
- description: coreMessages.thanksDescription,
- }),
],
}),
],
diff --git a/libs/application/templates/parental-leave/src/forms/EmployerApproveEdits.ts b/libs/application/templates/parental-leave/src/forms/EmployerApproveEdits.ts
index db995eb2fea3..4b1e62a33cdb 100644
--- a/libs/application/templates/parental-leave/src/forms/EmployerApproveEdits.ts
+++ b/libs/application/templates/parental-leave/src/forms/EmployerApproveEdits.ts
@@ -127,13 +127,13 @@ export const EmployerApproveEdits: Form = buildForm({
}),
],
}),
+ buildDescriptionField({
+ id: 'final.approve',
+ title: coreMessages.thanks,
+ description: coreMessages.thanksDescription,
+ }),
],
}),
- buildDescriptionField({
- id: 'final.approve',
- title: coreMessages.thanks,
- description: coreMessages.thanksDescription,
- }),
],
}),
],
diff --git a/libs/application/templates/parental-leave/src/forms/ParentalLeaveForm.ts b/libs/application/templates/parental-leave/src/forms/ParentalLeaveForm.ts
index 44eb08a2b991..53f37caefbfc 100644
--- a/libs/application/templates/parental-leave/src/forms/ParentalLeaveForm.ts
+++ b/libs/application/templates/parental-leave/src/forms/ParentalLeaveForm.ts
@@ -99,11 +99,6 @@ export const ParentalLeaveForm: Form = buildForm({
logo: Logo,
mode: FormModes.DRAFT,
children: [
- buildSection({
- id: 'prerequisites',
- title: parentalLeaveFormMessages.shared.prerequisitesSection,
- children: [],
- }),
buildSection({
id: 'theApplicant',
title: parentalLeaveFormMessages.shared.applicantSection,
diff --git a/libs/application/templates/parental-leave/src/forms/Prerequisites.ts b/libs/application/templates/parental-leave/src/forms/Prerequisites.ts
index f892eec3f141..16e330627bb4 100644
--- a/libs/application/templates/parental-leave/src/forms/Prerequisites.ts
+++ b/libs/application/templates/parental-leave/src/forms/Prerequisites.ts
@@ -664,35 +664,5 @@ export const PrerequisitesForm: Form = buildForm({
}),
],
}),
- buildSection({
- id: 'theApplicant',
- title: parentalLeaveFormMessages.shared.applicantSection,
- children: [],
- }),
- buildSection({
- id: 'rights',
- title: parentalLeaveFormMessages.shared.rightsSection,
- children: [],
- }),
- buildSection({
- id: 'leavePeriods',
- title: parentalLeaveFormMessages.shared.periodsSection,
- children: [],
- }),
- buildSection({
- id: 'additionalInformation',
- title: parentalLeaveFormMessages.shared.additionalInformationSection,
- children: [],
- }),
- buildSection({
- id: 'confirmation',
- title: parentalLeaveFormMessages.confirmation.title,
- children: [],
- }),
- buildSection({
- id: 'conclusion',
- title: conclusionMessages.information.sectionTitle,
- children: [],
- }),
],
})
diff --git a/libs/application/templates/parental-leave/src/lib/ParentalLeaveTemplate.ts b/libs/application/templates/parental-leave/src/lib/ParentalLeaveTemplate.ts
index 9ee3caa1f925..43a721173eb2 100644
--- a/libs/application/templates/parental-leave/src/lib/ParentalLeaveTemplate.ts
+++ b/libs/application/templates/parental-leave/src/lib/ParentalLeaveTemplate.ts
@@ -171,7 +171,7 @@ const ParentalLeaveTemplate: ApplicationTemplate<
logMessage: coreHistoryMessages.applicationSent,
},
},
- lifecycle: pruneAfterDays(90),
+ lifecycle: pruneAfterDays(970), //pruneAfterDays(90),
onExit: defineTemplateApi({
action: ApiModuleActions.validateApplication,
throwOnError: true,
@@ -233,7 +233,7 @@ const ParentalLeaveTemplate: ApplicationTemplate<
},
],
},
- lifecycle: birthDayLifeCycle,
+ lifecycle: pruneAfterDays(970),
onEntry: defineTemplateApi({
action: ApiModuleActions.assignOtherParent,
throwOnError: true,
@@ -312,7 +312,7 @@ const ParentalLeaveTemplate: ApplicationTemplate<
logMessage: statesMessages.editHistoryLogMessage,
},
},
- lifecycle: birthDayLifeCycle,
+ lifecycle: pruneAfterDays(970),
onEntry: defineTemplateApi({
action: ApiModuleActions.notifyApplicantOfRejectionFromOtherParent,
throwOnError: true,
@@ -349,7 +349,7 @@ const ParentalLeaveTemplate: ApplicationTemplate<
},
],
},
- lifecycle: birthDayLifeCycle,
+ lifecycle: pruneAfterDays(970),
onEntry: defineTemplateApi({
action: ApiModuleActions.assignEmployer,
throwOnError: true,
@@ -394,7 +394,7 @@ const ParentalLeaveTemplate: ApplicationTemplate<
},
],
},
- lifecycle: birthDayLifeCycle,
+ lifecycle: pruneAfterDays(970),
roles: [
{
id: Roles.ASSIGNEE,
@@ -474,7 +474,7 @@ const ParentalLeaveTemplate: ApplicationTemplate<
logMessage: statesMessages.editHistoryLogMessage,
},
},
- lifecycle: birthDayLifeCycle,
+ lifecycle: pruneAfterDays(970),
onEntry: defineTemplateApi({
action: ApiModuleActions.notifyApplicantOfRejectionFromEmployer,
throwOnError: true,
@@ -531,7 +531,7 @@ const ParentalLeaveTemplate: ApplicationTemplate<
},
],
},
- lifecycle: birthDayLifeCycle,
+ lifecycle: pruneAfterDays(970),
onEntry: [
defineTemplateApi({
triggerEvent: DefaultEvents.SUBMIT,
@@ -614,7 +614,7 @@ const ParentalLeaveTemplate: ApplicationTemplate<
logMessage: statesMessages.editHistoryLogMessage,
},
},
- lifecycle: birthDayLifeCycle,
+ lifecycle: pruneAfterDays(970),
roles: [
{
id: Roles.APPLICANT,
@@ -663,7 +663,7 @@ const ParentalLeaveTemplate: ApplicationTemplate<
statesMessages.additionalDocumentRequiredApproveHistoryLogMessage,
},
},
- lifecycle: birthDayLifeCycle,
+ lifecycle: pruneAfterDays(970),
roles: [
{
id: Roles.APPLICANT,
@@ -705,7 +705,7 @@ const ParentalLeaveTemplate: ApplicationTemplate<
displayStatus: 'warning',
},
},
- lifecycle: birthDayLifeCycle,
+ lifecycle: pruneAfterDays(970),
onEntry: defineTemplateApi({
action: ApiModuleActions.setBirthDate,
externalDataId: 'dateOfBirth',
@@ -765,7 +765,7 @@ const ParentalLeaveTemplate: ApplicationTemplate<
},
],
},
- lifecycle: birthDayLifeCycle,
+ lifecycle: pruneAfterDays(970),
onExit: defineTemplateApi({
action: ApiModuleActions.validateApplication,
triggerEvent: DefaultEvents.APPROVE,
@@ -826,7 +826,7 @@ const ParentalLeaveTemplate: ApplicationTemplate<
},
],
},
- lifecycle: birthDayLifeCycle,
+ lifecycle: pruneAfterDays(970),
onExit: [
defineTemplateApi({
action: ApiModuleActions.setBirthDate,
@@ -938,7 +938,7 @@ const ParentalLeaveTemplate: ApplicationTemplate<
},
],
},
- lifecycle: birthDayLifeCycle,
+ lifecycle: pruneAfterDays(970),
onExit: defineTemplateApi({
triggerEvent: DefaultEvents.SUBMIT,
action: ApiModuleActions.validateApplication,
@@ -1004,7 +1004,7 @@ const ParentalLeaveTemplate: ApplicationTemplate<
actionCard: {
pendingAction: employerApprovalStatePendingAction,
},
- lifecycle: birthDayLifeCycle,
+ lifecycle: pruneAfterDays(970),
onEntry: defineTemplateApi({
action: ApiModuleActions.assignEmployer,
throwOnError: true,
@@ -1055,7 +1055,7 @@ const ParentalLeaveTemplate: ApplicationTemplate<
},
],
},
- lifecycle: birthDayLifeCycle,
+ lifecycle: pruneAfterDays(970),
roles: [
{
id: Roles.ASSIGNEE,
@@ -1140,7 +1140,7 @@ const ParentalLeaveTemplate: ApplicationTemplate<
},
],
},
- lifecycle: birthDayLifeCycle,
+ lifecycle: pruneAfterDays(970),
onEntry: defineTemplateApi({
action: ApiModuleActions.notifyApplicantOfRejectionFromEmployer,
throwOnError: true,
@@ -1231,7 +1231,7 @@ const ParentalLeaveTemplate: ApplicationTemplate<
},
],
},
- lifecycle: birthDayLifeCycle,
+ lifecycle: pruneAfterDays(970),
onEntry: [
defineTemplateApi({
triggerEvent: DefaultEvents.APPROVE,
@@ -1321,7 +1321,7 @@ const ParentalLeaveTemplate: ApplicationTemplate<
},
],
},
- lifecycle: birthDayLifeCycle,
+ lifecycle: pruneAfterDays(970),
onExit: defineTemplateApi({
action: ApiModuleActions.setVMSTPeriods,
triggerEvent: DefaultEvents.EDIT,
diff --git a/libs/application/templates/parental-leave/src/lib/parentalLeaveUtils.ts b/libs/application/templates/parental-leave/src/lib/parentalLeaveUtils.ts
index 321329d958a5..a1c9b24c60c5 100644
--- a/libs/application/templates/parental-leave/src/lib/parentalLeaveUtils.ts
+++ b/libs/application/templates/parental-leave/src/lib/parentalLeaveUtils.ts
@@ -2080,7 +2080,7 @@ export const calculatePruneDate = (application: Application) => {
// Just to be sure that we have some date set for prune date
if (!pruneAt) {
const pruneDate = new Date()
- pruneDate.setMonth(pruneDate.getMonth() + 3)
+ pruneDate.setMonth(pruneDate.getMonth() + 24)
return pruneDate
}
diff --git a/libs/application/templates/public-debt-payment-plan/src/fields/DescriptionWithLink/index.tsx b/libs/application/templates/public-debt-payment-plan/src/fields/DescriptionWithLink/index.tsx
deleted file mode 100644
index 098a446f616f..000000000000
--- a/libs/application/templates/public-debt-payment-plan/src/fields/DescriptionWithLink/index.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-import { Link, Text } from '@island.is/island-ui/core'
-import React, { FC } from 'react'
-import { useLocale } from '@island.is/localization'
-import { formatText } from '@island.is/application/core'
-import { FieldBaseProps } from '@island.is/application/types'
-import { Box } from '@island.is/island-ui/core'
-
-type DescriptionLinkProps = {
- field: {
- props: {
- descriptionFirstPart: string
- descriptionSecondPart: string
- linkName: string
- url: string
- }
- }
-}
-
-export const DescriptionWithLink: FC<
- React.PropsWithChildren
-> = ({ application, field }) => {
- const { props } = field
- const { formatMessage } = useLocale()
- const { descriptionFirstPart, descriptionSecondPart, linkName, url } = props
- return (
-
-
-
- {`${formatText(descriptionFirstPart, application, formatMessage)} `}
-
- {` ${formatText(
- linkName,
- application,
- formatMessage,
- )}`}
-
- {formatText(descriptionSecondPart, application, formatMessage)}
-
-
-
- )
-}
diff --git a/libs/application/templates/public-debt-payment-plan/src/fields/EmployerInfo/EmployerInfo.tsx b/libs/application/templates/public-debt-payment-plan/src/fields/EmployerInfo/EmployerInfo.tsx
deleted file mode 100644
index 7a7a80e4b533..000000000000
--- a/libs/application/templates/public-debt-payment-plan/src/fields/EmployerInfo/EmployerInfo.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-import { PaymentScheduleEmployer } from '@island.is/api/schema'
-import { getValueViaPath } from '@island.is/application/core'
-import { FieldBaseProps } from '@island.is/application/types'
-import { Box, Text } from '@island.is/island-ui/core'
-import { format as formatKennitala } from 'kennitala'
-import React from 'react'
-
-export const EmployerInfo = ({ application }: FieldBaseProps) => {
- const employerInfo = getValueViaPath(
- application.externalData,
- 'paymentPlanPrerequisites.data.employer',
- ) as PaymentScheduleEmployer
-
- const correctedNationalId = getValueViaPath(
- application.answers,
- 'correctedEmployer.nationalId',
- undefined,
- )
- const correctedName = getValueViaPath(
- application.answers,
- 'correctedEmployer.label',
- undefined,
- )
-
- if (!employerInfo) {
- console.error(
- 'Public Dept Payment Plan Application: Did not receive employer information from service.',
- )
- return null
- }
-
- return (
-
- {{correctedName || employerInfo.name}}
-
- {`kt. ${formatKennitala(
- correctedNationalId || employerInfo.nationalId,
- )}`}
-
-
- )
-}
diff --git a/libs/application/templates/public-debt-payment-plan/src/fields/EmployerInfo/EmployerInfoDescription.css.ts b/libs/application/templates/public-debt-payment-plan/src/fields/EmployerInfo/EmployerInfoDescription.css.ts
deleted file mode 100644
index 03675f510288..000000000000
--- a/libs/application/templates/public-debt-payment-plan/src/fields/EmployerInfo/EmployerInfoDescription.css.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import { style } from '@vanilla-extract/css'
-
-export const wrapper = style({
- marginTop: -24,
-})
diff --git a/libs/application/templates/public-debt-payment-plan/src/fields/EmployerInfo/EmployerInfoDescription.tsx b/libs/application/templates/public-debt-payment-plan/src/fields/EmployerInfo/EmployerInfoDescription.tsx
deleted file mode 100644
index 5a5211bddf03..000000000000
--- a/libs/application/templates/public-debt-payment-plan/src/fields/EmployerInfo/EmployerInfoDescription.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import { Button, Link, Text } from '@island.is/island-ui/core'
-import { useLocale } from '@island.is/localization'
-import React from 'react'
-import { employer } from '../../lib/messages'
-import * as styles from './EmployerInfoDescription.css'
-
-export const EmployerInfoDescription = () => {
- const { formatMessage } = useLocale()
-
- return (
-
-
- {`${formatMessage(employer.general.pageDescription)} `}
-
-
-
-
-
- )
-}
diff --git a/libs/application/templates/public-debt-payment-plan/src/fields/index.ts b/libs/application/templates/public-debt-payment-plan/src/fields/index.ts
index 6d46016e1363..7f73029d83a2 100644
--- a/libs/application/templates/public-debt-payment-plan/src/fields/index.ts
+++ b/libs/application/templates/public-debt-payment-plan/src/fields/index.ts
@@ -1,7 +1,4 @@
export * from './DisposableIncome/DisposableIncome'
-export * from './EmployerInfo/EmployerInfo'
-export * from './EmployerInfo/EmployerInfoDescription'
export * from './Overview/Overview'
export * from './PaymentPlan/PaymentPlan'
export * from './PaymentPlanList/PaymentPlanList'
-export * from './DescriptionWithLink'
diff --git a/libs/application/templates/public-debt-payment-plan/src/forms/PaymentPlanForm.ts b/libs/application/templates/public-debt-payment-plan/src/forms/PaymentPlanForm.ts
index e46f1cf3ba2c..5c384e1dda31 100644
--- a/libs/application/templates/public-debt-payment-plan/src/forms/PaymentPlanForm.ts
+++ b/libs/application/templates/public-debt-payment-plan/src/forms/PaymentPlanForm.ts
@@ -1,12 +1,17 @@
-import { PaymentScheduleDebts } from '@island.is/api/schema'
+import {
+ PaymentScheduleDebts,
+ PaymentScheduleEmployer,
+} from '@island.is/api/schema'
import {
buildCompanySearchField,
buildCustomField,
+ buildDescriptionField,
buildForm,
buildMultiField,
buildRadioField,
buildSection,
buildSubmitField,
+ getValueViaPath,
} from '@island.is/application/core'
import {
CustomField,
@@ -35,6 +40,7 @@ import {
paymentPlanIndexKeyMapper,
PublicDebtPaymentPlan,
} from '../types'
+import { format as formatKennitala } from 'kennitala'
// Builds a payment plan step that exists of two custom fields:
// The overview step detailing a list of all payment plans and their status
@@ -99,17 +105,43 @@ export const PaymentPlanForm: Form = buildForm({
return debts?.find((x) => x.type === 'Wagedection') !== undefined
},
children: [
- buildCustomField({
+ buildDescriptionField({
id: 'employerInfoDescription',
title: '',
- doesNotRequireAnswer: true,
- component: 'EmployerInfoDescription',
+ description: employer.general.pageDescription,
}),
- buildCustomField({
- id: 'employerInfo',
- title: '',
- doesNotRequireAnswer: true,
- component: 'EmployerInfo',
+ buildDescriptionField({
+ id: 'employerInfoDescription',
+ title: (application) => {
+ const correctedName = getValueViaPath(
+ application.answers,
+ 'correctedEmployer.label',
+ )
+ const employerInfo = getValueViaPath(
+ application.externalData,
+ 'paymentPlanPrerequisites.data.employer',
+ ) as PaymentScheduleEmployer
+
+ return correctedName || employerInfo.name
+ },
+ titleVariant: 'h2',
+ description: (application) => {
+ const correctedNationalId = getValueViaPath(
+ application.answers,
+ 'correctedEmployer.nationalId',
+ undefined,
+ )
+
+ const employerInfo = getValueViaPath(
+ application.externalData,
+ 'paymentPlanPrerequisites.data.employer',
+ ) as PaymentScheduleEmployer
+
+ return `kt ${formatKennitala(
+ correctedNationalId || employerInfo.nationalId,
+ )}`
+ },
+ marginTop: 3,
}),
buildRadioField({
id: 'employer.isCorrectInfo',
diff --git a/libs/application/templates/public-debt-payment-plan/src/lib/messages/employer.ts b/libs/application/templates/public-debt-payment-plan/src/lib/messages/employer.ts
index 3c5b38c2e9fc..962ae1abb1bf 100644
--- a/libs/application/templates/public-debt-payment-plan/src/lib/messages/employer.ts
+++ b/libs/application/templates/public-debt-payment-plan/src/lib/messages/employer.ts
@@ -8,9 +8,9 @@ export const employer = {
description: 'Employer page title',
},
pageDescription: {
- id: `pdpp.application:application.employer.general.pageDescription`,
+ id: 'pdpp.application:application.employer.general.pageDescription#markdown',
defaultMessage:
- 'Samkvæmt 11. gr. laga um innheimtu opinberra skatta og gjalda, nr. 150/2019 ber launagreiðanda að draga af launum opinber gjöld utan staðgreiðslu, þ.e. þing- og sveitarsjóðsgjöld. Nánar má lesa um launaafdrátt á ',
+ 'Samkvæmt 11. gr. laga um innheimtu opinberra skatta og gjalda, nr. 150/2019 ber launagreiðanda að draga af launum opinber gjöld utan staðgreiðslu, þ.e. þing- og sveitarsjóðsgjöld. Nánar má lesa um launaafdrátt á [heimasíðu skattsins](https://www.skatturinn.is)',
description: 'Employer page description',
},
taxHomePageUrl: {
diff --git a/libs/application/types/src/lib/ApplicationTypes.ts b/libs/application/types/src/lib/ApplicationTypes.ts
index 369a3cc0cc3e..a31a817fa69f 100644
--- a/libs/application/types/src/lib/ApplicationTypes.ts
+++ b/libs/application/types/src/lib/ApplicationTypes.ts
@@ -30,6 +30,7 @@ export enum ApplicationTypes {
MORTGAGE_CERTIFICATE = 'MortgageCertificate',
MARRIAGE_CONDITIONS = 'MarriageConditions',
NO_DEBT_CERTIFICATE = 'NoDebtCertificate',
+ FINANCIAL_STATEMENT_CEMETERY = 'FinancialStatementCemetery',
FINANCIAL_STATEMENTS_INAO = 'FinancialStatementsInao',
OPERATING_LICENSE = 'OperatingLicense',
ESTATE = 'Estate',
@@ -202,6 +203,10 @@ export const ApplicationConfigurations = {
slug: 'skuldleysisvottord',
translation: 'ndc.application',
},
+ [ApplicationTypes.FINANCIAL_STATEMENT_CEMETERY]: {
+ slug: 'skil-arsreikninga-kirkjugardar',
+ translation: 'fsck.application',
+ },
[ApplicationTypes.FINANCIAL_STATEMENTS_INAO]: {
slug: 'skilarsreikninga',
translation: 'fsn.application',
@@ -360,7 +365,7 @@ export const ApplicationConfigurations = {
},
[ApplicationTypes.STREET_REGISTRATION]: {
slug: 'gotuskraning-taekis',
- translation: 'sr.application',
+ translation: 'aosh.sr.application',
},
[ApplicationTypes.NEW_PRIMARY_SCHOOL]: {
slug: 'nyr-grunnskoli',
diff --git a/libs/application/types/src/lib/Fields.ts b/libs/application/types/src/lib/Fields.ts
index 52b0678fd9fc..4820e3031c4a 100644
--- a/libs/application/types/src/lib/Fields.ts
+++ b/libs/application/types/src/lib/Fields.ts
@@ -456,7 +456,7 @@ export interface LinkField extends BaseField {
readonly type: FieldTypes.LINK
component: FieldComponents.LINK
s3key?: FormText
- link?: string
+ link?: FormText
iconProps?: Pick
}
@@ -470,15 +470,19 @@ export interface PaymentChargeOverviewField extends BaseField {
) => { chargeItemCode: string; extraLabel?: StaticText }[]
}
+type ImageWidthProps = 'full' | 'auto' | '50%'
+type ImagePositionProps = 'left' | 'right' | 'center'
+
export interface ImageField extends BaseField {
readonly type: FieldTypes.IMAGE
component: FieldComponents.IMAGE
image: React.FunctionComponent> | string
alt?: string
- imageWidth?: 'full' | 'auto'
marginTop?: ResponsiveProp
marginBottom?: ResponsiveProp
titleVariant?: TitleVariants
+ imageWidth?: ImageWidthProps | Array
+ imagePosition?: ImagePositionProps | Array
}
export interface PdfLinkButtonField extends BaseField {
diff --git a/libs/application/types/src/lib/InstitutionMapper.ts b/libs/application/types/src/lib/InstitutionMapper.ts
index 2afd8b56e0e3..3de8410d1c99 100644
--- a/libs/application/types/src/lib/InstitutionMapper.ts
+++ b/libs/application/types/src/lib/InstitutionMapper.ts
@@ -123,6 +123,10 @@ export const institutionMapper = {
nationalId: InstitutionNationalIds.FJARSYSLA_RIKISINS,
slug: InstitutionTypes.FJARSYSLA_RIKISINS,
},
+ [ApplicationTypes.FINANCIAL_STATEMENT_CEMETERY]: {
+ nationalId: InstitutionNationalIds.RIKISENDURSKODUN,
+ slug: InstitutionTypes.RIKISENDURSKODUN,
+ },
[ApplicationTypes.FINANCIAL_STATEMENTS_INAO]: {
nationalId: InstitutionNationalIds.RIKISENDURSKODUN,
slug: InstitutionTypes.RIKISENDURSKODUN,
diff --git a/libs/application/ui-fields/src/lib/AsyncSelectFormField/AsyncSelectFormField.tsx b/libs/application/ui-fields/src/lib/AsyncSelectFormField/AsyncSelectFormField.tsx
index 791e983a3518..22f97bc59d4a 100644
--- a/libs/application/ui-fields/src/lib/AsyncSelectFormField/AsyncSelectFormField.tsx
+++ b/libs/application/ui-fields/src/lib/AsyncSelectFormField/AsyncSelectFormField.tsx
@@ -42,7 +42,7 @@ export const AsyncSelectFormField: FC> = ({
const [hasLoadingError, setHasLoadingError] = useState(false)
useEffect(() => {
- async function load() {
+ const load = async () => {
try {
setHasLoadingError(false)
const loaded = await loadOptions({ application, apolloClient })
diff --git a/libs/application/ui-fields/src/lib/DateFormField/DateFormField.tsx b/libs/application/ui-fields/src/lib/DateFormField/DateFormField.tsx
index df34acb17704..38a0cbe05c95 100644
--- a/libs/application/ui-fields/src/lib/DateFormField/DateFormField.tsx
+++ b/libs/application/ui-fields/src/lib/DateFormField/DateFormField.tsx
@@ -29,7 +29,6 @@ export const DateFormField: FC> = ({
disabled,
title,
description,
- defaultValue,
required,
placeholder,
backgroundColor,
diff --git a/libs/application/ui-fields/src/lib/DescriptionFormField/DescriptionFormField.tsx b/libs/application/ui-fields/src/lib/DescriptionFormField/DescriptionFormField.tsx
index e91e8949c475..d196870350fd 100644
--- a/libs/application/ui-fields/src/lib/DescriptionFormField/DescriptionFormField.tsx
+++ b/libs/application/ui-fields/src/lib/DescriptionFormField/DescriptionFormField.tsx
@@ -26,16 +26,10 @@ export const DescriptionFormField: FC<
{formatText(field.title, application, formatMessage)}
{field.titleTooltip && (
- <>
-
- >
+
)}
)}
@@ -47,12 +41,10 @@ export const DescriptionFormField: FC<
)}
{field.tooltip && (
- <>
-
- >
+
)}
)}
diff --git a/libs/application/ui-fields/src/lib/FindVehicleFormField/FindVehicleFormField.tsx b/libs/application/ui-fields/src/lib/FindVehicleFormField/FindVehicleFormField.tsx
index 5f5d94964b16..5fe5fdc004bc 100644
--- a/libs/application/ui-fields/src/lib/FindVehicleFormField/FindVehicleFormField.tsx
+++ b/libs/application/ui-fields/src/lib/FindVehicleFormField/FindVehicleFormField.tsx
@@ -178,11 +178,11 @@ export const FindVehicleFormField: FC> = ({
const [energyDetails, setEnergyDetails] =
useState(null)
- const MAX_LENGTH = isMachine ? 6 : 5
const [submitButtonDisabledCalled, setSubmitButtonDisabledCalled] =
useState(false)
const updateInputState = (value: string) => {
- setButtonDisabled(value.length !== MAX_LENGTH)
+ const maxLength = isMachine ? 7 : 5
+ setButtonDisabled(value.length !== maxLength && value.length !== 6)
setPlate(value)
}
const findVehicleByPlate = async () => {
@@ -318,7 +318,7 @@ export const FindVehicleFormField: FC> = ({
setSubmitButtonDisabled && setSubmitButtonDisabled(true)
setSubmitButtonDisabledCalled(true)
}
- if (plate.length === MAX_LENGTH) {
+ if (plate.length === 5 || plate.length === 6 || plate.length === 7) {
setButtonDisabled(false)
}
if (machineDetails && machineDetails.disabled) {
@@ -346,13 +346,19 @@ export const FindVehicleFormField: FC> = ({
rules={{
required: true,
validate: (value) => {
- if (value.length !== MAX_LENGTH) {
- return false
+ if (isMachine) {
+ if (value.length !== 6 && value.length !== 7) {
+ return false
+ }
+ } else {
+ if (value.length !== 5) {
+ return false
+ }
}
return true
},
}}
- maxLength={MAX_LENGTH}
+ maxLength={isMachine ? 7 : 5}
/>
| |