diff --git a/i18n/messages.se.js b/i18n/messages.se.js
index 9cb67d28..bbb35ade 100644
--- a/i18n/messages.se.js
+++ b/i18n/messages.se.js
@@ -127,7 +127,7 @@ module.exports = {
},
},
sourceInfo: {
- noInfoYet: 'Ingen information tillagd.',
+ noInfoYet: 'Ingen information tillagd',
insertedSubSection: 'Avsnittet nedan kommer inte från kursplanen:',
},
sectionsLabels: {
diff --git a/public/js/app/components/AllSections.jsx b/public/js/app/components/AllSections.jsx
index 2aaa85d5..dc978b81 100644
--- a/public/js/app/components/AllSections.jsx
+++ b/public/js/app/components/AllSections.jsx
@@ -3,8 +3,7 @@ import Alert from '../components-shared/Alert'
import i18n from '../../../../i18n'
import { context, sections } from '../util/fieldsByType'
-import { EMPTY } from '../util/constants'
-import { getAllSectionsAndHeadingsToShow, headingAllowedToBeShownEvenIfNoContent } from '../util/AllSectionsUtils'
+import { getAllSectionsAndHeadingsToShow } from '../util/allSectionsUtils'
import Section from './Section'
import ContentFromNewSectionEditor from './ContentFromNewSectionEditor'
@@ -14,19 +13,25 @@ function AllSections({ memoData, memoLanguageIndex }) {
return {i18n.messages[memoLanguageIndex].messages.noPublishedMemo}
}
const { sectionsLabels } = i18n.messages[memoLanguageIndex]
+ const { noInfoYet } = i18n.messages[memoLanguageIndex].sourceInfo
const sectionsAndContent = getAllSectionsAndHeadingsToShow({ sections, context, memoData })
- return sectionsAndContent.map(({ id, headings, hasHeadingOrExtraHeading, extraHeaderTitle }) => {
- if (!hasHeadingOrExtraHeading) {
- return
+ return sectionsAndContent.map(({ id, standardHeadingIds, extraHeaderTitle, extraHeadingIndices, isEmptySection }) => {
+ if (isEmptySection) {
+ return
}
return (
-
-
-
+
+
+
)
})
@@ -34,11 +39,13 @@ function AllSections({ memoData, memoLanguageIndex }) {
export default AllSections
-const EmptySection = ({ id, sectionsLabels, memoLanguageIndex }) => (
+const EmptySection = ({ id, sectionsLabels, noInfoYet }) => (
-
- {EMPTY[memoLanguageIndex]}
-
+
+
+ {noInfoYet}
+
+
)
@@ -51,16 +58,10 @@ const SectionWrapper = ({ id, sectionsLabels, children }) => (
)
-const Sections = ({ headings, id, memoData, memoLanguageIndex }) =>
- headings.map(contentId => {
+const Sections = ({ headings, id, memoData, memoLanguageIndex }) => {
+ return headings.map(contentId => {
const menuId = id + '-' + contentId
-
- const { isRequired, type } = context[contentId]
- let contentHtml = memoData[contentId]
-
- if (headingAllowedToBeShownEvenIfNoContent(isRequired, type) && !contentHtml) {
- contentHtml = EMPTY[memoLanguageIndex]
- }
+ const htmlContent = memoData[contentId]
return (
contentId={contentId}
menuId={menuId}
key={contentId}
- visibleInMemo={true}
- html={contentHtml}
+ htmlContent={htmlContent}
/>
)
})
+}
-const ExtraHeaders = ({ extraHeaderTitle, memoData }) => {
- if (!extraHeaderTitle) {
- return null
- }
-
- return memoData[extraHeaderTitle].map(({ title, htmlContent, visibleInMemo, isEmptyNew, uKey }) => (
-
- ))
+const ExtraHeaders = ({ headingIndices, extraHeaderTitle, memoData, memoLanguageIndex }) => {
+ return headingIndices.map(index => {
+ const { uKey, title, htmlContent } = memoData[extraHeaderTitle]?.[index]
+ return (
+
+ )
+ })
}
diff --git a/public/js/app/components/ContentFromNewSectionEditor.jsx b/public/js/app/components/ContentFromNewSectionEditor.jsx
index 87f14c16..4026edc7 100644
--- a/public/js/app/components/ContentFromNewSectionEditor.jsx
+++ b/public/js/app/components/ContentFromNewSectionEditor.jsx
@@ -1,32 +1,15 @@
import React from 'react'
import i18n from '../../../../i18n'
-import { useWebContext } from '../context/WebContext'
import { ExtraHeaderHead } from './ContentHead'
import HtmlWrapper from './HtmlWrapper'
-function ContentFromNewSectionEditor({ htmlContent = '', title = '', isEmptyNew = false, visibleInMemo }) {
- const [webContext] = useWebContext()
- const { userLanguageIndex = 1 } = webContext
-
- const { sourceInfo } = i18n.messages[userLanguageIndex]
+function ContentFromNewSectionEditor({ htmlContent = '', title = '', memoLanguageIndex = 0 /* en */ }) {
+ const { noInfoYet } = i18n.messages[memoLanguageIndex].sourceInfo
return (
- {!isEmptyNew && }
-
- {!isEmptyNew &&
- /* is included in memo, preview text without editor */
- ((visibleInMemo && (
- ${sourceInfo.noInfoYet}
`} />
- )) ||
- /* editor has content but is not yet included in pm */
- (htmlContent !== '' && (
-
-
- {sourceInfo.noInfoYet}
-
-
- )))}
+
+ ${noInfoYet}`} />
)
}
diff --git a/public/js/app/components/Section.jsx b/public/js/app/components/Section.jsx
index d8fdc4e0..874a3e47 100644
--- a/public/js/app/components/Section.jsx
+++ b/public/js/app/components/Section.jsx
@@ -4,7 +4,7 @@ import { context } from '../util/fieldsByType'
import { ContentHead, SubSectionHeaderMessage } from './ContentHead'
import HtmlWrapper from './HtmlWrapper'
-const Section = ({ contentId, menuId, visibleInMemo, html, memoLangIndex = 0 /* en */ }) => {
+const Section = ({ contentId, menuId, htmlContent, memoLangIndex = 0 /* en */ }) => {
const { noInfoYet, insertedSubSection } = i18n.messages[memoLangIndex].sourceInfo
const fromSyllabus = {
is: context[contentId].source === '(s)',
@@ -18,7 +18,7 @@ const Section = ({ contentId, menuId, visibleInMemo, html, memoLangIndex = 0 /*
) : (
)}
- {visibleInMemo && ${noInfoYet}`} />}
+ ${noInfoYet}`} />
)
}
diff --git a/public/js/app/pages/__tests__/__snapshots__/CourseMemo.test.js.snap b/public/js/app/pages/__tests__/__snapshots__/CourseMemo.test.js.snap
index 4be24888..3920b15d 100644
--- a/public/js/app/pages/__tests__/__snapshots__/CourseMemo.test.js.snap
+++ b/public/js/app/pages/__tests__/__snapshots__/CourseMemo.test.js.snap
@@ -351,7 +351,11 @@ exports[`Page CourseMemo renders a side menu and a page structure 1`] = `
- Ingen information tillagd
+
+
+ Ingen information tillagd
+
+
- Ingen information tillagd
+
+
+ Ingen information tillagd
+
+
@@ -403,7 +411,11 @@ exports[`Page CourseMemo renders a side menu and a page structure 1`] = `
Kurslitteratur
- Ingen information tillagd
+
+
+ Ingen information tillagd
+
+
- Ingen information tillagd
+
+
+ Ingen information tillagd
+
+
@@ -455,7 +471,11 @@ exports[`Page CourseMemo renders a side menu and a page structure 1`] = `
- Ingen information tillagd
+
+
+ Ingen information tillagd
+
+
- Ingen information tillagd
+
+
+ Ingen information tillagd
+
+
- Ingen information tillagd
+
+
+ Ingen information tillagd
+
+
@@ -526,11 +554,13 @@ exports[`Page CourseMemo renders a side menu and a page structure 1`] = `
>
Ytterligare Information
-
-
- Ingen information tillagd
-
-
+
+
+
+ Ingen information tillagd
+
+
+
{
- const mandatoryTypes = ['mandatory', 'mandatoryAndEditable']
- return isRequired && mandatoryTypes.includes(type)
-}
-
-const headingHasContent = contentHtml => contentHtml !== undefined && contentHtml !== ''
-
-export const headingShouldBeShown = ({ isRequired, type, contentHtml, visibleInMemo = true }) => {
- if (headingHasContent(contentHtml) || headingAllowedToBeShownEvenIfNoContent(isRequired, type)) {
- return visibleInMemo
- }
-
- return false
-}
-
-const headingHasAtLeastOneVisibleExtraHeader = (extraHeaderTitle, extraHeaderTitles) => {
- if (extraHeaderTitle && extraHeaderTitles && Array.isArray(extraHeaderTitles)) {
- return extraHeaderTitles.some(({ visibleInMemo }) => visibleInMemo)
- }
-
- return false
-}
-
-const sectionsToSkip = ['contacts']
-
-export const getAllSectionsAndHeadingsToShow = ({ sections, context, memoData }) => {
- const sectionsAndHeadings = []
- sections
- .filter(({ id }) => !sectionsToSkip.includes(id))
- .forEach(({ id, content, extraHeaderTitle }) => {
- sectionsAndHeadings[id] = []
- const headings = []
-
- content.forEach(contentId => {
- const { isRequired, type } = context[contentId]
- const contentHtml = memoData[contentId]
- const visibleInMemo = memoData.visibleInMemo[contentId]
-
- if (headingShouldBeShown({ isRequired, type, contentHtml, visibleInMemo })) {
- headings.push(contentId)
- }
- })
-
- const hasExtraHeading = headingHasAtLeastOneVisibleExtraHeader(extraHeaderTitle, memoData[extraHeaderTitle])
-
- const hasHeadingOrExtraHeading = headings.length > 0 || hasExtraHeading
-
- sectionsAndHeadings.push({
- id,
- headings,
- hasHeadingOrExtraHeading,
- extraHeaderTitle: hasExtraHeading ? extraHeaderTitle : undefined,
- })
- })
-
- return sectionsAndHeadings
-}
diff --git a/public/js/app/util/__tests__/AllSectionsUtils.test.js b/public/js/app/util/__tests__/AllSectionsUtils.test.js
deleted file mode 100644
index 544732bb..00000000
--- a/public/js/app/util/__tests__/AllSectionsUtils.test.js
+++ /dev/null
@@ -1,129 +0,0 @@
-import { headingShouldBeShown } from '../AllSectionsUtils'
-
-describe('headingShouldBeShown', () => {
- test.each([
- { isRequired: true, type: 'mandatory', contentHtml: 'someContent', visibleInMemo: true },
- { isRequired: true, type: 'mandatory', contentHtml: 'someContent', visibleInMemo: false },
- { isRequired: true, type: 'mandatory', contentHtml: '', visibleInMemo: true },
- { isRequired: true, type: 'mandatory', contentHtml: '', visibleInMemo: false },
- { isRequired: true, type: 'mandatoryAndEditable', contentHtml: 'someContent', visibleInMemo: true },
- { isRequired: true, type: 'mandatoryAndEditable', contentHtml: 'someContent', visibleInMemo: false },
- { isRequired: true, type: 'mandatoryAndEditable', contentHtml: '', visibleInMemo: true },
- { isRequired: true, type: 'mandatoryAndEditable', contentHtml: '', visibleInMemo: false },
- ])(
- 'if isRequired and type is mandatory or mandatoryAndEditable, return visibleInMemo, regardless if contentHTML is empty or not',
- params => {
- expect(headingShouldBeShown(params)).toBe(params.visibleInMemo)
- }
- )
-
- test.each([
- { isRequired: true, type: 'mandatory', contentHtml: 'someContent', visibleInMemo: undefined },
- { isRequired: true, type: 'mandatory', contentHtml: '', visibleInMemo: undefined },
- { isRequired: true, type: 'mandatoryAndEditable', contentHtml: 'someContent', visibleInMemo: undefined },
- { isRequired: true, type: 'mandatoryAndEditable', contentHtml: '', visibleInMemo: undefined },
- ])(
- 'if isRequired, type is mandatory or mandatoryAndEditable and visibleInMemo is undefined, return true, regardless if contentHTML is empty or not',
- params => {
- expect(headingShouldBeShown(params)).toBe(true)
- }
- )
-
- test.each([
- { isRequired: true, type: 'mandatoryForSome', contentHtml: '', visibleInMemo: true },
- { isRequired: true, type: 'mandatoryForSome', contentHtml: '', visibleInMemo: false },
- { isRequired: true, type: 'mandatoryForSome', contentHtml: '', visibleInMemo: undefined },
- { isRequired: true, type: 'mandatoryForSome', contentHtml: undefined, visibleInMemo: true },
- { isRequired: true, type: 'mandatoryForSome', contentHtml: undefined, visibleInMemo: false },
- { isRequired: true, type: 'mandatoryForSome', contentHtml: undefined, visibleInMemo: undefined },
- ])('if is required, and mandatoryForSome but no contentHTML, should return false', params => {
- expect(headingShouldBeShown(params)).toBe(false)
- })
-
- test.each([
- { isRequired: true, type: 'mandatoryForSome', contentHtml: 'someContent', visibleInMemo: true },
- { isRequired: true, type: 'somethingElse', contentHtml: 'someContent', visibleInMemo: true },
- { isRequired: false, type: 'mandatory', contentHtml: 'someContent', visibleInMemo: true },
- { isRequired: false, type: 'mandatoryForSome', contentHtml: 'someContent', visibleInMemo: true },
- { isRequired: false, type: 'mandatoryAndEditable', contentHtml: 'someContent', visibleInMemo: true },
- { isRequired: false, type: 'somethingElse', contentHtml: 'someContent', visibleInMemo: true },
- { isRequired: undefined, type: 'mandatory', contentHtml: 'someContent', visibleInMemo: true },
- { isRequired: undefined, type: 'mandatoryForSome', contentHtml: 'someContent', visibleInMemo: true },
- { isRequired: undefined, type: 'mandatoryAndEditable', contentHtml: 'someContent', visibleInMemo: true },
- { isRequired: undefined, type: 'somethingElse', contentHtml: 'someContent', visibleInMemo: true },
- ])('if visibleInMemo and has content, return true regardless of isRequired and type', params => {
- expect(headingShouldBeShown(params)).toBe(true)
- })
-
- test.each([
- { isRequired: true, type: 'mandatoryForSome', contentHtml: 'someContent', visibleInMemo: undefined },
- { isRequired: true, type: 'somethingElse', contentHtml: 'someContent', visibleInMemo: undefined },
- { isRequired: false, type: 'mandatory', contentHtml: 'someContent', visibleInMemo: undefined },
- { isRequired: false, type: 'mandatoryForSome', contentHtml: 'someContent', visibleInMemo: undefined },
- { isRequired: false, type: 'mandatoryAndEditable', contentHtml: 'someContent', visibleInMemo: undefined },
- { isRequired: false, type: 'somethingElse', contentHtml: 'someContent', visibleInMemo: undefined },
- { isRequired: undefined, type: 'mandatory', contentHtml: 'someContent', visibleInMemo: undefined },
- { isRequired: undefined, type: 'mandatoryForSome', contentHtml: 'someContent', visibleInMemo: undefined },
- { isRequired: undefined, type: 'mandatoryAndEditable', contentHtml: 'someContent', visibleInMemo: undefined },
- { isRequired: undefined, type: 'somethingElse', contentHtml: 'someContent', visibleInMemo: undefined },
- ])('if visibleInMemo is undefined and has content, return true regardless of isRequired and type', params => {
- expect(headingShouldBeShown(params)).toBe(true)
- })
-
- test.each([
- { isRequired: true, type: 'mandatoryForSome', contentHtml: 'someContent', visibleInMemo: false },
- { isRequired: true, type: 'somethingElse', contentHtml: 'someContent', visibleInMemo: false },
- { isRequired: true, type: 'somethingElse', contentHtml: '', visibleInMemo: false },
- { isRequired: false, type: 'mandatory', contentHtml: 'someContent', visibleInMemo: false },
- { isRequired: false, type: 'mandatory', contentHtml: '', visibleInMemo: false },
- { isRequired: false, type: 'mandatoryForSome', contentHtml: 'someContent', visibleInMemo: false },
- { isRequired: false, type: 'mandatoryForSome', contentHtml: '', visibleInMemo: false },
- { isRequired: false, type: 'mandatoryAndEditable', contentHtml: 'someContent', visibleInMemo: false },
- { isRequired: false, type: 'mandatoryAndEditable', contentHtml: '', visibleInMemo: false },
- { isRequired: false, type: 'somethingElse', contentHtml: 'someContent', visibleInMemo: false },
- { isRequired: false, type: 'somethingElse', contentHtml: '', visibleInMemo: false },
- { isRequired: undefined, type: 'mandatory', contentHtml: 'someContent', visibleInMemo: false },
- { isRequired: undefined, type: 'mandatory', contentHtml: '', visibleInMemo: false },
- { isRequired: undefined, type: 'mandatoryForSome', contentHtml: 'someContent', visibleInMemo: false },
- { isRequired: undefined, type: 'mandatoryForSome', contentHtml: '', visibleInMemo: false },
- { isRequired: undefined, type: 'mandatoryAndEditable', contentHtml: 'someContent', visibleInMemo: false },
- { isRequired: undefined, type: 'mandatoryAndEditable', contentHtml: '', visibleInMemo: false },
- { isRequired: undefined, type: 'somethingElse', contentHtml: 'someContent', visibleInMemo: false },
- { isRequired: undefined, type: 'somethingElse', contentHtml: '', visibleInMemo: false },
- ])('if visibleInMemo is false, return false regardless of isRequired, type and contentHTML', params => {
- expect(headingShouldBeShown(params)).toBe(false)
- })
-
- test.each([
- { isRequired: undefined, type: 'mandatory', contentHtml: '', visibleInMemo: true },
- { isRequired: undefined, type: 'mandatory', contentHtml: '', visibleInMemo: undefined },
- { isRequired: undefined, type: 'mandatoryForSome', contentHtml: '', visibleInMemo: true },
- { isRequired: undefined, type: 'mandatoryForSome', contentHtml: '', visibleInMemo: undefined },
- { isRequired: undefined, type: 'mandatoryAndEditable', contentHtml: '', visibleInMemo: true },
- { isRequired: undefined, type: 'mandatoryAndEditable', contentHtml: '', visibleInMemo: undefined },
- { isRequired: undefined, type: 'somethingElse', contentHtml: '', visibleInMemo: true },
- { isRequired: undefined, type: 'somethingElse', contentHtml: '', visibleInMemo: undefined },
- ])('if isRequired is undefined (false) and contentHtml is empty, return false', params => {
- expect(headingShouldBeShown(params)).toBe(false)
- })
-
- test.each([
- { isRequired: false, type: 'somethingElse', contentHtml: '', visibleInMemo: true },
- { isRequired: false, type: 'somethingElse', contentHtml: '', visibleInMemo: undefined },
- { isRequired: true, type: 'somethingElse', contentHtml: '', visibleInMemo: true },
- { isRequired: true, type: 'somethingElse', contentHtml: '', visibleInMemo: undefined },
- ])('if type is somethingElse and contentHtml is empty, return false', params => {
- expect(headingShouldBeShown(params)).toBe(false)
- })
-
- test.each([
- { isRequired: false, type: 'mandatory', contentHtml: '', visibleInMemo: true },
- { isRequired: false, type: 'mandatory', contentHtml: '', visibleInMemo: undefined },
- { isRequired: false, type: 'mandatoryForSome', contentHtml: '', visibleInMemo: true },
- { isRequired: false, type: 'mandatoryForSome', contentHtml: '', visibleInMemo: undefined },
- { isRequired: false, type: 'mandatoryAndEditable', contentHtml: '', visibleInMemo: true },
- { isRequired: false, type: 'mandatoryAndEditable', contentHtml: '', visibleInMemo: undefined },
- ])('if isRequired is false, type is one of the special types and contentHtml is empty, return false', params => {
- expect(headingShouldBeShown(params)).toBe(false)
- })
-})
diff --git a/public/js/app/util/__tests__/allSectionsUtils.test.js b/public/js/app/util/__tests__/allSectionsUtils.test.js
new file mode 100644
index 00000000..a5557cad
--- /dev/null
+++ b/public/js/app/util/__tests__/allSectionsUtils.test.js
@@ -0,0 +1,107 @@
+import { isStandardHeadingVisibleInPublished, isExtraHeadingVisibleInPublished } from '../allSectionsUtils'
+
+const context = {
+ courseContent: { type: 'mandatory', isRequired: true },
+ literature: { type: 'mandatoryAndEditable', isRequired: true },
+ learningActivities: { type: 'optionalEditable', isRequired: false },
+ scheduleDetails: { type: 'optionalEditable', isRequired: false },
+ prerequisites: { type: 'optional', isRequired: false },
+ permanentDisabilitySubSection: { isRequired: false },
+ additionalRegulations: { type: 'mandatoryForSome', isRequired: true },
+ otherRequirementsForFinalGrade: { type: 'mandatoryForSome', isRequired: true },
+ examinationSubSection: { isRequired: false },
+ ethicalApproachSubSection: { isRequired: false },
+}
+
+const memoData = {
+ courseContent: 'Some text
',
+ literature: '',
+ learningActivities: '',
+ scheduleDetails: 'Some text
',
+ prerequisites: '',
+ additionalRegulations: '',
+ otherRequirementsForFinalGrade: 'Some text
',
+ examinationSubSection: 'Some text
',
+ ethicalApproachSubSection: '',
+ permanentDisabilitySubSection: 'Some text
',
+ extraHeaders1: [
+ { title: 'Extra Heading 1', htmlContent: '', visibleInMemo: true },
+ { title: 'Extra Heading 2', htmlContent: 'Some text
', visibleInMemo: true },
+ { title: 'Extra Heading 3', htmlContent: 'Some text
', visibleInMemo: false },
+ ],
+ extraHeaders2: [],
+ visibleInMemo: {
+ prerequisites: true,
+ permanentDisabilitySubSection: false,
+ additionalRegulations: true,
+ examinationSubSection: true,
+ ethicalApproachSubSection: true,
+ },
+}
+
+describe('isStandardHeadingVisibleInPublished', () => {
+ test.each(['courseContent', 'literature'])('if type is mandatory or mandatoryAndEditable, return true', contentId => {
+ const visibleInMemo = isStandardHeadingVisibleInPublished(contentId, context, memoData)
+ expect(visibleInMemo).toBe(true)
+ })
+
+ describe('if type is not mandatory or mandatoryAndEditable', () => {
+ test.each(['learningActivities', 'prerequisites', 'ethicalApproachSubSection', 'additionalRegulations'])(
+ 'if html does not have content, return false',
+ contentId => {
+ const visibleInMemo = isStandardHeadingVisibleInPublished(contentId, context, memoData)
+ expect(visibleInMemo).toBe(false)
+ }
+ )
+
+ test.each(['otherRequirementsForFinalGrade'])(
+ 'if html has content and type is mandatoryForSome, return true',
+ contentId => {
+ const visibleInMemo = isStandardHeadingVisibleInPublished(contentId, context, memoData)
+ expect(visibleInMemo).toBe(true)
+ }
+ )
+
+ test.each(['examinationSubSection'])(
+ 'if html has content and visibility is stored as true in db, return true',
+ contentId => {
+ const visibleInMemo = isStandardHeadingVisibleInPublished(contentId, context, memoData)
+ expect(visibleInMemo).toBe(true)
+ }
+ )
+
+ test.each(['scheduleDetails'])(
+ 'if html has content, visibility is not stored or is stored as false in db and type is not mandatoryForSome, return false',
+ contentId => {
+ const visibleInMemo = isStandardHeadingVisibleInPublished(contentId, context, memoData)
+ expect(visibleInMemo).toBe(false)
+ }
+ )
+ })
+})
+
+describe('isExtraHeadingVisibleInPublished', () => {
+ test.each([{ extraHeaderTitle: 'extraHeaders1', index: 0 }])(
+ 'if html does not have content and visibility is stored as true in db, return false',
+ ({ extraHeaderTitle, index }) => {
+ const visibleInMemo = isExtraHeadingVisibleInPublished(extraHeaderTitle, index, memoData)
+ expect(visibleInMemo).toBe(false)
+ }
+ )
+
+ test.each([{ extraHeaderTitle: 'extraHeaders1', index: 1 }])(
+ 'if html has content and visibility is stored as true in db, return true',
+ ({ extraHeaderTitle, index }) => {
+ const visibleInMemo = isExtraHeadingVisibleInPublished(extraHeaderTitle, index, memoData)
+ expect(visibleInMemo).toBe(true)
+ }
+ )
+
+ test.each([{ extraHeaderTitle: 'extraHeaders1', index: 2 }])(
+ 'if html has content and visibility is stored as false in db, return false',
+ ({ extraHeaderTitle, index }) => {
+ const visibleInMemo = isExtraHeadingVisibleInPublished(extraHeaderTitle, index, memoData)
+ expect(visibleInMemo).toBe(false)
+ }
+ )
+})
diff --git a/public/js/app/util/allSectionsUtils.js b/public/js/app/util/allSectionsUtils.js
new file mode 100644
index 00000000..332d3ab3
--- /dev/null
+++ b/public/js/app/util/allSectionsUtils.js
@@ -0,0 +1,66 @@
+const isMandatory = type => type === 'mandatory' || type === 'mandatoryAndEditable'
+
+const isMandatoryForSome = type => type === 'mandatoryForSome'
+
+const isStoredAsVisibleInDB = (contentId, memoData) => memoData?.visibleInMemo?.[contentId] === true
+
+const htmlHasContent = contentHtml => contentHtml !== undefined && contentHtml !== ''
+
+export const isStandardHeadingVisibleInPublished = (contentId, context, memoData) => {
+ const { type } = context[contentId]
+ const htmlContent = memoData[contentId]
+
+ const mandatory = isMandatory(type)
+ const mandatoryForSomeOrStoredAsVisible = isMandatoryForSome(type) || isStoredAsVisibleInDB(contentId, memoData)
+
+ return mandatory || (htmlHasContent(htmlContent) && mandatoryForSomeOrStoredAsVisible)
+}
+
+export const isExtraHeadingVisibleInPublished = (extraHeaderTitle, index, memoData) => {
+ const headingObject = memoData[extraHeaderTitle]?.[index]
+ const { visibleInMemo, htmlContent } = headingObject
+ const storedAsVisible = visibleInMemo === true
+
+ return storedAsVisible && htmlHasContent(htmlContent)
+}
+
+const sectionsToSkip = ['contacts']
+
+export const getAllSectionsAndHeadingsToShow = ({ sections, context, memoData }) => {
+ const sectionsAndHeadings = []
+ sections
+ .filter(({ id }) => !sectionsToSkip.includes(id))
+ .forEach(({ id, content, extraHeaderTitle }) => {
+ sectionsAndHeadings[id] = []
+ const standardHeadingIds = []
+ const extraHeadingIndices = []
+
+ content.forEach(contentId => {
+ const visibleInMemo = isStandardHeadingVisibleInPublished(contentId, context, memoData)
+
+ if (visibleInMemo) {
+ standardHeadingIds.push(contentId)
+ }
+ })
+
+ memoData[extraHeaderTitle]?.forEach((headingObject, index) => {
+ const visibleInMemo = isExtraHeadingVisibleInPublished(extraHeaderTitle, index, memoData)
+
+ if (visibleInMemo) {
+ extraHeadingIndices.push(index)
+ }
+ })
+
+ const isEmptySection = standardHeadingIds.length === 0 && extraHeadingIndices.length === 0
+
+ sectionsAndHeadings.push({
+ id,
+ standardHeadingIds,
+ extraHeaderTitle,
+ extraHeadingIndices,
+ isEmptySection,
+ })
+ })
+
+ return sectionsAndHeadings
+}
diff --git a/public/js/app/util/fieldsByType.js b/public/js/app/util/fieldsByType.js
index dc5880dd..b4c0eee9 100644
--- a/public/js/app/util/fieldsByType.js
+++ b/public/js/app/util/fieldsByType.js
@@ -39,14 +39,12 @@ const context = {
source: '(s)',
},
ethicalApproachSubSection: {
- openIfContent: true,
isEditable: true,
isRequired: false,
hasParentTitle: true,
},
examination: { type: 'mandatory', isEditable: false, isRequired: true, source: '(s)' },
examinationSubSection: {
- openIfContent: true,
isEditable: true,
isRequired: false,
hasParentTitle: true,
@@ -58,7 +56,6 @@ const context = {
extraHeaders4: { isEditable: true, isRequired: false },
extraHeaders5: { isEditable: true, isRequired: false },
equipment: {
- openIfContent: true,
type: 'optionalEditable',
isEditable: true,
isRequired: false,
@@ -81,7 +78,6 @@ const context = {
}, // Läraktiviteter
learningOutcomes: { type: 'mandatory', isEditable: false, isRequired: true, source: '(s)' },
literature: {
- openIfContent: true,
type: 'mandatoryAndEditable',
isEditable: true,
isRequired: true,
@@ -95,19 +91,16 @@ const context = {
},
permanentDisability: { type: 'mandatory', isEditable: false, isRequired: true }, // Funktionsnedsättning
permanentDisabilitySubSection: {
- openIfContent: true,
isEditable: true,
isRequired: false,
hasParentTitle: true,
},
possibilityToCompletion: {
- openIfContent: true,
type: 'optionalEditable',
isEditable: true,
isRequired: false,
}, // default
possibilityToAddition: {
- openIfContent: true,
type: 'optionalEditable',
isEditable: true,
isRequired: false,
@@ -119,7 +112,6 @@ const context = {
},
preparations: { type: 'optionalEditable', isEditable: true, isRequired: false }, // Förberedelser inför kursstart
prerequisites: {
- openIfContent: true,
type: 'optional',
isEditable: false,
isRequired: false,
@@ -127,14 +119,12 @@ const context = {
}, // Rekommenderade förkunskaper
reportingResults: { isEditable: true, isRequired: false },
scheduleDetails: {
- openIfContent: true,
type: 'optionalEditable',
isEditable: true,
isRequired: false,
},
software: { type: 'optionalEditable', isEditable: true, isRequired: false }, // Programvara
teacherAssistants: {
- openIfContent: true,
type: 'optional',
isEditable: false,
isRequired: false,