Skip to content

Commit

Permalink
feat: Update content layout and allow users to config theme (#123)
Browse files Browse the repository at this point in the history
* feat: Update content layout and allow users to config theme

* chore: Fix the content layout title

* chore: Add window api for returning current workspace data in markdown format

* chore: Update to not to use localstorage for ide-extension mode
  • Loading branch information
jessieweiyi authored Jul 4, 2024
1 parent 384ae90 commit 9c7a32e
Show file tree
Hide file tree
Showing 33 changed files with 580 additions and 319 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import AppLayoutComponent, {
AppLayoutProps as AppLayoutComponentProps,
} from '@cloudscape-design/components/app-layout';
import Box from '@cloudscape-design/components/box';
import BreadcrumbGroup, { BreadcrumbGroupProps } from '@cloudscape-design/components/breadcrumb-group';
import { CancelableEventHandler } from '@cloudscape-design/components/internal/events';
import SideNavigation, { SideNavigationProps } from '@cloudscape-design/components/side-navigation';
Expand Down Expand Up @@ -163,19 +162,15 @@ const AppLayout: FC<PropsWithChildren<AppLayoutProps>> = ({
'navigation' in props ? (
props.navigation
) : (
<div>
<SideNavigation
header={{ text: title, href: headerHref }}
activeHref={activeHref}
onFollow={onNavigate}
items={props.navigationItems}
/>
</div>
<SideNavigation
header={{ text: title, href: headerHref }}
activeHref={activeHref}
onFollow={onNavigate}
items={props.navigationItems}
/>
)
}
content={
!contentType || contentType === 'default' ? <Box padding={{ top: 'l' }}>{children}</Box> : children
}
content={children}
{...props}
contentType={contentType}
notifications={notifications}
Expand Down
5 changes: 3 additions & 2 deletions packages/threat-composer-app/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,16 @@ import reportWebVitals from './reportWebVitals';
import * as serviceWorkerRegistration from './serviceWorkerRegistration';
import isMemoryRouterUsed from './utils/isMemoryRouterUsed';

//For the ide-extension, the theme can be set via meta tag.
const initialThemeString = (document.querySelector('meta[name="dark-mode"]') as HTMLMetaElement)?.content;

const initialTheme = initialThemeString ?
let initialTheme = initialThemeString ?
(initialThemeString === 'true' ? Mode.Dark : Mode.Light) :
undefined;

ReactDOM.render(
<React.StrictMode>
<ThemeProvider theme={initialTheme}>
<ThemeProvider theme={initialTheme} appMode={process.env.REACT_APP_APP_MODE || undefined}>
<App />
</ThemeProvider>
</React.StrictMode>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import SpaceBetween from '@cloudscape-design/components/space-between';
import { FC, useState, useCallback, useMemo, useEffect } from 'react';
import { useApplicationInfoContext } from '../../../contexts/ApplicationContext/context';
import { ApplicationInfoSchema, EditableComponentBaseProps } from '../../../customTypes';
import ContentLayout from '../../generic/ContentLayout';
import Input from '../../generic/Input';
import MarkdownEditor from '../../generic/MarkdownEditor';
import MarkdownViewer from '../../generic/MarkdownViewer';
Expand All @@ -30,7 +31,7 @@ const ApplicationInfo: FC<EditableComponentBaseProps> = ({
MarkdownEditorComponentType = MarkdownEditor,
}) => {
const { applicationInfo, setApplicationInfo } = useApplicationInfoContext();
const [editMode, setEditMode] = useState(!applicationInfo.name && !applicationInfo.description );
const [editMode, setEditMode] = useState(!applicationInfo.name && !applicationInfo.description);
const [content, setContent] = useState('');
const [name, setName] = useState('');

Expand Down Expand Up @@ -60,33 +61,35 @@ const ApplicationInfo: FC<EditableComponentBaseProps> = ({
</SpaceBetween>) : (<Button onClick={handleEdit}>Edit</Button>);
}, [editMode, handleSaveApplicationInfo, handleEdit, setEditMode]);

return (<Container
header={<Header actions={actions}>{applicationInfo.name || 'Application Introduction'}</Header>}
>{editMode ? (<SpaceBetween direction='vertical' size='s'>
<FormField
label="Application name"
>
<Input
value={name}
onChange={event =>
setName(event.detail.value)
}
validateData={ApplicationInfoSchema.shape.name.safeParse}
placeholder='Enter application name'
return (<ContentLayout title='Application information'>
<Container
header={<Header actions={actions}>{applicationInfo.name || 'Application Introduction'}</Header>}
>{editMode ? (<SpaceBetween direction='vertical' size='s'>
<FormField
label="Application name"
>
<Input
value={name}
onChange={event =>
setName(event.detail.value)
}
validateData={ApplicationInfoSchema.shape.name.safeParse}
placeholder='Enter application name'
/>
</FormField>
<MarkdownEditorComponentType
value={content}
onChange={setContent}
label='Description'
parentHeaderLevel='h2'
validateData={ApplicationInfoSchema.shape.description.safeParse}
/>
</FormField>
<MarkdownEditorComponentType
value={content}
onChange={setContent}
label='Description'
parentHeaderLevel='h2'
validateData={ApplicationInfoSchema.shape.description.safeParse}
/>
</SpaceBetween>) :
(<MarkdownViewer>
{applicationInfo.description || ''}
</MarkdownViewer>)}
</Container>);
</SpaceBetween>) :
(<MarkdownViewer>
{applicationInfo.description || ''}
</MarkdownViewer>)}
</Container>
</ContentLayout>);
};

export default ApplicationInfo;
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ import BaseDiagramInfo from '../../generic/BaseDiagramInfo';

const ArchitectureInfo: FC<EditableComponentBaseProps> = (props) => {
const { architectureInfo, setArchitectureInfo } = useArchitectureInfoContext();
return <BaseDiagramInfo
{...props}
headerTitle='Architecture'
diagramTitle='Architecture Diagram'
entity={architectureInfo}
onConfirm={(diagram) => setArchitectureInfo(diagram)}
validateData={ArchitectureInfoSchema.shape.description.safeParse}
/>;
return (
<BaseDiagramInfo
{...props}
headerTitle='Architecture'
diagramTitle='Architecture Diagram'
entity={architectureInfo}
onConfirm={(diagram) => setArchitectureInfo(diagram)}
validateData={ArchitectureInfoSchema.shape.description.safeParse}
/>);
};

export default ArchitectureInfo;
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
import Button from '@cloudscape-design/components/button';
import Container from '@cloudscape-design/components/container';
import Grid from '@cloudscape-design/components/grid';
import Header from '@cloudscape-design/components/header';
import SpaceBetween from '@cloudscape-design/components/space-between';
import TextFilter from '@cloudscape-design/components/text-filter';
import { FC, useCallback, useMemo, useState } from 'react';
import { useAssumptionLinksContext } from '../../../contexts';
import { useAssumptionsContext } from '../../../contexts/AssumptionsContext/context';
import { Assumption, AssumptionLink } from '../../../customTypes';
import { addTagToEntity, removeTagFromEntity } from '../../../utils/entityTag';
import ContentLayout from '../../generic/ContentLayout';
import LinkedEntityFilter, { ALL, WITHOUT_NO_LINKED_ENTITY, WITH_LINKED_ENTITY } from '../../generic/LinkedEntityFilter';
import TagSelector from '../../generic/TagSelector';
import AssumptionCard from '../AssumptionCard';
Expand Down Expand Up @@ -158,11 +158,9 @@ const AssumptionList: FC = () => {

}, [saveAssumption, addAssumptionLinks]);

return (<div>
return (<ContentLayout title='Assumptions' counter={`(${filteredList.length})`}>
<SpaceBetween direction='vertical' size='s'>
<Container header={
<Header counter={`(${filteredList.length})`}>Assumption List</Header>
}>
<Container>
<SpaceBetween direction='vertical' size='s'>
<TextFilter
filteringText={filteringText}
Expand Down Expand Up @@ -225,7 +223,7 @@ const AssumptionList: FC = () => {
onSave={handleSaveNew}
/>
</SpaceBetween>
</div>);
</ContentLayout>);
};

export default AssumptionList;
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import SpaceBetween from '@cloudscape-design/components/space-between';
import { FC, useCallback, useState, useMemo, useEffect } from 'react';
import { BaseImageInfo, EditableComponentBaseProps } from '../../../customTypes';
import imageStyles from '../../../styles/image';
import ContentLayout from '../../generic/ContentLayout';
import ImageEdit from '../ImageEdit';
import MarkdownEditor, { MarkdownEditorProps } from '../MarkdownEditor';
import MarkdownViewer from '../MarkdownViewer';
Expand Down Expand Up @@ -71,27 +72,32 @@ const BaseDiagramInfo: FC<BaseDiagramInfoProps> = ({
</SpaceBetween>) : (<Button onClick={handleEdit}>Edit</Button>);
}, [editMode, handleSaveDiagramInfo, handleEdit, setEditMode]);

return (<Container header={<Header actions={actions}>{headerTitle}</Header>}>
{editMode ? (<SpaceBetween direction='vertical' size='s'>
<MarkdownEditorComponentType
label='Introduction'
value={content}
onChange={setContent}
parentHeaderLevel='h3'
validateData={validateData}
/>
<Header variant='h3'>{headerTitle} Diagram</Header>
<ImageEdit value={image} onChange={setImage} />
</SpaceBetween>) :
(<SpaceBetween direction='vertical' size='s'>
<Header variant='h3' key='diagramInfo'>Introduction</Header>
<MarkdownViewer>
{entity.description || ''}
</MarkdownViewer>
<Header variant='h3' key='diagram'>{diagramTitle}</Header>
{entity.image && <img css={imageStyles} src={entity.image} alt={diagramTitle} />}
</SpaceBetween>)}
</Container>
return (<ContentLayout
title={headerTitle}
actions={actions}
>
<Container>
{editMode ? (<SpaceBetween direction='vertical' size='s'>
<MarkdownEditorComponentType
label='Introduction'
value={content}
onChange={setContent}
parentHeaderLevel='h3'
validateData={validateData}
/>
<Header variant='h3'>{headerTitle} Diagram</Header>
<ImageEdit value={image} onChange={setImage} />
</SpaceBetween>) :
(<SpaceBetween direction='vertical' size='s'>
<Header variant='h3' key='diagramInfo'>Introduction</Header>
<MarkdownViewer>
{entity.description || ''}
</MarkdownViewer>
<Header variant='h3' key='diagram'>{diagramTitle}</Header>
{entity.image && <img css={imageStyles} src={entity.image} alt={diagramTitle} />}
</SpaceBetween>)}
</Container>
</ContentLayout>
);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/** *******************************************************************************************************************
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
******************************************************************************************************************** */

import ContentLayoutComponent from '@cloudscape-design/components/content-layout';
import Header, { HeaderProps } from '@cloudscape-design/components/header';
import { FC, PropsWithChildren } from 'react';
import { useApplicationInfoContext } from '../../../contexts/ApplicationContext';

export interface ContentLayoutProps extends Omit<HeaderProps, 'info'> {
/**
* The title of the header.
*/
title?: string;
}

const ContentLayout: FC<PropsWithChildren<ContentLayoutProps>> = ({
title,
children,
...props
}) => {
const { applicationInfo } = useApplicationInfoContext();

return (<ContentLayoutComponent
header={<Header
variant="h1"
{...props}
info={applicationInfo.name ? `| ${applicationInfo.name}` : undefined}
>
{title}
</Header>}
>
{children}
</ContentLayoutComponent>);
};

export default ContentLayout;
Loading

0 comments on commit 9c7a32e

Please sign in to comment.