mirror of
https://github.com/ansible/awx.git
synced 2026-05-14 21:07:39 -02:30
WIP
This commit is contained in:
@@ -10,23 +10,20 @@ import ContentLoading from '@components/ContentLoading';
|
|||||||
import ErrorDetail from '@components/ErrorDetail';
|
import ErrorDetail from '@components/ErrorDetail';
|
||||||
import { JobTemplatesAPI } from '@api';
|
import { JobTemplatesAPI } from '@api';
|
||||||
import ContentEmpty from '@components/ContentEmpty';
|
import ContentEmpty from '@components/ContentEmpty';
|
||||||
import { getQSConfig } from '@util/qs';
|
|
||||||
import AlertModal from '@components/AlertModal';
|
import AlertModal from '@components/AlertModal';
|
||||||
import SurveyListItem from './SurveyListItem';
|
import SurveyListItem from './SurveyListItem';
|
||||||
import SurveyToolbar from './SurveyToolbar';
|
import SurveyToolbar from './SurveyToolbar';
|
||||||
|
|
||||||
const QS_CONFIG = getQSConfig('survey', {
|
|
||||||
page: 1,
|
|
||||||
});
|
|
||||||
|
|
||||||
function SurveyList({ template, i18n }) {
|
function SurveyList({ template, i18n }) {
|
||||||
const [selected, setSelected] = useState([]);
|
const [selected, setSelected] = useState([]);
|
||||||
|
// const [updated, setUpdated] = useState(null);
|
||||||
const [surveyEnabled, setSurveyEnabled] = useState(template.survey_enabled);
|
const [surveyEnabled, setSurveyEnabled] = useState(template.survey_enabled);
|
||||||
const [showToggleError, setShowToggleError] = useState(false);
|
const [showError, setShowError] = useState(false);
|
||||||
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
||||||
|
const [questions, setQuestions] = useState(null);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
result: { questions, name, description },
|
result: { fetchedQuestions, name, description },
|
||||||
error: contentError,
|
error: contentError,
|
||||||
isLoading,
|
isLoading,
|
||||||
request: fetchSurvey,
|
request: fetchSurvey,
|
||||||
@@ -35,8 +32,9 @@ function SurveyList({ template, i18n }) {
|
|||||||
const {
|
const {
|
||||||
data: { spec = [], description: surveyDescription, name: surveyName },
|
data: { spec = [], description: surveyDescription, name: surveyName },
|
||||||
} = await JobTemplatesAPI.readSurvey(template.id);
|
} = await JobTemplatesAPI.readSurvey(template.id);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
questions: spec?.map((s, index) => ({ ...s, id: index })),
|
fetchedQuestions: spec?.map((s, index) => ({ ...s, id: index })),
|
||||||
description: surveyDescription,
|
description: surveyDescription,
|
||||||
name: surveyName,
|
name: surveyName,
|
||||||
};
|
};
|
||||||
@@ -44,41 +42,27 @@ function SurveyList({ template, i18n }) {
|
|||||||
{ questions: [], name: '', description: '' }
|
{ questions: [], name: '', description: '' }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setQuestions(fetchedQuestions);
|
||||||
|
}, [fetchedQuestions]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchSurvey();
|
fetchSurvey();
|
||||||
}, [fetchSurvey]);
|
}, [fetchSurvey]);
|
||||||
|
|
||||||
const isAllSelected =
|
const isAllSelected =
|
||||||
selected.length === questions?.length && selected.length > 0;
|
selected.length === questions?.length && selected.length > 0;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isLoading: isDeleteLoading,
|
isLoading: isDeleteLoading,
|
||||||
deleteItems: deleteQuestions,
|
deleteItems: deleteSurvey,
|
||||||
deletionError,
|
deletionError,
|
||||||
clearDeletionError,
|
|
||||||
} = useDeleteItems(
|
} = useDeleteItems(
|
||||||
useCallback(async () => {
|
useCallback(async () => {
|
||||||
if (isAllSelected) {
|
await JobTemplatesAPI.destroySurvey(template.id);
|
||||||
return JobTemplatesAPI.destroySurvey(template.id);
|
fetchSurvey();
|
||||||
}
|
}, [template.id, fetchSurvey])
|
||||||
const surveyQuestions = [];
|
|
||||||
questions.forEach(q => {
|
|
||||||
if (!selected.some(s => s.id === q.id)) {
|
|
||||||
surveyQuestions.push(q);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return JobTemplatesAPI.updateSurvey(template.id, {
|
|
||||||
name,
|
|
||||||
description,
|
|
||||||
spec: surveyQuestions,
|
|
||||||
});
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, [selected]),
|
|
||||||
{
|
|
||||||
qsConfig: QS_CONFIG,
|
|
||||||
fetchItems: fetchSurvey,
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isToggleLoading,
|
isToggleLoading,
|
||||||
error: toggleError,
|
error: toggleError,
|
||||||
@@ -93,12 +77,6 @@ function SurveyList({ template, i18n }) {
|
|||||||
template.survey_enabled
|
template.survey_enabled
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (toggleError) {
|
|
||||||
setShowToggleError(true);
|
|
||||||
}
|
|
||||||
}, [toggleError]);
|
|
||||||
|
|
||||||
const handleSelectAll = isSelected => {
|
const handleSelectAll = isSelected => {
|
||||||
setSelected(isSelected ? [...questions] : []);
|
setSelected(isSelected ? [...questions] : []);
|
||||||
};
|
};
|
||||||
@@ -112,15 +90,56 @@ function SurveyList({ template, i18n }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleDelete = async () => {
|
const handleDelete = async () => {
|
||||||
await deleteQuestions();
|
if (isAllSelected) {
|
||||||
setIsDeleteModalOpen(false);
|
await deleteSurvey();
|
||||||
|
setIsDeleteModalOpen(false);
|
||||||
|
} else {
|
||||||
|
setQuestions(questions.filter(q => !selected.includes(q)));
|
||||||
|
setIsDeleteModalOpen(false);
|
||||||
|
}
|
||||||
setSelected([]);
|
setSelected([]);
|
||||||
};
|
};
|
||||||
const canEdit = template.summary_fields.user_capabilities.edit;
|
|
||||||
const canDelete = template.summary_fields.user_capabilities.delete;
|
const {
|
||||||
|
isLoading: isUpdateLoading,
|
||||||
|
error: updateError,
|
||||||
|
// request: updateSurvey,
|
||||||
|
} = useRequest(
|
||||||
|
useCallback(async () => {
|
||||||
|
return JobTemplatesAPI.updateSurvey(template.id, {
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
spec: questions,
|
||||||
|
});
|
||||||
|
}, [template.id, name, description, questions])
|
||||||
|
);
|
||||||
|
|
||||||
|
const moveUp = question => {
|
||||||
|
const index = questions.indexOf(question);
|
||||||
|
if (index < 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const beginning = questions.slice(0, index - 1);
|
||||||
|
const swapWith = questions[index - 1];
|
||||||
|
const end = questions.slice(index + 1);
|
||||||
|
setQuestions([...beginning, question, swapWith, ...end]);
|
||||||
|
};
|
||||||
|
const moveDown = question => {
|
||||||
|
const index = questions.indexOf(question);
|
||||||
|
if (index === -1 || index > questions.length - 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const beginning = questions.slice(0, index);
|
||||||
|
const swapWith = questions[index + 1];
|
||||||
|
const end = questions.slice(index + 2);
|
||||||
|
setQuestions([...beginning, swapWith, question, ...end]);
|
||||||
|
};
|
||||||
|
|
||||||
let content;
|
let content;
|
||||||
if (isLoading || isToggleLoading || isDeleteLoading) {
|
if (
|
||||||
|
(isLoading || isToggleLoading || isDeleteLoading || isUpdateLoading) &&
|
||||||
|
questions?.length <= 0
|
||||||
|
) {
|
||||||
content = <ContentLoading />;
|
content = <ContentLoading />;
|
||||||
} else if (contentError) {
|
} else if (contentError) {
|
||||||
content = <ContentError error={contentError} />;
|
content = <ContentError error={contentError} />;
|
||||||
@@ -140,9 +159,29 @@ function SurveyList({ template, i18n }) {
|
|||||||
question={question}
|
question={question}
|
||||||
isChecked={selected.some(s => s.id === question.id)}
|
isChecked={selected.some(s => s.id === question.id)}
|
||||||
onSelect={() => handleSelect(question)}
|
onSelect={() => handleSelect(question)}
|
||||||
|
onMoveUp={moveUp}
|
||||||
|
onMoveDown={moveDown}
|
||||||
/>
|
/>
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const error = deletionError || toggleError || updateError;
|
||||||
|
let errorMessage = '';
|
||||||
|
if (updateError) {
|
||||||
|
errorMessage = i18n._(t`Failed to update survey`);
|
||||||
|
}
|
||||||
|
if (toggleError) {
|
||||||
|
errorMessage = i18n._(t`Failed to toggle survey`);
|
||||||
|
}
|
||||||
|
if (deletionError) {
|
||||||
|
errorMessage = i18n._(t`Failed to delete survey`);
|
||||||
|
}
|
||||||
|
useEffect(() => {
|
||||||
|
if (error) {
|
||||||
|
setShowError(true);
|
||||||
|
}
|
||||||
|
}, [error]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SurveyToolbar
|
<SurveyToolbar
|
||||||
@@ -150,7 +189,7 @@ function SurveyList({ template, i18n }) {
|
|||||||
onSelectAll={handleSelectAll}
|
onSelectAll={handleSelectAll}
|
||||||
surveyEnabled={surveyEnabled}
|
surveyEnabled={surveyEnabled}
|
||||||
onToggleSurvey={toggleSurvey}
|
onToggleSurvey={toggleSurvey}
|
||||||
isDeleteDisabled={selected?.length === 0 || !canEdit || !canDelete}
|
isDeleteDisabled={selected?.length === 0}
|
||||||
onToggleDeleteModal={() => setIsDeleteModalOpen(true)}
|
onToggleDeleteModal={() => setIsDeleteModalOpen(true)}
|
||||||
/>
|
/>
|
||||||
{content}
|
{content}
|
||||||
@@ -198,26 +237,15 @@ function SurveyList({ template, i18n }) {
|
|||||||
))}
|
))}
|
||||||
</AlertModal>
|
</AlertModal>
|
||||||
)}
|
)}
|
||||||
{deletionError && (
|
{showError && (
|
||||||
<AlertModal
|
<AlertModal
|
||||||
isOpen={deletionError}
|
isOpen={showError}
|
||||||
variant="error"
|
variant="error"
|
||||||
title={i18n._(t`Error!`)}
|
title={i18n._(t`Error!`)}
|
||||||
onClose={clearDeletionError}
|
onClose={() => setShowError(false)}
|
||||||
>
|
>
|
||||||
{i18n._(t`Failed to delete one or more jobs.`)}
|
{errorMessage}
|
||||||
<ErrorDetail error={deletionError} />
|
<ErrorDetail error={error} />
|
||||||
</AlertModal>
|
|
||||||
)}
|
|
||||||
{toggleError && (
|
|
||||||
<AlertModal
|
|
||||||
variant="error"
|
|
||||||
title={i18n._(t`Error!`)}
|
|
||||||
isOpen={showToggleError && !isLoading}
|
|
||||||
onClose={() => setShowToggleError(false)}
|
|
||||||
>
|
|
||||||
{i18n._(t`Failed to toggle host.`)}
|
|
||||||
<ErrorDetail error={toggleError} />
|
|
||||||
</AlertModal>
|
</AlertModal>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ function SurveyListItem({
|
|||||||
isFirst,
|
isFirst,
|
||||||
isChecked,
|
isChecked,
|
||||||
onSelect,
|
onSelect,
|
||||||
|
onMoveUp,
|
||||||
|
onMoveDown,
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<DataList aria-label={i18n._(t`Survey List`)}>
|
<DataList aria-label={i18n._(t`Survey List`)}>
|
||||||
@@ -51,6 +53,7 @@ function SurveyListItem({
|
|||||||
variant="plain"
|
variant="plain"
|
||||||
aria-label={i18n._(t`move up`)}
|
aria-label={i18n._(t`move up`)}
|
||||||
isDisabled={isFirst}
|
isDisabled={isFirst}
|
||||||
|
onClick={() => onMoveUp(question)}
|
||||||
>
|
>
|
||||||
<CaretUpIcon />
|
<CaretUpIcon />
|
||||||
</Button>
|
</Button>
|
||||||
@@ -60,6 +63,7 @@ function SurveyListItem({
|
|||||||
variant="plain"
|
variant="plain"
|
||||||
aria-label={i18n._(t`move down`)}
|
aria-label={i18n._(t`move down`)}
|
||||||
isDisabled={isLast}
|
isDisabled={isLast}
|
||||||
|
onClick={() => onMoveDown(question)}
|
||||||
>
|
>
|
||||||
<CaretDownIcon />
|
<CaretDownIcon />
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ export default function useRequest(makeRequest, initialValue) {
|
|||||||
|
|
||||||
export function useDeleteItems(
|
export function useDeleteItems(
|
||||||
makeRequest,
|
makeRequest,
|
||||||
{ qsConfig, allItemsSelected, fetchItems }
|
{ qsConfig = null, allItemsSelected = false, fetchItems = null } = {}
|
||||||
) {
|
) {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
@@ -71,6 +71,9 @@ export function useDeleteItems(
|
|||||||
|
|
||||||
const deleteItems = async () => {
|
const deleteItems = async () => {
|
||||||
await request();
|
await request();
|
||||||
|
if (!qsConfig) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const params = parseQueryString(qsConfig, location.search);
|
const params = parseQueryString(qsConfig, location.search);
|
||||||
if (params.page > 1 && allItemsSelected) {
|
if (params.page > 1 && allItemsSelected) {
|
||||||
const newParams = encodeNonDefaultQueryString(
|
const newParams = encodeNonDefaultQueryString(
|
||||||
|
|||||||
Reference in New Issue
Block a user