wlabel API
The white label has an internal API that is used to "bind" widgets either to each other, to third-party hosts, or to the white label itself.
platformMeta
platformMeta: IPlatformMeta; - meta information, used in widgets sometimes, when you need to know widget ID or current dashboard ID.
Below is an example where a related parties widget uses platformMeta to generate a valid link based on the dashboard ID:
const titleLink = generatePath(DASHBOARD_LIGHTBOX_PATH, {
dashboardId: platformMeta.currentDashboardId as string,
widgetId: WIDGET_ID,
});
httpClient
The httpClient is a client for external requests, appearing in all widgets.
The default way it works is to use our library as a "factory" (in the sense of a pattern) to create an instance of the client.
For different projects pull an action, for example, for these various projects, which in turn use the same library to create the same instance, but with predefined properties by default (eg, mandatory headers for queries).
This client instance is passed to all widgets and can be used in the white label to make queries. For more information, click here.
The httpClient – is a client for HTTP requests, in the example below pulls it from the extensibility, if there is one, if not, it is used in the widget itself to make requests to the server.
This is essentially analogous to fetch from JavaScript, it just has a couple of default parameters, automatic response parsing, etc.
const HttpClientContext =
React.createContext<HttpClientT<any>>(defaultHttpClient);
export const useHttpClient = () => {
return useContext(HttpClientContext);
};
shareValue
shareValue - for status sharing between widgets (useShareValue, useSelectSharedValue, useDeleteSharedValue).
It's a hook we give to widgets, by which we can get or write data by some key.
It's something like a key-value repository that can be accessed from the white label or any widget.
For more information, click here.
An example of usage shareValue, useShareValue and useSelectSharedValue:
const GetUserInfo = ({
apiUrl,
httpClient,
useShareValue,
useSelectSharedValue,
}: IWidgetProps) => {
const shareValue = useShareValue();
const userProfile = useSelectSharedValue(userProfileSelector);
useAsync(async () => {
if (apiUrl && !userProfile) {
try {
const res = await httpClient(`${apiUrl}/user/profile`, {
traceId: projectId,
});
shareValue(["userProfile"], res);
} catch (e) {
console.error(e, projectId);
}
}
}, [httpClient, apiUrl, userProfile]);
return null;
};
Example of useDeleteSharedValue:
export function useDeleteSharedValue() {
const dispatch = useDispatch():
return useMemo(
() => (path: string[]) => {
if (!path || !Array.isArray(path) || !path.length) {
throw new Error(
'Wrong path to shared key in `useDeleteShareValue. `path` should be non empty array of strings `path: string[]`'
);
}
const action = deleteSharedValueAction(path) as Action<string[]>;
dispatch(action);
},
[dispatch]
);
}
remoteModule
remoteModule: RemoteModuleT; – the component that allows you to call another model inside a widget which is a module.
For more information, click here.
In the example below, the dashboard header widget embeds role switchers, editing menus, etc.
<BreadcrumbsWrapper>
<RemoteModule
module={breadcrumbsData.component}
scope={breadcrumbsData.scope}
url={breadcrumbsData.host}
componentProps={{ apiUrl, customizationUrl }}
/>
</BreadcrumbsWrapper>
generateWidgetData
generateWidgetData: GenerateWidgetDataT; – the utility that generates widget data. Allows quickly generate widget metadata inside another widget.
const widgetId = "283";
const widgetName = "VendorName_Breadcrumbs";
const breadcrumbsData = useMemo(
() => generateWidgetData(widgetName, widgetId),
[generateWidgetData]
);
useQueryData
useQueryData: UseQueryDataT; – is a hook, that internally subscribes to the react-query cache, and returns an updated query state object if it was changed.
Under the hood of useQueryData we use (react-query QueryCache)[https://tanstack.com/query/v4/docs/reference/QueryCache].
The main thing you need to use is the queryKey, through which the cached data is subscribed. The key should be as static as possible.
import { useQuery } from "react-query";
// lets get info in some place
const defaultDashboardQuery = useQuery<{ result: string }, unknown, string>(
["navigation", "defaultDashboard"],
() => httpClient(`${CUSTOMIZATION_BE}/dashboards/default-dashboard`),
{
select: (data) => data?.result,
}
);
// Another widget wants to know this info
const Widget = ({ useQueryData }) => {
const defaultDashboardQueryData = useQueryData([
"navigation",
"defaultDashboard",
]);
};
useDashboardNavigationInfo: UseDashboardNavigationInfoT; – the hook to get information about the navigation graph node by dashboard ID.
const { data: navigationInfo } = useDashboardNavigationInfo(dashboardId);
useDashboardsNavigationMeta: UseDashboardsNavigationMetaT; – the hook to get all the meta of all the dashboards.
installedExtensions & getExtension
installedExtensions: ExtensionT[]; – a list of all installed Extensions, http-client-companion, bff-companion, etc.
The list of installed extensions is stored on the bff.
getExtension: GetExtensionT; – the hook to get an instance of the extensions, for example for http-client-companion.
Here is an example of using getExtension to load an entity-accessor:
import {
getExtension,
getExtensionsList,
} from "@/lib/module-federation/use-extensions";
const { getExtension, getExtensionsList } = props;
useEffect(() => {
const wss = getExtension("@invent/bff-ws-ext");
const handler = (message: unknown) => {
console.log(message);
};
// (methodName: string, method: (...args: any[]) => void)) => void
wss?.subscribe('downloadsChanged', handler);
return () => {
wss?.unsubscribe('downloadsChanged', handler);
};
}, [getExtension("@invent/bff-ws-ext")]);
dashboardWidgetInstanceId
dashboardWidgetInstanceId?: string; – identifies a widget instance inside the specific dashboard.
It can be used for state sharing across this dashboard or other means.
layout
layout?: IDashboardWidgetLayout; – the data for the widget on the dashboard to know its sizes: width, height.
errorStateComponent – component, which is a state error widget, and used in the layout
errorStateComponent?: (
props: Record<string, unknown> & { error?: IErrorMetaInfo }
) => JSX.Element;
showNotification
It triggers a notification showing. Works by passing a type of notification and message. We are using (react-toastify)[https://fkhadra.github.io/react-toastify/introduction] underhood.
export type InfoNotificationTypeT = "info" | "error" | "warning" | "success";
export type ShowNotificationOptionsT = ToastOptions & {
refreshHandler?: () => void;
};
export type ShowNotificationT = (
type: InfoNotificationTypeT,
content: ToastContent,
options?: ShowNotificationOptionsT
) => void;
Default ToastContainer options:
{
"hideProgressBar": true,
"containerId": "wlabel-platform-container-notifications",
"enableMultiContainer": true,
"autoClose": 3000,
"limit": 3,
"position": "bottom-left",
"closeButton": false
}
If you wish tune ToastContainer behavior, pass config to showNotification.
...
showNotification('success', 'GREAT SUCCESS!', {
position: 'top-center',
autoClose: false
});
...