Skip to content

Commit

Permalink
Se/share button (#126)
Browse files Browse the repository at this point in the history
  • Loading branch information
scespinoza authored Nov 13, 2024
2 parents 03a27d3 + 43bed1a commit 0cfcd81
Show file tree
Hide file tree
Showing 11 changed files with 87 additions and 12 deletions.
8 changes: 7 additions & 1 deletion src/components/SelectCubes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,17 @@ function useBuildGraph(items, locale) {
.map(item => {
const {name} = item;
const topic = getAnnotation(item, "topic", locale);
const topic_order = getAnnotation(item, "topic_order", locale);
const subtopic = getAnnotation(item, "subtopic", locale);
const table = getAnnotation(item, "table", locale);
const hide = getAnnotation(item, "hide_in_ui", locale);
console.log(topic, topic_order);
if (!yn(hide)) {
graph.addNode(topic);
if(topic_order) {
console.log(topic, topic_order);
graph.addTopicOrder(topic, topic_order)
};
graph.addNode(subtopic);
graph.addNode(name);
graph.addEdge(topic, subtopic);
Expand Down Expand Up @@ -301,7 +307,7 @@ function RootAccordions({items, graph, locale, selectedItem, onSelectCube}) {
}
})}
>
{items.map(item => {
{items.sort((a, b) => graph.topicOrder[a] - graph.topicOrder[b]).map(item => {
return (
<Accordion.Item value={`topic-${item}`} key={`topic-${item}`}>
<AccordionControl>{item}</AccordionControl>
Expand Down
4 changes: 4 additions & 0 deletions src/hooks/buildGraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export default function useBuildGraph(locale: string): Graph {
.map(item => {
const {name} = item;
const topic = getAnnotation(item, "topic", locale);
const topic_order = getAnnotation(item, "topic_order", locale);
const subtopic = getAnnotation(item, "subtopic", locale);
const table = getAnnotation(item, "table", locale);
const hide = getAnnotation(item, "hide_in_ui", locale);
Expand All @@ -27,6 +28,9 @@ export default function useBuildGraph(locale: string): Graph {
graph.addNode(name);
graph.addEdge(topic, subtopic);
graph.addEdge(subtopic, name);
if(topic_order) {
graph.addTopicOrder(topic, topic_order)
}
return item;
}

Expand Down
15 changes: 12 additions & 3 deletions src/hooks/permalink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ export function serializePermalink(item: QueryItem): string {
Object.entries(request).filter(entry => entry[1] != null && entry[1] !== "")
);
search.set("panel", item.panel || "table");
if (item.chart !== "" && item.chart){
search.set("chart", item.chart)
}
return search.toString();
}

Expand All @@ -22,9 +25,10 @@ export function parsePermalink(cube: TesseractCube, value: string | URLSearchPar
const search = new URLSearchParams(value);

const params = requestToQueryParams(cube, search);

console.log(search.get("chart"));
return buildQuery({
panel: search.get("panel") || "table",
chart: search.get("chart") || "",
params
});
}
Expand Down Expand Up @@ -65,8 +69,12 @@ export function usePermalink(
if (currPermalink !== nextPermalink) {
const nextLocation = `${window.location.pathname}?${nextPermalink}`;
const oldPanel = new URLSearchParams(window.location.search).get("panel");
// If only the panel changed, use replaceState
if (oldPanel && oldPanel[1] !== panel) {
const oldChart = new URLSearchParams(window.location.search).get("chart");
// If only the panel or chartchanged, use replaceState
if (
(oldPanel && oldPanel[1] !== panel)
|| (oldChart && oldChart[1] !== queryItem.chart)
) {
window.history.replaceState(queryItem, "", nextLocation);
} else {
window.history.pushState(queryItem, "", nextLocation);
Expand Down Expand Up @@ -103,6 +111,7 @@ export function useUpdatePermaLink({

export function useKey(params: Partial<QueryParams> = {}) {
const queryItem = useSelector(selectCurrentQueryItem);
console.log(queryItem);
if (isValidQuery(queryItem.params)) {
return serializePermalink({...queryItem, params: {...queryItem.params, ...params}});
}
Expand Down
2 changes: 2 additions & 0 deletions src/hooks/translation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,8 @@ export const defaultTranslation = {
},
vizbuilder: {
action_close: "Close",
action_share: "Share",
share_copied: "Copied",
action_enlarge: "Enlarge",
action_fileissue: "Report an issue",
action_retry: "Retry",
Expand Down
5 changes: 5 additions & 0 deletions src/state/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ export const queriesSlice = createSlice({
const current = state.itemMap[state.current];
current.panel = action.payload;
},

updateChart(state, action: Action<string | null>) {
const current = state.itemMap[state.current];
current.chart = action.payload;
},

/**
* Remove a single CutItem from the current QueryItem.
Expand Down
1 change: 1 addition & 0 deletions src/state/thunks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ export function willParseQueryUrl(url: string | URL): ExplorerThunk<Promise<void

const queryItem = buildQuery({
panel: search.get("panel") || "table",
chart: search.get("chart") || "",
// params: {...params, drilldowns: keyBy(dds, "key")}
params
});
Expand Down
9 changes: 9 additions & 0 deletions src/utils/graph.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ class Graph {
this.nodes = new Set([]);
this.adjList = {};
this.items = [];
this.topicOrder = {};
}

addTopicOrder(topic, order) {
this.topicOrder[topic] = Number(order);
}

getTopicOrder(topic) {
return this.topicOrder[topic] || 0;
}

addNode(node) {
Expand Down
2 changes: 2 additions & 0 deletions src/utils/structs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export interface QueryItem {
key: string;
label: string;
panel: string | null;
chart: string | null;
params: QueryParams;
result: QueryResult;
}
Expand Down Expand Up @@ -128,6 +129,7 @@ export function buildQuery(props: RecursivePartial<QueryItem>): QueryItem {
label: props.label || "",
isDirty: true,
panel: props.panel || null,
chart: props.chart || null,
params: buildQueryParams(props.params || {}),
result: {
data: [],
Expand Down
31 changes: 30 additions & 1 deletion src/vizbuilder/components/ChartCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,20 @@ import {Box, Button, Group, Paper, Stack} from "@mantine/core";
import {
IconArrowsMaximize,
IconArrowsMinimize,
IconCheck,
IconDownload,
IconPhotoDown,
IconShare,
IconVectorTriangle,
} from "@tabler/icons-react";
import {saveElement} from "d3plus-export";
import React, {useMemo, useRef} from "react";
import React, {useMemo, useRef, useState} from "react";
import type {TesseractMeasure} from "../../api/tesseract/schema";
import {useTranslation} from "../../hooks/translation";
import {asArray as castArray} from "../../utils/array";
import {useD3plusConfig} from "../hooks/useD3plusConfig";
import {ErrorBoundary} from "./ErrorBoundary";
import {useClipboard} from '@mantine/hooks';

const iconByFormat = {
jpg: IconPhotoDown,
Expand Down Expand Up @@ -66,6 +69,10 @@ export function ChartCard(props: {
t: translate,
});

const clipboard = useClipboard();

const [isShared, setIsShared] = useState(false);

const downloadButtons = useMemo(() => {
// Sanitize filename for Windows and Unix
const filename = (
Expand Down Expand Up @@ -119,6 +126,27 @@ export function ChartCard(props: {
);
}, [isFullMode, translate, onFocus]);

const shareButton = useMemo(() => {
return (
<Button
compact
leftIcon={isShared ? <IconCheck size={16} /> : <IconShare size={16} />}
onClick={() => {
clipboard.copy(window.location.href);
setIsShared(true);
setTimeout(() => setIsShared(false), 1500);
}}
size="sm"
variant={isShared ? "filled" : "light"}
color={isShared ? "green" : "blue"}
>
{isShared
? translate("vizbuilder.share_copied")
: translate("vizbuilder.action_share")}
</Button>
);
}, [clipboard, translate, isShared]);

const height = isFullMode ? "calc(100vh - 3rem)" : 300;

if (!ChartComponent) return null;
Expand All @@ -128,6 +156,7 @@ export function ChartCard(props: {
<ErrorBoundary>
<Stack spacing={0} h={height} style={{position: "relative"}} w="100%">
<Group position="right" p="xs" spacing="xs" align="center">
{isFullMode && shareButton}
{downloadButtons}
{onFocus && focusButton}
</Group>
Expand Down
20 changes: 14 additions & 6 deletions src/vizbuilder/components/Vizbuilder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@ import {
} from "@datawheel/vizbuilder";
import {Modal, SimpleGrid} from "@mantine/core";
import cls from "clsx";
import React, {useCallback, useMemo, useState} from "react";
import React, {useCallback, useMemo} from "react";
import type {TesseractLevel, TesseractMeasure} from "../../api/tesseract/schema";
import {asArray as castArray} from "../../utils/array";
import {ChartCard} from "./ChartCard";
import {ErrorBoundary} from "./ErrorBoundary";
import {NonIdealState} from "./NonIdealState";
import {useSelector} from "react-redux";
import {selectCurrentQueryItem} from "../../state/queries";
import {useSettings} from "../../hooks/settings";

export type VizbuilderProps = React.ComponentProps<typeof Vizbuilder>;

Expand Down Expand Up @@ -125,7 +128,13 @@ export function Vizbuilder(props: {
userConfig,
} = props;

const [currentChart, setCurrentChart] = useState("");
const queryItem = useSelector(selectCurrentQueryItem);
const currentChart = queryItem?.chart || "";
const {actions} = useSettings();

const setCurrentChart = useCallback((chart: string) => {
actions.updateChart(chart);
}, [actions]);

// Normalize measureConfig to function type
const getMeasureConfig = useMemo(() => {
Expand All @@ -142,15 +151,14 @@ export function Vizbuilder(props: {
// Compute possible charts
const charts = useMemo(() => {
const charts = generateCharts(castArray(datasets), {
chartLimits,
chartLimits: chartLimits as ChartLimits | undefined,
chartTypes,
datacap,
getTopojsonConfig,
});
return Object.fromEntries(charts.map(chart => [chart.key, chart]));
}, [chartLimits, chartTypes, datacap, datasets, getTopojsonConfig]);

console.log("charts", charts);
const content = useMemo(() => {
const Notice = nonIdealState || NonIdealState;

Expand Down Expand Up @@ -183,7 +191,7 @@ export function Vizbuilder(props: {
<ChartCard
key={chart.key}
chart={chart}
downloadFormats={downloadFormats}
downloadFormats={downloadFormats as string[] | undefined}
measureConfig={getMeasureConfig}
onFocus={() => setCurrentChart(chart.key)}
showConfidenceInt={showConfidenceInt}
Expand Down Expand Up @@ -212,7 +220,7 @@ export function Vizbuilder(props: {
<ChartCard
key={`${chart.key}-focus`}
chart={chart}
downloadFormats={downloadFormats}
downloadFormats={downloadFormats as string[] | undefined}
measureConfig={getMeasureConfig}
onFocus={() => setCurrentChart("")}
showConfidenceInt={showConfidenceInt}
Expand Down
2 changes: 1 addition & 1 deletion src/vizbuilder/hooks/useD3plusConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ function _buildTitle(t: TranslateFunction, chart: Chart) {
const [mainSeries, otherSeries] = series;
const {measure} = values;
const timeline = chart.timeline || chart.time;
console.log({chart})

const seriesStr = (series: Chart["series"][number]) => {
if(!series) return "";
const {members} = series.captions[series.level.name];
Expand Down

0 comments on commit 0cfcd81

Please sign in to comment.