in superset-frontend/src/views/CRUD/hooks.ts [234:401]
export function useSingleViewResource<D extends object = any>(
resourceName: string,
resourceLabel: string, // resourceLabel for translations
handleErrorMsg: (errorMsg: string) => void,
path_suffix = '',
) {
const [state, setState] = useState<SingleViewResourceState<D>>({
loading: false,
resource: null,
error: null,
});
function updateState(update: Partial<SingleViewResourceState<D>>) {
setState(currentState => ({ ...currentState, ...update }));
}
const fetchResource = useCallback(
(resourceID: number) => {
// Set loading state
updateState({
loading: true,
});
const baseEndpoint = `/api/v1/${resourceName}/${resourceID}`;
const endpoint =
path_suffix !== '' ? `${baseEndpoint}/${path_suffix}` : baseEndpoint;
return SupersetClient.get({
endpoint,
})
.then(
({ json = {} }) => {
updateState({
resource: json.result,
error: null,
});
return json.result;
},
createErrorHandler((errMsg: Record<string, string[] | string>) => {
handleErrorMsg(
t(
'An error occurred while fetching %ss: %s',
resourceLabel,
parsedErrorMessage(errMsg),
),
);
updateState({
error: errMsg,
});
}),
)
.finally(() => {
updateState({ loading: false });
});
},
[handleErrorMsg, resourceName, resourceLabel],
);
const createResource = useCallback(
(resource: D, hideToast = false) => {
// Set loading state
updateState({
loading: true,
});
return SupersetClient.post({
endpoint: `/api/v1/${resourceName}/`,
body: JSON.stringify(resource),
headers: { 'Content-Type': 'application/json' },
})
.then(
({ json = {} }) => {
updateState({
resource: { id: json.id, ...json.result },
error: null,
});
return json.id;
},
createErrorHandler((errMsg: Record<string, string[] | string>) => {
// we did not want toasts for db-connection-ui but did not want to disable it everywhere
if (!hideToast) {
handleErrorMsg(
t(
'An error occurred while creating %ss: %s',
resourceLabel,
parsedErrorMessage(errMsg),
),
);
}
updateState({
error: errMsg,
});
}),
)
.finally(() => {
updateState({ loading: false });
});
},
[handleErrorMsg, resourceName, resourceLabel],
);
const updateResource = useCallback(
(resourceID: number, resource: D, hideToast = false, setLoading = true) => {
// Set loading state
if (setLoading) {
updateState({
loading: true,
});
}
return SupersetClient.put({
endpoint: `/api/v1/${resourceName}/${resourceID}`,
body: JSON.stringify(resource),
headers: { 'Content-Type': 'application/json' },
})
.then(
({ json = {} }) => {
updateState({
resource: { ...json.result, id: json.id },
error: null,
});
return json.result;
},
createErrorHandler(errMsg => {
if (!hideToast) {
handleErrorMsg(
t(
'An error occurred while fetching %ss: %s',
resourceLabel,
JSON.stringify(errMsg),
),
);
}
updateState({
error: errMsg,
});
return errMsg;
}),
)
.finally(() => {
if (setLoading) {
updateState({ loading: false });
}
});
},
[handleErrorMsg, resourceName, resourceLabel],
);
const clearError = () =>
updateState({
error: null,
});
return {
state,
setResource: (update: D) =>
updateState({
resource: update,
}),
fetchResource,
createResource,
updateResource,
clearError,
};
}