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

Reduces re-renderings when loading documentation #30

Merged
merged 3 commits into from
Oct 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
const nextConfig = {
eslint: {
// Allows production builds to successfully complete even if it has linting errors.
// This is only OK bevause we do linting as part of our CI setup.
// This is only OK because we do linting as part of our CI setup.
ignoreDuringBuilds: true,
}
}
Expand Down
3 changes: 0 additions & 3 deletions src/common/client/startup.ts

This file was deleted.

10 changes: 0 additions & 10 deletions src/common/events/BaseEvent.ts

This file was deleted.

12 changes: 0 additions & 12 deletions src/common/events/OpenApiSpecificationChangedEvent.ts

This file was deleted.

11 changes: 0 additions & 11 deletions src/common/events/ProjectChangedEvent.ts

This file was deleted.

7 changes: 0 additions & 7 deletions src/common/events/SettingsChangedEvent.ts

This file was deleted.

11 changes: 0 additions & 11 deletions src/common/events/VersionChangedEvent.ts

This file was deleted.

18 changes: 0 additions & 18 deletions src/common/events/utils.ts

This file was deleted.

21 changes: 1 addition & 20 deletions src/features/projects/domain/projectNavigator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,26 +34,7 @@ const projectNavigator = {
router: IProjectRouter
) {
router.push(`/${selection.project.id}/${selection.version.id}/${specificationId}`)
},
navigateToCurrentSelection(
candidateSelection: {
projectId?: string,
versionId?: string,
specificationId?: string
},
actualSelection: ProjectPageSelection,
router: IProjectRouter
) {
if (
actualSelection.project.id != candidateSelection.projectId ||
actualSelection.version.id != candidateSelection.versionId ||
actualSelection.specification.id != candidateSelection.specificationId
) {
router.replace(
`/${actualSelection.project.id}/${actualSelection.version.id}/${actualSelection.specification.id}`
)
}
}
}
}

export default projectNavigator
13 changes: 8 additions & 5 deletions src/features/projects/view/ProjectList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,20 @@ import ProjectListItem from "./ProjectListItem"
import ProjectListItemPlaceholder from "./ProjectListItemPlaceholder"
import IProject from "../domain/IProject"

interface ProjectListProps<ProjectType extends IProject> {
interface ProjectListProps {
readonly isLoading: boolean
readonly projects: ProjectType[]
readonly projects: IProject[]
readonly selectedProjectId?: string
readonly onSelectProject: (project: IProject) => void
}

const ProjectList = <ProjectType extends IProject>(
const ProjectList = (
{
isLoading,
projects,
selectedProjectId
}: ProjectListProps<ProjectType>
selectedProjectId,
onSelectProject
}: ProjectListProps
) => {
const loadingItemCount = 6
if (isLoading || projects.length > 0) {
Expand All @@ -33,6 +35,7 @@ const ProjectList = <ProjectType extends IProject>(
key={project.id}
project={project}
isSelected={project.id === selectedProjectId}
onSelectProject={onSelectProject}
/>
))}
</List>
Expand Down
8 changes: 4 additions & 4 deletions src/features/projects/view/ProjectListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import { useRouter } from "next/navigation"
import { ListItem, ListItemButton, ListItemText, Typography } from "@mui/material"
import IProject from "../domain/IProject"
import ProjectAvatar from "./ProjectAvatar"

interface ProjectListItemProps<ProjectType extends IProject> {
readonly project: ProjectType
readonly isSelected: boolean
readonly onSelectProject: (project: IProject) => void
}

const ProjectListItem = <ProjectType extends IProject>(
{
project,
isSelected
isSelected,
onSelectProject
}: ProjectListItemProps<ProjectType>
) => {
const router = useRouter()
return (
<ListItem disablePadding>
<ListItemButton
onClick={() => router.push(`/${project.id}`)}
onClick={() => onSelectProject(project)}
selected={isSelected}
sx={{
paddingLeft: "15px",
Expand Down
16 changes: 7 additions & 9 deletions src/features/projects/view/ProjectsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import SidebarContainer from "@/common/SidebarContainer"
import ProjectList from "./ProjectList"
import ProjectsPageSecondaryContent from "./ProjectsPageSecondaryContent"
import ProjectsPageTrailingToolbarItem from "./ProjectsPageTrailingToolbarItem"
import useProjects from "../data/useProjects"
import IProject from "../domain/IProject"
import { getProjectPageState } from "../domain/ProjectPageState"
import projectNavigator from "../domain/projectNavigator"
import useProjects from "../data/useProjects"

interface ProjectsPageProps {
readonly projectId?: string
Expand All @@ -28,14 +29,10 @@ export default function ProjectsPage(
selectedVersionId: versionId,
selectedSpecificationId: specificationId
})
// Ensure the URL reflects the current selection of project, version, and specification.
if (stateContainer.selection) {
const candidateSelection = { projectId, versionId, specificationId }
projectNavigator.navigateToCurrentSelection(
candidateSelection,
stateContainer.selection,
router
)
const handleProjectSelected = (project: IProject) => {
const version = project.versions[0]
const specification = version.specifications[0]
router.push(`/${project.id}/${version.id}/${specification.id}`)
}
return (
<SidebarContainer
Expand All @@ -44,6 +41,7 @@ export default function ProjectsPage(
isLoading={isLoading}
projects={projects}
selectedProjectId={stateContainer.selection?.project.id}
onSelectProject={handleProjectSelected}
/>
}
secondary={
Expand Down
25 changes: 6 additions & 19 deletions src/features/projects/view/docs/DocumentationViewer.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,14 @@
import { useEffect } from "react"
import { Events } from "@/common/events/BaseEvent"
import { subscribe, unsubscribe } from "@/common/events/utils"
import { useForceUpdate } from "@/common/useForceUpdate"
import { settingsStore } from "@/common/client/startup"
import Swagger from "./Swagger"
import Redocly from "./Redocly"
import DocumentationVisualizer from "@/features/settings/domain/DocumentationVisualizer"
import useDocumentationVisualizer from "@/features/settings/data/useDocumentationVisualizer"

const DocumentationViewer: React.FC<{ url: string }> = ({ url }) => {
const forceUpdate = useForceUpdate()
const visualizer = settingsStore.documentationVisualizer

useEffect(() => {
subscribe(Events.SETTINGS_CHANGED, forceUpdate)
return () => {
unsubscribe(Events.SETTINGS_CHANGED, forceUpdate)
}
})

switch (visualizer.toString()) {
case DocumentationVisualizer.SWAGGER.toString():
const DocumentationViewer = ({ url }: { url: string }) => {
const [documentationVisualizer] = useDocumentationVisualizer()
switch (documentationVisualizer) {
case DocumentationVisualizer.SWAGGER:
return <Swagger url={url} />
case DocumentationVisualizer.REDOCLY.toString():
case DocumentationVisualizer.REDOCLY:
return <Redocly url={url} />
}
}
Expand Down
36 changes: 0 additions & 36 deletions src/features/settings/data/SettingsStore.ts

This file was deleted.

6 changes: 6 additions & 0 deletions src/features/settings/data/useDocumentationVisualizer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { useLocalStorage } from "usehooks-ts"
import DocumentationVisualizer from "@/features/settings/domain/DocumentationVisualizer"

export default function useDocumentationVisualizer() {
return useLocalStorage("documentationVisualizer", DocumentationVisualizer.SWAGGER)
}
5 changes: 0 additions & 5 deletions src/features/settings/domain/ISettingsStore.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,32 +1,28 @@
import { useState } from "react"
import { ToggleButtonGroup, ToggleButton } from "@mui/material"
import DocumentationVisualizer from "../domain/DocumentationVisualizer"
import { settingsStore } from "@/common/client/startup"
import useDocumentationVisualizer from "@/features/settings/data/useDocumentationVisualizer"

const DocumentationVisualizationPicker: React.FC = () => {
const [value, setValue] = useState(settingsStore.documentationVisualizer)
const [value, setValue] = useDocumentationVisualizer()
const handleChange = (
_event: React.MouseEvent<HTMLElement>,
documentationVisualizer: DocumentationVisualizer
) => {
setValue(documentationVisualizer)
setTimeout(() => {
settingsStore.documentationVisualizer = documentationVisualizer
})
}
return (
<ToggleButtonGroup
exclusive
value={value.toString()}
value={value}
onChange={handleChange}
fullWidth={true}
color="secondary"
aria-label="Viewer"
>
<ToggleButton value={DocumentationVisualizer.SWAGGER.toString()}>
<ToggleButton value={DocumentationVisualizer.SWAGGER}>
Swagger
</ToggleButton>
<ToggleButton value={DocumentationVisualizer.REDOCLY.toString()}>
<ToggleButton value={DocumentationVisualizer.REDOCLY}>
Redocly
</ToggleButton>
</ToggleButtonGroup>
Expand Down