Feature/improve custom extension repos support (#540)
* Move "TextSetting" to new folder * Extract dialog of "TextSetting" * Immediately show dialog when adding a list item * Reuse "TextSettingProps" for "MutableListSetting" * Add "placeholder" prop to "MutableListSetting" * Prevent duplicates by default * Clear dialog values on save * Validate repo url
This commit is contained in:
@@ -15,7 +15,9 @@ import List from '@mui/material/List';
|
||||
import DeleteIcon from '@mui/icons-material/Delete';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import DialogContentText from '@mui/material/DialogContentText';
|
||||
import { TextSetting, TextSettingProps } from '@/components/settings/TextSetting.tsx';
|
||||
import { TextSetting, TextSettingProps } from '@/components/settings/text/TextSetting.tsx';
|
||||
import { TextSettingDialog } from '@/components/settings/text/TextSettingDialog.tsx';
|
||||
import { makeToast } from '@/components/util/Toast.tsx';
|
||||
|
||||
const MutableListItem = ({
|
||||
handleDelete,
|
||||
@@ -35,24 +37,34 @@ const MutableListItem = ({
|
||||
);
|
||||
};
|
||||
|
||||
type MutableListSettingProps = Pick<TextSettingProps, 'settingName' | 'placeholder'> & {
|
||||
values?: string[];
|
||||
description?: string;
|
||||
addItemButtonTitle?: string;
|
||||
handleChange: (values: string[]) => void;
|
||||
allowDuplicates?: boolean;
|
||||
validateItem?: (value: string) => boolean;
|
||||
invalidItemError?: string;
|
||||
};
|
||||
|
||||
export const MutableListSetting = ({
|
||||
settingName,
|
||||
description,
|
||||
values,
|
||||
handleChange,
|
||||
addItemButtonTitle,
|
||||
}: {
|
||||
settingName: string;
|
||||
description?: string;
|
||||
values?: string[];
|
||||
handleChange: (values: string[]) => void;
|
||||
addItemButtonTitle?: string;
|
||||
}) => {
|
||||
placeholder,
|
||||
allowDuplicates = false,
|
||||
validateItem = () => true,
|
||||
invalidItemError,
|
||||
}: MutableListSettingProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
||||
const [dialogValues, setDialogValues] = useState(values ?? []);
|
||||
|
||||
const [isAddItemDialogOpen, setIsAddItemDialogOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!values) {
|
||||
return;
|
||||
@@ -76,11 +88,25 @@ export const MutableListSetting = ({
|
||||
return;
|
||||
}
|
||||
|
||||
const isDuplicate = !allowDuplicates && dialogValues.includes(newValue);
|
||||
if (isDuplicate) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (newValue === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!validateItem(newValue)) {
|
||||
makeToast(invalidItemError ?? t('global.error.label.invalid_input'), 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
setDialogValues(dialogValues.toSpliced(index, 1, newValue.trim()));
|
||||
};
|
||||
|
||||
const saveChanges = () => {
|
||||
closeDialog();
|
||||
closeDialog(true);
|
||||
handleChange(dialogValues.filter((dialogValue) => dialogValue !== ''));
|
||||
};
|
||||
|
||||
@@ -105,8 +131,8 @@ export const MutableListSetting = ({
|
||||
<List>
|
||||
{dialogValues.map((dialogValue, index) => (
|
||||
<MutableListItem
|
||||
settingName={dialogValue === '' ? t('global.label.placeholder') : ''}
|
||||
placeholder="https://github.com/MY_ACCOUNT/MY_REPO/tree/repo"
|
||||
settingName=""
|
||||
placeholder={placeholder}
|
||||
handleChange={(newValue: string) => updateSetting(index, newValue)}
|
||||
handleDelete={() => updateSetting(index, undefined)}
|
||||
value={dialogValue}
|
||||
@@ -116,7 +142,7 @@ export const MutableListSetting = ({
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Stack sx={{ width: '100%' }} direction="row" justifyContent="space-between">
|
||||
<Button onClick={() => updateSetting(dialogValues.length, '')}>
|
||||
<Button onClick={() => setIsAddItemDialogOpen(true)}>
|
||||
{addItemButtonTitle ?? t('global.button.add')}
|
||||
</Button>
|
||||
<Stack direction="row">
|
||||
@@ -126,6 +152,16 @@ export const MutableListSetting = ({
|
||||
</Stack>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
|
||||
{isAddItemDialogOpen && (
|
||||
<TextSettingDialog
|
||||
settingName=""
|
||||
placeholder={placeholder}
|
||||
handleChange={(newValue: string) => updateSetting(dialogValues.length, newValue)}
|
||||
isDialogOpen={isAddItemDialogOpen}
|
||||
setIsDialogOpen={setIsAddItemDialogOpen}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user