typescript
This commit is contained in:
@@ -0,0 +1,203 @@
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
const useCapabilitySets = ({ api, notifyApiError, setStatusMessage, token }) => {
|
||||
const [capabilitySets, setCapabilitySets] = useState([]);
|
||||
const [capabilitySetsLoading, setCapabilitySetsLoading] = useState(false);
|
||||
const [creatingCapabilitySet, setCreatingCapabilitySet] = useState(false);
|
||||
const [savingCapabilitySetId, setSavingCapabilitySetId] = useState(null);
|
||||
const [deletingCapabilitySetId, setDeletingCapabilitySetId] = useState(null);
|
||||
const [supportsCapabilitySetLabels, setSupportsCapabilitySetLabels] = useState(false);
|
||||
|
||||
const applyCapabilitySets = useCallback((updater) => {
|
||||
setCapabilitySets((previous) => {
|
||||
const base = Array.isArray(previous) ? [...previous] : [];
|
||||
const next = typeof updater === 'function'
|
||||
? updater(base)
|
||||
: (Array.isArray(updater) ? [...updater] : base);
|
||||
const supportsLabels = next.some((item) => Object.prototype.hasOwnProperty.call(item || {}, 'label'));
|
||||
setSupportsCapabilitySetLabels(supportsLabels);
|
||||
return next;
|
||||
});
|
||||
}, []);
|
||||
|
||||
const refreshCapabilitySets = useCallback(async () => {
|
||||
if (!token) {
|
||||
applyCapabilitySets([]);
|
||||
return;
|
||||
}
|
||||
setCapabilitySetsLoading(true);
|
||||
try {
|
||||
const { data } = await api.get('/capability-sets');
|
||||
applyCapabilitySets(Array.isArray(data) ? data : []);
|
||||
} catch (error) {
|
||||
notifyApiError?.(error, 'Failed to load capability sets.');
|
||||
} finally {
|
||||
setCapabilitySetsLoading(false);
|
||||
}
|
||||
}, [api, applyCapabilitySets, notifyApiError, token]);
|
||||
|
||||
useEffect(() => {
|
||||
if (token) {
|
||||
refreshCapabilitySets();
|
||||
} else {
|
||||
applyCapabilitySets([]);
|
||||
}
|
||||
}, [applyCapabilitySets, refreshCapabilitySets, token]);
|
||||
|
||||
const createCapabilitySet = useCallback(
|
||||
async ({ slug, label, capabilities } = {}) => {
|
||||
if (creatingCapabilitySet) {
|
||||
return false;
|
||||
}
|
||||
if (!Array.isArray(capabilities) || capabilities.length === 0) {
|
||||
setStatusMessage?.('Select at least one capability.', 'error');
|
||||
return false;
|
||||
}
|
||||
setCreatingCapabilitySet(true);
|
||||
try {
|
||||
const payload = {
|
||||
capabilities,
|
||||
};
|
||||
const trimmedSlug = slug?.trim();
|
||||
if (trimmedSlug) {
|
||||
payload.slug = trimmedSlug;
|
||||
}
|
||||
const trimmedLabel = label?.trim();
|
||||
if (trimmedLabel && supportsCapabilitySetLabels) {
|
||||
payload.label = trimmedLabel;
|
||||
}
|
||||
|
||||
const { data } = await api.post('/capability-sets', payload);
|
||||
if (data) {
|
||||
applyCapabilitySets((previous) => {
|
||||
const next = previous.filter((entry) => entry?.id !== data.id);
|
||||
next.push(data);
|
||||
next.sort((a, b) => a.slug.localeCompare(b.slug));
|
||||
return next;
|
||||
});
|
||||
} else {
|
||||
await refreshCapabilitySets();
|
||||
}
|
||||
setStatusMessage?.('Capability set created.', 'success');
|
||||
return data;
|
||||
} catch (error) {
|
||||
notifyApiError?.(error, 'Failed to create capability set.');
|
||||
return false;
|
||||
} finally {
|
||||
setCreatingCapabilitySet(false);
|
||||
}
|
||||
},
|
||||
[
|
||||
api,
|
||||
applyCapabilitySets,
|
||||
creatingCapabilitySet,
|
||||
notifyApiError,
|
||||
refreshCapabilitySets,
|
||||
setStatusMessage,
|
||||
supportsCapabilitySetLabels,
|
||||
],
|
||||
);
|
||||
|
||||
const updateCapabilitySet = useCallback(
|
||||
async (capabilitySetId, { slug, label, capabilities } = {}) => {
|
||||
if (!capabilitySetId) {
|
||||
return false;
|
||||
}
|
||||
setSavingCapabilitySetId(capabilitySetId);
|
||||
try {
|
||||
const payload = {};
|
||||
if (slug !== undefined) {
|
||||
const trimmed = slug?.trim();
|
||||
if (trimmed) {
|
||||
payload.slug = trimmed;
|
||||
} else if (slug === '') {
|
||||
payload.slug = '';
|
||||
}
|
||||
}
|
||||
if (label !== undefined && supportsCapabilitySetLabels) {
|
||||
const trimmed = label?.trim();
|
||||
if (trimmed) {
|
||||
payload.label = trimmed;
|
||||
} else if (label === '') {
|
||||
payload.label = '';
|
||||
}
|
||||
}
|
||||
if (Array.isArray(capabilities)) {
|
||||
payload.capabilities = capabilities;
|
||||
}
|
||||
|
||||
const { data } = await api.patch(`/capability-sets/${capabilitySetId}`, payload);
|
||||
if (data) {
|
||||
applyCapabilitySets((previous) => {
|
||||
let found = false;
|
||||
const next = previous.map((entry) => {
|
||||
if (entry?.id === data.id) {
|
||||
found = true;
|
||||
return data;
|
||||
}
|
||||
return entry;
|
||||
});
|
||||
if (!found) {
|
||||
next.push(data);
|
||||
}
|
||||
next.sort((a, b) => a.slug.localeCompare(b.slug));
|
||||
return next;
|
||||
});
|
||||
} else {
|
||||
await refreshCapabilitySets();
|
||||
}
|
||||
setStatusMessage?.('Capability set updated.', 'success');
|
||||
return true;
|
||||
} catch (error) {
|
||||
notifyApiError?.(error, 'Failed to update capability set.');
|
||||
return false;
|
||||
} finally {
|
||||
setSavingCapabilitySetId(null);
|
||||
}
|
||||
},
|
||||
[
|
||||
api,
|
||||
applyCapabilitySets,
|
||||
notifyApiError,
|
||||
refreshCapabilitySets,
|
||||
setStatusMessage,
|
||||
supportsCapabilitySetLabels,
|
||||
],
|
||||
);
|
||||
|
||||
const deleteCapabilitySet = useCallback(
|
||||
async (capabilitySetId) => {
|
||||
if (!capabilitySetId) {
|
||||
return false;
|
||||
}
|
||||
setDeletingCapabilitySetId(capabilitySetId);
|
||||
try {
|
||||
await api.delete(`/capability-sets/${capabilitySetId}`);
|
||||
applyCapabilitySets((previous) => previous.filter((entry) => entry?.id !== capabilitySetId));
|
||||
setStatusMessage?.('Capability set deleted.', 'success');
|
||||
return true;
|
||||
} catch (error) {
|
||||
notifyApiError?.(error, 'Failed to delete capability set.');
|
||||
return false;
|
||||
} finally {
|
||||
setDeletingCapabilitySetId(null);
|
||||
}
|
||||
},
|
||||
[api, applyCapabilitySets, notifyApiError, setStatusMessage],
|
||||
);
|
||||
|
||||
return {
|
||||
capabilitySets,
|
||||
capabilitySetsLoading,
|
||||
creatingCapabilitySet,
|
||||
savingCapabilitySetId,
|
||||
deletingCapabilitySetId,
|
||||
supportsCapabilitySetLabels,
|
||||
refreshCapabilitySets,
|
||||
createCapabilitySet,
|
||||
updateCapabilitySet,
|
||||
deleteCapabilitySet,
|
||||
};
|
||||
};
|
||||
|
||||
export default useCapabilitySets;
|
||||
Reference in New Issue
Block a user