Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(regulations-admin): Add change appendix diff #15811

Merged
merged 12 commits into from
Sep 30, 2024
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ApiProperty } from '@nestjs/swagger'
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'
import { HTMLText, PlainText } from '@island.is/regulations'

export class AppendixModel {
Expand All @@ -7,4 +7,7 @@ export class AppendixModel {

@ApiProperty()
text!: HTMLText

@ApiPropertyOptional()
diff?: HTMLText
}
2 changes: 1 addition & 1 deletion apps/services/regulations-admin-backend/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ bootstrap({
appModule: AppModule,
name: 'regulations-admin-backend',
openApi,
jsonBodyLimit: '300kb',
jsonBodyLimit: '400kb',
})
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ class CreateChangeAppendixInput {

@Field(() => String, { nullable: true })
text!: HTMLText

@Field(() => String, { nullable: true })
diff?: HTMLText
}
@InputType()
export class CreateDraftRegulationChangeInput {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ class UpdateChangeAppendixInput {

@Field(() => String, { nullable: true })
text!: HTMLText

@Field(() => String, { nullable: true })
diff?: HTMLText
}

@InputType()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ export class ChangeAppendix {

@Field(() => String, { nullable: true })
text!: HTMLText

@Field(() => String, { nullable: true })
diff?: HTMLText
}

@ObjectType()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import { RegulationDraftTypes } from '../types'
import ConfirmModal from './ConfirmModal/ConfirmModal'
import { ReferenceText } from './impacts/ReferenceText'
import { DraftChangeForm, DraftImpactForm } from '../state/types'
import { makeDraftAppendixForm } from '../state/makeFields'
import { hasAnyChange } from '../utils/formatAmendingUtils'

const updateText =
'Ósamræmi er í texta stofnreglugerðar og breytingareglugerðar. Texti breytingareglugerðar þarf að samræmast breytingum sem gerðar hafa verið á stofnreglugerð, eigi breytingarnar að færast inn með réttum hætti.'
Expand All @@ -37,6 +39,7 @@ export const EditBasics = () => {
const [editorKey, setEditorKey] = useState('initial')
const [titleError, setTitleError] = useState<string | undefined>(undefined)
const [hasUpdated, setHasUpdated] = useState<boolean>(false)
const [hasUpdatedAppendix, setHasUpdatedAppendix] = useState<boolean>(false)
const [references, setReferences] = useState<DraftImpactForm[]>()
const [isModalVisible, setIsModalVisible] = useState<boolean>(true)
const [hasConfirmed, setHasConfirmed] = useState<boolean>(false)
Expand All @@ -45,8 +48,7 @@ export const EditBasics = () => {
const { text, appendixes } = draft
const { updateState } = actions

const startTextExpanded =
!text.value || appendixes.length === 0 || !!text.error
const startTextExpanded = true

const regType =
draft.type.value &&
Expand Down Expand Up @@ -118,13 +120,53 @@ export const EditBasics = () => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [draft.impacts])

useEffect(() => {
if (!hasUpdatedAppendix && hasUpdated) {
updateAppendixes()
setHasUpdatedAppendix(true)
}
}, [hasUpdated, hasUpdatedAppendix])

const updateAppendixes = () => {
// FORMAT AMENDING REGULATION APPENDIXES
const impactArray = Object.values(draft.impacts).flat()
const amendingArray = impactArray.filter(
(item) => item.type === 'amend',
) as DraftChangeForm[]

if (appendixes?.length > 0) {
appendixes.splice(0, appendixes.length)
}

amendingArray.map((item) => {
item.appendixes.map((apx, idx) => {
if (apx.diff?.value && hasAnyChange(apx.diff.value)) {
const defaultTitle = apx.title.value ?? `Viðauki ${idx + 1}`
const defaultText = apx.text.value
if (
appendixes?.length === 0 ||
!appendixes.some((ap) => ap.text.value === defaultText)
) {
appendixes.push(
makeDraftAppendixForm(
{ title: defaultTitle, text: defaultText },
String(appendixes.length),
),
)
}
}
})
})
}
thordurhhh marked this conversation as resolved.
Show resolved Hide resolved

const updateEditorText = () => {
const additions = formatAmendingBodyWithArticlePrefix(draft.impacts)

setEditorKey(Date.now().toString())
updateState('title', formatAmendingRegTitle(draft))
const additionString = additions.join('') as HTMLText
updateState('text', additionString)

setHasUpdated(true)
}

Expand Down Expand Up @@ -228,7 +270,7 @@ export const EditBasics = () => {
name: (references[0].name as RegName) ?? '',
appendixes: references[0].appendixes.map((apx) => ({
title: apx.title.value,
text: apx.text.value,
text: apx.diff?.value,
})),
} as Regulation
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,12 +221,32 @@ export const EditChange = (props: EditChangeProp) => {
validateImpact(activeChange)
}, [activeChange])

const getDiffHtml = () => {
const emptyHTML = '' as HTMLText
const prev = previousRegulation?.text || emptyHTML
const current = activeChange.text.value || emptyHTML
const emptyHTML = '' as HTMLText
const getDiffHtml = (previous?: HTMLText, current?: HTMLText) => {
const prev = previous || previousRegulation?.text || emptyHTML
const curr = current || activeChange.text.value || emptyHTML

return getDiff(dirtyClean(prev), dirtyClean(current)).diff || emptyHTML
return getDiff(dirtyClean(prev), dirtyClean(curr)).diff || emptyHTML
}

const getAppendixDiffHtml = (i: number) => {
const previous = previousRegulation?.appendixes[i]?.text || emptyHTML
const current = activeChange?.appendixes[i]?.text.value || emptyHTML

const diff = getDiff(dirtyClean(previous), dirtyClean(current)).diff

if (!previousRegulation?.appendixes[i]) {
// If the appendix is new
return `<div data-diff="new">${diff}</div>` as HTMLText
}

if (diff) {
// If the appendix has changes
return diff
} else {
// If the appendix has no changes
return undefined
}
thordurhhh marked this conversation as resolved.
Show resolved Hide resolved
}

const saveChange = async () => {
Expand All @@ -239,9 +259,10 @@ export const EditChange = (props: EditChangeProp) => {
title: activeChange.title.value,
text: activeChange.text.value,
diff: getDiffHtml(),
appendixes: activeChange.appendixes.map((apx) => ({
appendixes: activeChange.appendixes.map((apx, i) => ({
title: apx.title.value,
text: apx.text.value,
diff: getAppendixDiffHtml(i),
})),
date: toISODate(activeChange.date.value),
},
Expand All @@ -264,9 +285,10 @@ export const EditChange = (props: EditChangeProp) => {
title: activeChange.title.value,
text: activeChange.text.value,
diff: getDiffHtml(),
appendixes: activeChange.appendixes.map((apx) => ({
appendixes: activeChange.appendixes.map((apx, i) => ({
title: apx.title.value,
text: apx.text.value,
diff: getAppendixDiffHtml(i),
})),
date: toISODate(activeChange.date.value),
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,10 @@ export const ReferenceText = (props: ReferenceTextProps) => {
{appendixes.map(({ title, text }, i) => (
<div className={s.referenceTextAppendix} key={i}>
<h2 className={s.referenceTextAppendixTitle}>{title}</h2>
<HTMLDump className={ed.classes.editor} html={text as HTMLText} />
<HTMLDump
className={cn(ed.classes.editor, s.diff)}
html={text as HTMLText}
/>
</div>
))}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,12 @@ export const makeDraftChangeForm = (
// ---------------------------------------------------------------------------

export const makeDraftAppendixForm = (
appendix: Appendix,
appendix: Appendix & { diff?: HTMLText },
key: string,
): AppendixDraftForm => ({
title: fText(appendix.title, true),
text: fHtml(appendix.text, true),
diff: appendix.diff ? fHtml(appendix.diff) : undefined,
key,
})

Expand Down
1 change: 1 addition & 0 deletions libs/portals/admin/regulations-admin/src/state/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export type AppendixDraftForm = {
title: DraftField<PlainText, 'text'>
text: HtmlDraftField

diff?: HtmlDraftField
/**
* Appendixes may be revoked by `RegulationChange`s.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { asDiv, HTMLText } from '@island.is/regulations'
import { GroupedDraftImpactForms, RegDraftForm } from '../state/types'
import {
AppendixDraftForm,
GroupedDraftImpactForms,
RegDraftForm,
} from '../state/types'
import format from 'date-fns/format'
import is from 'date-fns/locale/is'
import compact from 'lodash/compact'
Expand All @@ -10,8 +14,10 @@ import {
extractArticleTitleDisplay,
getTextWithSpaces,
groupElementsByArticleTitleFromDiv,
hasAnyChange,
isGildisTaka,
removeRegPrefix,
updateAppendixWording,
} from './formatAmendingUtils'
import { getDeletionOrAddition } from './getDeletionOrAddition'

Expand Down Expand Up @@ -173,6 +179,7 @@ export const formatAmendingRegBody = (
repeal?: boolean,
diff?: HTMLText | string | undefined,
regTitle?: string,
appendixes?: AppendixDraftForm[],
) => {
const regName = removeRegNamePrefix(name)
if (repeal) {
Expand Down Expand Up @@ -409,6 +416,34 @@ export const formatAmendingRegBody = (
}
})

appendixes?.map((apx, idx) => {
if (apx.diff?.value) {
const defaultTitle = apx.title.value ?? `Viðauki ${idx + 1}`

const regNameAddition =
regName && regName !== 'self'
? `reglugerð nr. ${regName}`.replace(/\.$/, '')
: 'reglugerðina'
const regNameChange =
regName && regName !== 'self'
? `, reglugerðar nr. ${regName}`.replace(/\.$/, '')
: ''

const testAddTitle = `Við ${regNameAddition} bætist nýr viðauki, ${defaultTitle} sem ${
/fylgiskjal/i.test(defaultTitle) ? 'birt' : 'birtur'
} er með reglugerð þessari.`
const testChangeTitle = `Eftirfarandi breytingar eru gerðar á ${updateAppendixWording(
defaultTitle,
)}${regNameChange}:`

if (apx.diff?.value.includes('<div data-diff="new">')) {
additionArray.push([`<p>${testAddTitle}</p>` as HTMLText])
} else if (hasAnyChange(apx.diff?.value)) {
additionArray.push([`<p>${testChangeTitle}</p><p>[]</p>` as HTMLText])
}
}
})

thordurhhh marked this conversation as resolved.
Show resolved Hide resolved
return additionArray.flat()
}

Expand All @@ -426,6 +461,7 @@ export const formatAmendingBodyWithArticlePrefix = (
item.type === 'repeal',
item.type === 'amend' ? item.diff?.value : undefined,
item.regTitle,
item.type === 'amend' ? item.appendixes : undefined,
),
date: item.date.value,
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import isSameDay from 'date-fns/isSameDay'
import { HTMLText } from '@island.is/regulations'
import { HTMLText, asDiv } from '@island.is/regulations'

export const groupElementsByArticleTitleFromDiv = (
div: HTMLDivElement,
Expand Down Expand Up @@ -87,3 +87,30 @@ export const allSameDay = (objects: AdditionObject[]): boolean => {

return validObjects.every((obj) => isSameDay(obj.date!, firstDate))
}

export const hasAnyChange = (diff: string) => {
const testElement = asDiv(diff)
const hasDeletion = !!testElement.querySelector('del')
const hasInsert = !!testElement.querySelector('ins')

return hasDeletion || hasInsert
}

export const updateAppendixWording = (input: string): string => {
return input.replace(/fylgiskjal|viðauki/gi, (match) => {
if (match[0] === match[0].toUpperCase()) {
if (match.toLowerCase() === 'fylgiskjal') {
return 'Fylgiskjali'
} else if (match.toLowerCase() === 'viðauki') {
return 'Viðauka'
}
} else {
if (match.toLowerCase() === 'fylgiskjal') {
return 'fylgiskjali'
} else if (match.toLowerCase() === 'viðauki') {
return 'viðauka'
}
}
return match
})
}