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,