|
@@ -128,6 +128,9 @@ const renderBoxSx = {
|
|
|
interface SelectorProps extends SelTreeProps {
|
|
|
dropdown?: boolean;
|
|
|
mode?: string;
|
|
|
+ defaultSelectionMessage?: string;
|
|
|
+ selectionMessage?: string;
|
|
|
+ showSelectAll?: boolean;
|
|
|
}
|
|
|
|
|
|
const Selector = (props: SelectorProps) => {
|
|
@@ -145,6 +148,7 @@ const Selector = (props: SelectorProps) => {
|
|
|
height,
|
|
|
valueById,
|
|
|
mode = "",
|
|
|
+ showSelectAll = false,
|
|
|
} = props;
|
|
|
const [searchValue, setSearchValue] = useState("");
|
|
|
const [selectedValue, setSelectedValue] = useState<string[]>([]);
|
|
@@ -155,6 +159,7 @@ const Selector = (props: SelectorProps) => {
|
|
|
const className = useClassNames(props.libClassName, props.dynamicClassName, props.className);
|
|
|
const active = useDynamicProperty(props.active, props.defaultActive, true);
|
|
|
const hover = useDynamicProperty(props.hoverText, props.defaultHoverText, undefined);
|
|
|
+ const selectionMessage = useDynamicProperty(props.selectionMessage, props.defaultSelectionMessage, undefined);
|
|
|
|
|
|
useDispatchRequestUpdateOnFirstRender(dispatch, id, module, updateVars, updateVarName);
|
|
|
|
|
@@ -281,6 +286,24 @@ const Selector = (props: SelectorProps) => {
|
|
|
[dispatch, updateVarName, propagate, updateVars, valueById, props.onChange, module]
|
|
|
);
|
|
|
|
|
|
+ const handleCheckAllChange = useCallback(
|
|
|
+ (event: SelectChangeEvent<HTMLInputElement>, checked: boolean) => {
|
|
|
+ const sel = checked ? lovList.map((elt) => elt.id) : [];
|
|
|
+ setSelectedValue(sel);
|
|
|
+ dispatch(
|
|
|
+ createSendUpdateAction(
|
|
|
+ updateVarName,
|
|
|
+ sel,
|
|
|
+ module,
|
|
|
+ props.onChange,
|
|
|
+ propagate,
|
|
|
+ valueById ? undefined : getUpdateVar(updateVars, "lov")
|
|
|
+ )
|
|
|
+ );
|
|
|
+ },
|
|
|
+ [lovList, dispatch, updateVarName, propagate, updateVars, valueById, props.onChange, module]
|
|
|
+ );
|
|
|
+
|
|
|
const [autoValue, setAutoValue] = useState<LovItem | LovItem[] | null>(() => (multiple ? [] : null));
|
|
|
const handleAutoChange = useCallback(
|
|
|
(e: SyntheticEvent, sel: LovItem | LovItem[] | null) => {
|
|
@@ -411,43 +434,72 @@ const Selector = (props: SelectorProps) => {
|
|
|
multiple={multiple}
|
|
|
value={dropdownValue}
|
|
|
onChange={handleChange}
|
|
|
- input={<OutlinedInput label={props.label} />}
|
|
|
+ input={
|
|
|
+ <OutlinedInput
|
|
|
+ label={props.label}
|
|
|
+ startAdornment={
|
|
|
+ multiple && showSelectAll ? (
|
|
|
+ <Tooltip
|
|
|
+ title={
|
|
|
+ selectedValue.length == lovList.length
|
|
|
+ ? "Deselect All"
|
|
|
+ : "Select All"
|
|
|
+ }
|
|
|
+ >
|
|
|
+ <Checkbox
|
|
|
+ disabled={!active}
|
|
|
+ indeterminate={
|
|
|
+ selectedValue.length > 0 &&
|
|
|
+ selectedValue.length < lovList.length
|
|
|
+ }
|
|
|
+ checked={selectedValue.length == lovList.length}
|
|
|
+ onChange={handleCheckAllChange}
|
|
|
+ ></Checkbox>
|
|
|
+ </Tooltip>
|
|
|
+ ) : null
|
|
|
+ }
|
|
|
+ />
|
|
|
+ }
|
|
|
disabled={!active}
|
|
|
renderValue={(selected) => (
|
|
|
<Box sx={renderBoxSx}>
|
|
|
- {lovList
|
|
|
- .filter((it) =>
|
|
|
- Array.isArray(selected) ? selected.includes(it.id) : selected === it.id
|
|
|
- )
|
|
|
- .map((item, idx) => {
|
|
|
- if (multiple) {
|
|
|
- const chipProps = {} as Record<string, unknown>;
|
|
|
- if (typeof item.item === "string") {
|
|
|
- chipProps.label = item.item;
|
|
|
- } else {
|
|
|
- chipProps.label = item.item.text || "";
|
|
|
- chipProps.avatar = <Avatar src={item.item.path} />;
|
|
|
- }
|
|
|
- return (
|
|
|
- <Chip
|
|
|
- key={item.id}
|
|
|
- {...chipProps}
|
|
|
- onDelete={handleDelete}
|
|
|
- data-id={item.id}
|
|
|
- onMouseDown={doNotPropagateEvent}
|
|
|
- disabled={!active}
|
|
|
- />
|
|
|
- );
|
|
|
- } else if (idx === 0) {
|
|
|
- return typeof item.item === "string" ? (
|
|
|
- item.item
|
|
|
- ) : (
|
|
|
- <LovImage item={item.item} />
|
|
|
- );
|
|
|
- } else {
|
|
|
- return null;
|
|
|
- }
|
|
|
- })}
|
|
|
+ {typeof selectionMessage === "string"
|
|
|
+ ? selectionMessage
|
|
|
+ : lovList
|
|
|
+ .filter((it) =>
|
|
|
+ Array.isArray(selected)
|
|
|
+ ? selected.includes(it.id)
|
|
|
+ : selected === it.id
|
|
|
+ )
|
|
|
+ .map((item, idx) => {
|
|
|
+ if (multiple) {
|
|
|
+ const chipProps = {} as Record<string, unknown>;
|
|
|
+ if (typeof item.item === "string") {
|
|
|
+ chipProps.label = item.item;
|
|
|
+ } else {
|
|
|
+ chipProps.label = item.item.text || "";
|
|
|
+ chipProps.avatar = <Avatar src={item.item.path} />;
|
|
|
+ }
|
|
|
+ return (
|
|
|
+ <Chip
|
|
|
+ key={item.id}
|
|
|
+ {...chipProps}
|
|
|
+ onDelete={handleDelete}
|
|
|
+ data-id={item.id}
|
|
|
+ onMouseDown={doNotPropagateEvent}
|
|
|
+ disabled={!active}
|
|
|
+ />
|
|
|
+ );
|
|
|
+ } else if (idx === 0) {
|
|
|
+ return typeof item.item === "string" ? (
|
|
|
+ item.item
|
|
|
+ ) : (
|
|
|
+ <LovImage item={item.item} />
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ })}
|
|
|
</Box>
|
|
|
)}
|
|
|
MenuProps={getMenuProps(height)}
|
|
@@ -479,7 +531,7 @@ const Selector = (props: SelectorProps) => {
|
|
|
) : null}
|
|
|
<Tooltip title={hover || ""}>
|
|
|
<Paper sx={paperSx}>
|
|
|
- {filter && (
|
|
|
+ {filter ? (
|
|
|
<Box>
|
|
|
<OutlinedInput
|
|
|
margin="dense"
|
|
@@ -487,9 +539,46 @@ const Selector = (props: SelectorProps) => {
|
|
|
value={searchValue}
|
|
|
onChange={handleInput}
|
|
|
disabled={!active}
|
|
|
+ startAdornment={
|
|
|
+ multiple && showSelectAll ? (
|
|
|
+ <Tooltip
|
|
|
+ title={
|
|
|
+ selectedValue.length == lovList.length
|
|
|
+ ? "Deselect All"
|
|
|
+ : "Select All"
|
|
|
+ }
|
|
|
+ >
|
|
|
+ <Checkbox
|
|
|
+ disabled={!active}
|
|
|
+ indeterminate={
|
|
|
+ selectedValue.length > 0 &&
|
|
|
+ selectedValue.length < lovList.length
|
|
|
+ }
|
|
|
+ checked={selectedValue.length == lovList.length}
|
|
|
+ onChange={handleCheckAllChange}
|
|
|
+ ></Checkbox>
|
|
|
+ </Tooltip>
|
|
|
+ ) : null
|
|
|
+ }
|
|
|
+ />
|
|
|
+ </Box>
|
|
|
+ ) : multiple && showSelectAll ? (
|
|
|
+ <Box paddingLeft={1}>
|
|
|
+ <FormControlLabel
|
|
|
+ control={
|
|
|
+ <Checkbox
|
|
|
+ disabled={!active}
|
|
|
+ indeterminate={
|
|
|
+ selectedValue.length > 0 && selectedValue.length < lovList.length
|
|
|
+ }
|
|
|
+ checked={selectedValue.length == lovList.length}
|
|
|
+ onChange={handleCheckAllChange}
|
|
|
+ ></Checkbox>
|
|
|
+ }
|
|
|
+ label={selectedValue.length == lovList.length ? "Deselect All" : "Select All"}
|
|
|
/>
|
|
|
</Box>
|
|
|
- )}
|
|
|
+ ) : null}
|
|
|
<List sx={listSx} id={id}>
|
|
|
{lovList
|
|
|
.filter((elt) => showItem(elt, searchValue))
|