Skip to content

Commit

Permalink
🚧 Temporary optimistic merge of several features branches during the …
Browse files Browse the repository at this point in the history
…christmas period
  • Loading branch information
danyx23 committed Jan 9, 2025
3 parents e954517 + 3cc565e + d69d129 commit cdde7f4
Show file tree
Hide file tree
Showing 83 changed files with 5,227 additions and 4,078 deletions.
2 changes: 1 addition & 1 deletion adminSiteClient/AdminSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export const AdminSidebar = (): React.ReactElement => (
{chartViewsFeatureEnabled && (
<li>
<Link to="/chartViews">
<FontAwesomeIcon icon={faPanorama} /> Narrative views
<FontAwesomeIcon icon={faPanorama} /> Narrative charts
</Link>
</li>
)}
Expand Down
26 changes: 9 additions & 17 deletions adminSiteClient/ChartEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
getParentVariableIdFromChartConfig,
mergeGrapherConfigs,
isEmpty,
slugify,
omit,
CHART_VIEW_PROPS_TO_OMIT,
} from "@ourworldindata/utils"
Expand Down Expand Up @@ -200,23 +199,13 @@ export class ChartEditor extends AbstractChartEditor<ChartEditorManager> {
)
}

async saveAsNarrativeView(): Promise<void> {
async saveAsChartView(
name: string
): Promise<{ success: boolean; errorMsg?: string }> {
const { patchConfig, grapher } = this

const chartJson = omit(patchConfig, CHART_VIEW_PROPS_TO_OMIT)

const suggestedName = grapher.title ? slugify(grapher.title) : undefined

const name = prompt(
"Please enter a programmatic name for the narrative view. Note that this name cannot be changed later.",
suggestedName
)

if (name === null) return

// Need to open intermediary tab before AJAX to avoid popup blockers
const w = window.open("/", "_blank") as Window

const body = {
name,
parentChartId: grapher.id,
Expand All @@ -228,11 +217,14 @@ export class ChartEditor extends AbstractChartEditor<ChartEditorManager> {
body,
"POST"
)

if (json.success)
w.location.assign(
if (json.success) {
window.open(
this.manager.admin.url(`chartViews/${json.chartViewId}/edit`)
)
return { success: true }
} else {
return { success: false, errorMsg: json.errorMsg }
}
}

publishGrapher(): void {
Expand Down
5 changes: 3 additions & 2 deletions adminSiteClient/ChartViewEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
References,
type EditorTab,
} from "./AbstractChartEditor.js"
import { ENV } from "../settings/clientSettings.js"
import { BAKED_BASE_URL, ENV } from "../settings/clientSettings.js"
import {
CHART_VIEW_PROPS_TO_OMIT,
CHART_VIEW_PROPS_TO_PERSIST,
Expand All @@ -16,7 +16,8 @@ import { diffGrapherConfigs, omit, pick } from "@ourworldindata/utils"
// Don't yet show chart views in the admin interface
// This is low-stakes - if it shows up anyhow (e.g. on staging servers), it's not a big deal.
// TODO: Remove this flag once we're launching this feature
export const chartViewsFeatureEnabled = ENV === "development"
export const chartViewsFeatureEnabled =
ENV === "development" || BAKED_BASE_URL.includes("narrative-")

export interface Chart {
id: number
Expand Down
6 changes: 3 additions & 3 deletions adminSiteClient/ChartViewIndexPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { AdminAppContext } from "./AdminAppContext.js"
import { Timeago } from "./Forms.js"
import { ColumnsType } from "antd/es/table/InternalTable.js"
import { ApiChartViewOverview } from "../adminShared/AdminTypes.js"
import { BAKED_GRAPHER_URL } from "../settings/clientSettings.js"
import { GRAPHER_DYNAMIC_THUMBNAIL_URL } from "../settings/clientSettings.js"
import { Link } from "./Link.js"
import {
buildSearchWordsFromSearchString,
Expand All @@ -28,7 +28,7 @@ function createColumns(
width: 200,
render: (chartConfigId) => (
<img
src={`${BAKED_GRAPHER_URL}/by-uuid/${chartConfigId}.svg`}
src={`${GRAPHER_DYNAMIC_THUMBNAIL_URL}/by-uuid/${chartConfigId}.svg`}
style={{ maxWidth: 200, maxHeight: 200 }}
/>
),
Expand Down Expand Up @@ -135,7 +135,7 @@ export function ChartViewIndexPage() {
}, [admin])

return (
<AdminLayout title="Narrative views">
<AdminLayout title="Narrative charts">
<main className="ChartViewIndexPage">
<Flex justify="space-between">
<Input
Expand Down
2 changes: 1 addition & 1 deletion adminSiteClient/EditorReferencesTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export const ReferencesSection = (props: {

const chartViews = !!props.references?.chartViews?.length && (
<>
<p>Narrative views based on this chart</p>
<p>Narrative charts based on this chart</p>
<ul className="list-group">
{props.references.chartViews.map((chartView) => (
<li key={chartView.id} className="list-group-item">
Expand Down
33 changes: 20 additions & 13 deletions adminSiteClient/EditorTextTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
} from "./Forms.js"
import { AbstractChartEditor } from "./AbstractChartEditor.js"
import { ErrorMessages } from "./ChartEditorTypes.js"
import { isChartViewEditorInstance } from "./ChartViewEditor.js"

@observer
export class EditorTextTab<
Expand Down Expand Up @@ -74,6 +75,10 @@ export class EditorTextTab<
return this.props.errorMessages
}

@computed get showChartSlug() {
return !isChartViewEditorInstance(this.props.editor)
}

@computed get showAnyAnnotationFieldInTitleToggle() {
const { features } = this.props.editor
return (
Expand Down Expand Up @@ -139,19 +144,21 @@ export class EditorTextTab<
/>
)}
{this.showAnyAnnotationFieldInTitleToggle && <hr />}
<AutoTextField
label="/grapher"
value={grapher.displaySlug}
onValue={this.onSlug}
isAuto={grapher.slug === undefined}
onToggleAuto={() =>
(grapher.slug =
grapher.slug === undefined
? grapher.displaySlug
: undefined)
}
helpText="Human-friendly URL for this chart"
/>
{this.showChartSlug && (
<AutoTextField
label="/grapher"
value={grapher.displaySlug}
onValue={this.onSlug}
isAuto={grapher.slug === undefined}
onToggleAuto={() =>
(grapher.slug =
grapher.slug === undefined
? grapher.displaySlug
: undefined)
}
helpText="Human-friendly URL for this chart"
/>
)}
<BindAutoStringExt
label="Subtitle"
readFn={(grapher) => grapher.currentSubtitle}
Expand Down
20 changes: 13 additions & 7 deletions adminSiteClient/ImagesIndexPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -281,12 +281,13 @@ function createColumns({
title: "Filename",
dataIndex: "filename",
key: "filename",
width: 300,
width: 200,
},
{
title: "Alt text",
dataIndex: "defaultAlt",
key: "defaultAlt",
width: "auto",
sorter: (a, b) =>
a.defaultAlt && b.defaultAlt
? a.defaultAlt.localeCompare(b.defaultAlt)
Expand All @@ -309,7 +310,7 @@ function createColumns({
a.originalWidth && b.originalWidth
? a.originalWidth - b.originalWidth
: 0,
width: 100,
width: 50,
},
{
title: "Height",
Expand All @@ -319,13 +320,13 @@ function createColumns({
a.originalHeight && b.originalHeight
? a.originalHeight - b.originalHeight
: 0,
width: 100,
width: 50,
},
{
title: "Last updated",
dataIndex: "updatedAt",
key: "updatedAt",
width: 150,
width: 50,
defaultSortOrder: "descend",
sorter: (a, b) =>
a.updatedAt && b.updatedAt ? a.updatedAt - b.updatedAt : 0,
Expand All @@ -334,7 +335,7 @@ function createColumns({
{
title: "Owner",
key: "userId",
width: 200,
width: 100,
filters: [
{
text: "Unassigned",
Expand Down Expand Up @@ -375,7 +376,7 @@ function createColumns({
{
title: "Action",
key: "action",
width: 100,
width: 50,
render: (_, image) => {
const isDeleteDisabled = !!(usage && usage[image.id]?.length)
return (
Expand Down Expand Up @@ -657,7 +658,12 @@ export function ImageIndexPage() {
/>
<PostImageButton postImage={api.postImage} />
</Flex>
<Table columns={columns} dataSource={filteredImages} />
<Table
size="small"
columns={columns}
dataSource={filteredImages}
rowKey={(x) => x.id}
/>
</main>
</NotificationContext.Provider>
</AdminLayout>
Expand Down
64 changes: 64 additions & 0 deletions adminSiteClient/NarrativeChartNameModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { useEffect, useMemo, useRef, useState } from "react"
import { Form, Input, InputRef, Modal, Spin } from "antd"

export const NarrativeChartNameModal = (props: {
initialName: string
open: "open" | "open-loading" | "closed"
errorMsg?: string
onSubmit: (name: string) => void
onCancel?: () => void
}) => {
const [name, setName] = useState<string>(props.initialName)
const inputField = useRef<InputRef>(null)
const isLoading = useMemo(() => props.open === "open-loading", [props.open])
const isOpen = useMemo(() => props.open !== "closed", [props.open])

useEffect(() => setName(props.initialName), [props.initialName])

useEffect(() => {
if (isOpen) {
inputField.current?.focus({ cursor: "all" })
}
}, [isOpen])

return (
<Modal
title="Save as narrative chart"
open={isOpen}
onOk={() => props.onSubmit(name)}
onCancel={props.onCancel}
onClose={props.onCancel}
okButtonProps={{ disabled: !name || isLoading }}
cancelButtonProps={{ disabled: isLoading }}
>
<div>
<p>
This will create a new narrative chart that is linked to
this chart. Any currently pending changes will be applied to
the narrative chart.
</p>
<p>
Please enter a programmatic name for the narrative chart.{" "}
<i>Note that this name cannot be changed later.</i>
</p>
<Form.Item label="Name">
<Input
ref={inputField}
onChange={(e) => setName(e.target.value)}
value={name}
disabled={isLoading}
/>
</Form.Item>
{isLoading && <Spin />}
{props.errorMsg && (
<div
className="alert alert-danger"
style={{ whiteSpace: "pre-wrap" }}
>
{props.errorMsg}
</div>
)}
</div>
</Modal>
)
}
Loading

0 comments on commit cdde7f4

Please sign in to comment.