opendash
Version:
open.DASH data visualization framework
273 lines (228 loc) • 6.71 kB
text/typescript
import * as React from "react";
import {
useElementSize,
useImmerState,
useDataItems,
WidgetContextInterface,
WidgetBaseContextInterface,
WidgetConfigError,
useTranslation,
DataItemInterface,
useOpenDashServices,
DataItemHistoryOptionsInterface,
SourceInterface,
useSource,
DataItemValueInterface,
} from "..";
import { DataItemIdentifierInterface } from "../interfaces/DataItemIdentifierInterface";
import { DataItemDimensionIdentifierInterface } from "../interfaces/DataItemDimensionIdentifierInterface";
export function useWidgetContextSetup(
context: WidgetBaseContextInterface
): WidgetContextInterface {
const [t] = useTranslation(["opendash"]);
const { DashboardService } = useOpenDashServices();
const [draft, updateDraft, replaceDraft, assignToDraft] = useImmerState({});
React.useEffect(() => {
if (context?.widget?.config) {
replaceDraft(context?.widget?.config);
}
}, [context?.widget?.config]);
function saveDraft() {
DashboardService.updateWidget({
...context.widget,
id: context.id,
config: draft,
});
}
function setLoading(loading: boolean) {
context.setState({ loading });
}
function useContainerSize(): {
width: number;
height: number;
} {
return useElementSize(context.container, 250);
}
function useSourceConfig(): SourceInterface[] {
const type = context?.type.dataItems;
const config = context?.widget.config._sources;
const [, , allSources] = useSource();
if (!type) {
throw new WidgetConfigError(
t("monitoring.widgets.config_error.sources_unsupported")
);
}
if (type.select !== "source") {
throw new WidgetConfigError(
t("monitoring.widgets.config_error.sources_dev_bad_config")
);
}
if (!config) {
throw new WidgetConfigError(
t("monitoring.widgets.config_error.sources_notfound")
);
}
if (config.length > type.max) {
throw new WidgetConfigError(
t("monitoring.widgets.config_error.sources_max")
);
}
if (config.length < type.min) {
throw new WidgetConfigError(
t("monitoring.widgets.config_error.sources_min")
);
}
const sources: SourceInterface[] = config.map(id =>
allSources.find(source => source.id === id)
);
for (const source of sources) {
if (!source) {
throw new WidgetConfigError(
t("monitoring.widgets.config_error.sources_missing")
);
}
}
return sources;
}
function useItemConfig(): DataItemInterface[] {
const type = context?.type.dataItems;
const config = context?.widget.config._items;
const allItems = useDataItems();
if (!type) {
throw new WidgetConfigError(
t("monitoring.widgets.config_error.items_unsupported")
);
}
if (type.select !== "item") {
throw new WidgetConfigError(
t("monitoring.widgets.config_error.items_dev_bad_config")
);
}
if (!config) {
throw new WidgetConfigError(
t("monitoring.widgets.config_error.items_notfound")
);
}
if (config.length > type.max) {
throw new WidgetConfigError(
t("monitoring.widgets.config_error.items_max")
);
}
if (config.length < type.min) {
throw new WidgetConfigError(
t("monitoring.widgets.config_error.items_min")
);
}
const items: DataItemInterface[] = config.map(([source, id]) =>
allItems.find(item => item.id === id && item.source === source)
);
for (const item of items) {
if (!item) {
throw new WidgetConfigError(
t("monitoring.widgets.config_error.items_missing")
);
}
}
return items;
}
function useItemDimensionConfig(): [DataItemInterface, number][] {
const type = context?.type.dataItems;
const config = context?.widget.config._dimensions;
const allItems = useDataItems();
if (!type) {
throw new WidgetConfigError(
t("monitoring.widgets.config_error.items_unsupported")
);
}
if (type.select !== "dimension") {
throw new WidgetConfigError(
t("monitoring.widgets.config_error.items_dev_bad_config")
);
}
if (!config) {
throw new WidgetConfigError(
t("monitoring.widgets.config_error.items_notfound")
);
}
if (config.length > type.max) {
throw new WidgetConfigError(
t("monitoring.widgets.config_error.items_max")
);
}
if (config.length < type.min) {
throw new WidgetConfigError(
t("monitoring.widgets.config_error.items_min")
);
}
const items: [
DataItemInterface,
number
][] = config.map(([source, id, dimension]) => [
allItems.find(item => item.id === id && item.source === source),
dimension,
]);
for (const [item, dimension] of items) {
if (!item) {
throw new WidgetConfigError(
t("monitoring.widgets.config_error.items_missing")
);
}
if (!type.types.includes(item.valueTypes[dimension].type)) {
throw new WidgetConfigError(
t("monitoring.widgets.config_error.items_type")
);
}
}
return items;
}
function useFetchHistory(
overwriteOptions: DataItemHistoryOptionsInterface = {}
): DataItemValueInterface[] {
const allItems = useDataItems();
const itemsToFetch = React.useMemo(() => {
const config: (
| DataItemIdentifierInterface
| DataItemDimensionIdentifierInterface
)[] = [
...(context?.widget.config._items || []),
...(context?.widget.config._dimensions || []),
];
return config.map(([source, id]) =>
allItems.find(item => item.source === source && item.id === id)
);
}, [allItems, context?.widget.config]);
return [];
}
function useHistoryConfig(): DataItemHistoryOptionsInterface {
const type = context?.type.dataHistory;
const config = context?.widget.config._history;
if (!type) {
throw new WidgetConfigError(
t("monitoring.widgets.config_error.history_unsupported")
);
}
if (!config) {
throw new WidgetConfigError(
t("monitoring.widgets.config_error.history_notfound")
);
}
return context?.widget?.config?._history;
}
return React.useMemo(
() => ({
config: context?.widget.config,
draft,
updateDraft,
replaceDraft,
assignToDraft,
saveDraft,
setLoading,
useContainerSize,
useSourceConfig,
useItemConfig,
useItemDimensionConfig,
useHistoryConfig,
}),
[context, draft]
);
}