From 9895e340218909d2fe3616c39e477bd45513b281 Mon Sep 17 00:00:00 2001 From: Aditya Khatri Date: Wed, 20 Sep 2023 17:00:13 +0545 Subject: [PATCH] Add general configuration in report builder --- .../ReportBuilder/MetadataEdit/index.tsx | 118 ++++++++++++++++++ .../ReportBuilder/MetadataEdit/styles.css | 6 + .../ReportContainer/Content/index.tsx | 57 +++++++-- .../ReportContainer/Content/styles.css | 19 ++- .../ReportBuilder/ReportContainer/index.tsx | 6 +- .../ReportBuilder/ReportContainer/styles.css | 2 +- app/components/report/ReportBuilder/index.tsx | 8 +- app/components/report/utils.ts | 53 +++++--- app/views/PublicReportView/index.tsx | 71 +++++++++++ app/views/ReportEdit/index.tsx | 41 ++++++ schema.graphql | 20 +++ 11 files changed, 369 insertions(+), 32 deletions(-) diff --git a/app/components/report/ReportBuilder/MetadataEdit/index.tsx b/app/components/report/ReportBuilder/MetadataEdit/index.tsx index d9809e9a17..4dc8015fc8 100644 --- a/app/components/report/ReportBuilder/MetadataEdit/index.tsx +++ b/app/components/report/ReportBuilder/MetadataEdit/index.tsx @@ -3,10 +3,14 @@ import { _cs } from '@togglecorp/fujs'; import { Checkbox, TextInput, + NumberInput, + ExpandableContainer, + Heading, } from '@the-deep/deep-ui'; import { type EntriesAsList, type Error, + useFormObject, getErrorObject, getErrorString, } from '@togglecorp/toggle-form'; @@ -17,7 +21,14 @@ import NewOrganizationMultiSelectInput, { import { type PartialFormType, + type TextContentStyleFormType, + type BodyStyleConfig, + type ImageContentStyleFormType, + type HeadingContentStyleFormType, + type ConfigType, } from '../../schema'; +import TextElementsStylesEdit from '../ReportContainer/TextElementsStylesEdit'; +import ContainerStylesEdit from '../ReportContainer/ContainerStylesEdit'; import styles from './styles.css'; interface Props { @@ -45,6 +56,28 @@ function MetadataEdit(props: Props) { const error = getErrorObject(riskyError); + const onConfigChange = useFormObject< + 'configuration', ConfigType + >('configuration', setFieldValue, {}); + + const handleBodyStyleChange = useFormObject< + 'bodyStyle', BodyStyleConfig + >('bodyStyle', onConfigChange, {}); + + const handleTextContentStyleChange = useFormObject< + 'textContentStyle', TextContentStyleFormType + >('textContentStyle', onConfigChange, {}); + + const handleImageContentStyleChange = useFormObject< + 'imageContentStyle', ImageContentStyleFormType + >('imageContentStyle', onConfigChange, {}); + + const handleHeadingContentStyleChange = useFormObject< + 'headingContentStyle', HeadingContentStyleFormType + >('headingContentStyle', onConfigChange, {}); + + const configurationError = getErrorObject(error?.configuration); + return (
+ + + + + + + + + + + + H1 + + H2 + + H3 + + H4 + +
); } diff --git a/app/components/report/ReportBuilder/MetadataEdit/styles.css b/app/components/report/ReportBuilder/MetadataEdit/styles.css index 97bbf675a7..609fc82043 100644 --- a/app/components/report/ReportBuilder/MetadataEdit/styles.css +++ b/app/components/report/ReportBuilder/MetadataEdit/styles.css @@ -2,4 +2,10 @@ display: flex; flex-direction: column; gap: var(--dui-spacing-medium); + + .expanded-body { + display: flex; + flex-direction: column; + gap: var(--dui-spacing-medium); + } } diff --git a/app/components/report/ReportBuilder/ReportContainer/Content/index.tsx b/app/components/report/ReportBuilder/ReportContainer/Content/index.tsx index ca2b970f21..72fb0977a2 100644 --- a/app/components/report/ReportBuilder/ReportContainer/Content/index.tsx +++ b/app/components/report/ReportBuilder/ReportContainer/Content/index.tsx @@ -12,7 +12,10 @@ import { AnalysisReportContainerContentConfigurationType, } from '#generated/types'; -import { ContentDataType } from '../../../schema'; +import { + type ContentDataType, + type ConfigType, +} from '../../../schema'; import { resolveTextStyle, type ContentDataFileMap, @@ -24,6 +27,7 @@ interface Props { contentType: AnalysisReportContainerContentTypeEnum; contentData: ContentDataType[] | undefined; configuration: AnalysisReportContainerContentConfigurationType | undefined; + generalConfiguration: ConfigType | undefined; contentDataToFileMap: ContentDataFileMap | undefined; } @@ -31,6 +35,7 @@ function Content(props: Props) { const { contentType, configuration: configurationFromProps = {}, + generalConfiguration, contentData, contentDataToFileMap, } = props; @@ -53,7 +58,10 @@ function Content(props: Props) { styles.heading, styles.headingFour, )} - style={resolveTextStyle(style?.content)} + style={resolveTextStyle( + style?.content, + generalConfiguration?.headingContentStyle?.h4, + )} > {content ?? 'Title goes here'} @@ -66,7 +74,10 @@ function Content(props: Props) { styles.heading, styles.headingThree, )} - style={resolveTextStyle(style?.content)} + style={resolveTextStyle( + style?.content, + generalConfiguration?.headingContentStyle?.h3, + )} > {content ?? 'Title goes here'} @@ -79,7 +90,10 @@ function Content(props: Props) { styles.heading, styles.headingTwo, )} - style={resolveTextStyle(style?.content)} + style={resolveTextStyle( + style?.content, + generalConfiguration?.headingContentStyle?.h2, + )} > {content ?? 'Title goes here'} @@ -91,7 +105,10 @@ function Content(props: Props) { styles.heading, styles.headingOne, )} - style={resolveTextStyle(style?.content)} + style={resolveTextStyle( + style?.content, + generalConfiguration?.headingContentStyle?.h1, + )} > {content ?? 'Title goes here'} @@ -108,7 +125,10 @@ function Content(props: Props) { return (
{content ?? 'Content goes here'} @@ -137,7 +157,9 @@ function Content(props: Props) { if (contentType === 'IMAGE') { const { image: { + caption, altText, + style, } = {}, } = configuration; @@ -145,11 +167,24 @@ function Content(props: Props) { if (imageContentData && contentDataToFileMap) { return ( - {altText +
+ {altText + {caption && ( +
+ {caption} +
+ )} +
); } } diff --git a/app/components/report/ReportBuilder/ReportContainer/Content/styles.css b/app/components/report/ReportBuilder/ReportContainer/Content/styles.css index efbf337292..93a8fa882e 100644 --- a/app/components/report/ReportBuilder/ReportContainer/Content/styles.css +++ b/app/components/report/ReportBuilder/ReportContainer/Content/styles.css @@ -30,8 +30,21 @@ height: 100%; } -.image { - width: 100%; +.image-container { + display: flex; + flex-direction: column; height: 100%; - object-fit: contain; + gap: var(--dui-spacing-extra-small); + + .image { + flex-grow: 1; + width: 100%; + max-height: 100%; + object-fit: contain; + } + + .caption { + flex-shrink: 0; + text-align: center; + } } diff --git a/app/components/report/ReportBuilder/ReportContainer/index.tsx b/app/components/report/ReportBuilder/ReportContainer/index.tsx index 02b8f60e44..704eb42af4 100644 --- a/app/components/report/ReportBuilder/ReportContainer/index.tsx +++ b/app/components/report/ReportBuilder/ReportContainer/index.tsx @@ -46,6 +46,7 @@ import { type ReportContainerType, type ContentDataType, type ContainerStyleFormType, + type ConfigType, } from '../../schema'; import ContentAddModal from './ContentAddModal'; @@ -83,6 +84,7 @@ export interface Props { error: Error | undefined; contentType: AnalysisReportContainerContentTypeEnum | undefined; configuration: ContentConfigType | undefined; + generalConfiguration: ConfigType | undefined; setFieldValue: ((...entries: EntriesAsList) => void); contentDataToFileMap: ContentDataFileMap | undefined; style: ContainerStyleFormType | undefined; @@ -114,6 +116,7 @@ function ReportContainer(props: Props) { contentDataToFileMap, setContentDataToFileMap, disabled, + generalConfiguration, isBeingEdited, onContentEditChange, leftContentRef, @@ -342,7 +345,7 @@ function ReportContainer(props: Props) { const isErrored = analyzeErrors(error); - const containerStyles = resolveContainerStyle(style); + const containerStyles = resolveContainerStyle(style, generalConfiguration?.containerStyle); const heading = useMemo(() => { if (contentType !== 'HEADING') { @@ -442,6 +445,7 @@ function ReportContainer(props: Props) { diff --git a/app/components/report/ReportBuilder/ReportContainer/styles.css b/app/components/report/ReportBuilder/ReportContainer/styles.css index 33fc5b793a..3a6fc61230 100644 --- a/app/components/report/ReportBuilder/ReportContainer/styles.css +++ b/app/components/report/ReportBuilder/ReportContainer/styles.css @@ -79,7 +79,7 @@ */ &:hover { - border-color: var(--dui-color-accent); + border-color: var(--dui-color-accent)!important; /* .mask { diff --git a/app/components/report/ReportBuilder/index.tsx b/app/components/report/ReportBuilder/index.tsx index fe34fc2bd1..2cf6ad19ad 100644 --- a/app/components/report/ReportBuilder/index.tsx +++ b/app/components/report/ReportBuilder/index.tsx @@ -1,6 +1,7 @@ import React, { useState, useMemo, useCallback } from 'react'; import { _cs, + isDefined, listToMap, } from '@togglecorp/fujs'; import { @@ -131,6 +132,7 @@ function ReportBuilder(props: Props) { contentData: item?.contentData, configuration: item.contentConfiguration, contentType: item.contentType, + generalConfiguration: value?.configuration, leftContentRef, style: item.style, reportId, @@ -151,6 +153,7 @@ function ReportBuilder(props: Props) { leftContentRef, error, value?.containers, + value?.configuration, setFieldValue, readOnly, disabled, @@ -163,6 +166,8 @@ function ReportBuilder(props: Props) { )) ), [error]); + const gap = value?.configuration?.bodyStyle?.gap; + return (
- {setFieldValue && containerToEdit === 'metadata' && leftContentRef?.current && ( + {containerToEdit === 'metadata' && leftContentRef?.current && ( | undefined, + generalTextStyle: PurgeNull | undefined, ): React.CSSProperties { - if (!textStyle) { + if (!textStyle && !generalTextStyle) { return {}; } @@ -91,12 +103,23 @@ export function resolveTextStyle( size, } = textStyle ?? {}; + const { + align: generalAlign, + color: generalColor, + family: generalFamily, + weight: generalWeight, + size: generalSize, + } = generalTextStyle ?? {}; + + const textAlign = align ? alignStyleToValueMap[align] : undefined; + const generalTextAlign = generalAlign ? alignStyleToValueMap[generalAlign] : undefined; + return { - textAlign: align ? alignStyleToValueMap[align] : undefined, - color, - fontFamily: family, - fontWeight: weight, - fontSize: size, + textAlign: textAlign ?? generalTextAlign, + color: color ?? generalColor, + fontFamily: family ?? generalFamily, + fontWeight: weight ?? generalWeight, + fontSize: size ?? generalSize, }; } diff --git a/app/views/PublicReportView/index.tsx b/app/views/PublicReportView/index.tsx index ff650e2b4d..8f363b04c5 100644 --- a/app/views/PublicReportView/index.tsx +++ b/app/views/PublicReportView/index.tsx @@ -73,6 +73,77 @@ const PUBLIC_REPORT_DETAILS = gql` shortName } } + configuration { + containerStyle { + border { + width + color + opacity + style + } + padding { + top + bottom + left + right + } + background { + color + opacity + } + } + textContentStyle { + content { + align + color + family + size + weight + } + } + imageContentStyle { + caption { + align + color + family + size + weight + } + } + headingContentStyle { + h1 { + align + color + family + size + weight + } + h2 { + align + color + family + size + weight + } + h3 { + align + color + family + size + weight + } + h4 { + align + color + family + size + weight + } + } + bodyStyle { + gap + } + } containers { id clientId diff --git a/app/views/ReportEdit/index.tsx b/app/views/ReportEdit/index.tsx index 50abdd82e8..e33518f620 100644 --- a/app/views/ReportEdit/index.tsx +++ b/app/views/ReportEdit/index.tsx @@ -133,6 +133,47 @@ const REPORT_DETAILS = gql` organizations { ...OrganizationGeneralResponse } + configuration { + containerStyle { + border { + ...BorderStyle + } + padding { + ...PaddingStyle + } + background { + color + opacity + } + } + textContentStyle { + content { + ...TextStyle + } + } + imageContentStyle { + caption { + ...TextStyle + } + } + headingContentStyle { + h1 { + ...TextStyle + } + h2 { + ...TextStyle + } + h3 { + ...TextStyle + } + h4 { + ...TextStyle + } + } + bodyStyle { + gap + } + } containers { id clientId diff --git a/schema.graphql b/schema.graphql index 224ad193a4..c096d64a74 100644 --- a/schema.graphql +++ b/schema.graphql @@ -244,6 +244,25 @@ type ReportContainer { modifiedAt: String } +type GeneralHeadingContentStyle { + h1: TextStyle + h2: TextStyle + h3: TextStyle + h4: TextStyle +} + +type BodyStyleConfig { + gap: Int +} + +type GeneralConfiguration { + containerStyle: ReportContainerStyle + textContentStyle: TextConfigurationStyleType + imageContentStyle: ImageConfigurationStyleType + headingContentStyle: GeneralHeadingContentStyle + bodyStyle: BodyStyleConfig +} + type PublicReportDetails { id: String! analysis: String! @@ -252,6 +271,7 @@ type PublicReportDetails { slug: String! organizations: [Organization!] containers: [ReportContainer!] + configuration: GeneralConfiguration isPublic: Boolean modifiedAt: String }