Skip to content

Commit

Permalink
🎉 (grapher) make charts inherit indicator-level settings
Browse files Browse the repository at this point in the history
  • Loading branch information
sophiamersmann committed Jul 23, 2024
1 parent 689d9e8 commit cbdb440
Show file tree
Hide file tree
Showing 36 changed files with 1,939 additions and 829 deletions.
99 changes: 99 additions & 0 deletions adminSiteClient/AbstractChartEditor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import {
isEqual,
omit,
GrapherInterface,
diffGrapherConfigs,
mergeGrapherConfigs,
} from "@ourworldindata/utils"
import { computed, observable, when } from "mobx"
import { EditorFeatures } from "./EditorFeatures.js"
import { Admin } from "./Admin.js"
import { defaultGrapherConfig, Grapher } from "@ourworldindata/grapher"

export type EditorTab =
| "basic"
| "data"
| "text"
| "customize"
| "map"
| "scatter"
| "marimekko"
| "revisions"
| "refs"
| "export"

export interface AbstractChartEditorManager {
admin: Admin
patchConfig: GrapherInterface
parentConfig?: GrapherInterface
}

export abstract class AbstractChartEditor<
Manager extends AbstractChartEditorManager = AbstractChartEditorManager,
> {
manager: Manager

@observable.ref grapher = new Grapher()
@observable.ref currentRequest: Promise<any> | undefined // Whether the current chart state is saved or not
@observable.ref tab: EditorTab = "basic"
@observable.ref errorMessage?: { title: string; content: string }
@observable.ref previewMode: "mobile" | "desktop"
@observable.ref showStaticPreview = false
@observable.ref savedPatchConfig: GrapherInterface = {}
@observable.ref parentConfig: GrapherInterface | undefined = undefined

constructor(props: { manager: Manager }) {
this.manager = props.manager
this.previewMode =
localStorage.getItem("editorPreviewMode") === "mobile"
? "mobile"
: "desktop"

when(
() => this.manager.parentConfig !== undefined,
() => (this.parentConfig = this.manager.parentConfig)
)

when(
() => this.grapher.isReady,
() => (this.savedPatchConfig = this.patchConfig)
)
}

@computed get grapherConfig(): GrapherInterface {
const { patchConfig, parentConfig } = this.manager
if (!parentConfig) return patchConfig
return mergeGrapherConfigs(parentConfig, patchConfig)
}

@computed get liveConfig(): GrapherInterface {
return this.grapher.object
}

@computed get patchConfig(): GrapherInterface {
const { liveConfig, parentConfig } = this
if (!parentConfig) return liveConfig
// TODO: explain
const liveConfigWithDefaults = mergeGrapherConfigs(
defaultGrapherConfig,
liveConfig
)
return diffGrapherConfigs(liveConfigWithDefaults, parentConfig)
}

@computed get isModified(): boolean {
return !isEqual(
omit(this.patchConfig, "version"),
omit(this.savedPatchConfig, "version")
)
}

@computed get features(): EditorFeatures {
return new EditorFeatures(this)
}

abstract get isNewGrapher(): boolean
abstract get availableTabs(): EditorTab[]

abstract saveGrapher(props?: { onError?: () => void }): Promise<void>
}
12 changes: 12 additions & 0 deletions adminSiteClient/AdminApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import { BulkGrapherConfigEditorPage } from "./BulkGrapherConfigEditor.js"
import { GdocsIndexPage, GdocsMatchProps } from "./GdocsIndexPage.js"
import { GdocsPreviewPage } from "./GdocsPreviewPage.js"
import { GdocsStoreProvider } from "./GdocsStore.js"
import { IndicatorChartEditorPage } from "./IndicatorChartEditorPage.js"

@observer
class AdminErrorMessage extends React.Component<{ admin: Admin }> {
Expand Down Expand Up @@ -154,6 +155,17 @@ export class AdminApp extends React.Component<{
path="/charts"
component={ChartIndexPage}
/>
<Route
exact
path="/indicator-charts/:variableId/edit"
render={({ match }) => (
<IndicatorChartEditorPage
variableId={parseInt(
match.params.variableId
)}
/>
)}
/>
<Route
exact
path={`/${EXPLORERS_ROUTE_FOLDER}/:slug`}
Expand Down
Loading

0 comments on commit cbdb440

Please sign in to comment.