Skip to content

Commit

Permalink
JNG-5905 Fix tags component (#454)
Browse files Browse the repository at this point in the history
* fix tags component

* fix template

* fix template
  • Loading branch information
Madmat8 authored Sep 4, 2024
1 parent e0c81d9 commit 08ddb45
Showing 1 changed file with 48 additions and 48 deletions.
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
{{> fragment.header.hbs }}

import { type MouseEvent, type SyntheticEvent, useCallback, useMemo, useState, useRef, useEffect } from 'react';
import clsx from 'clsx';
import InputAdornment from '@mui/material/InputAdornment';
import Autocomplete from '@mui/material/Autocomplete';
import ButtonGroup from '@mui/material/ButtonGroup';
import CircularProgress from '@mui/material/CircularProgress';
import IconButton from '@mui/material/IconButton';
import Autocomplete from '@mui/material/Autocomplete';
import InputAdornment from '@mui/material/InputAdornment';
import TextField from '@mui/material/TextField';
import { MdiIcon } from '~/components/MdiIcon';
import { debounce } from '@mui/material/utils';
import clsx from 'clsx';
import { type MouseEvent, type SyntheticEvent, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { MdiIcon } from '~/components/MdiIcon';
import { debounceInputs } from '~/config/general';
import { QueryCustomizer } from '~/services/data-api/common/QueryCustomizer';
import { FilterByTypesString } from '~/services/data-api/rest/FilterByTypesString';
import { StringOperation } from '~/services/data-api/model/StringOperation';
import { FilterByTypesString } from '~/services/data-api/rest/FilterByTypesString';

export interface TagsProps<P, T> {
id: string;
Expand All @@ -26,6 +26,7 @@ export interface TagsProps<P, T> {
helperText?: string;
editMode?: boolean;
autoCompleteAttribute: keyof T;
identifierAttribute: string | keyof T;
onAutoCompleteSearch: (searchText: string, preparedQueryCustomizer: QueryCustomizer<T>) => Promise<T[]>;
additionalMaskAttributes?: string[];
limitOptions?: number;
Expand All @@ -44,8 +45,8 @@ export interface TagsProps<P, T> {

/**
* Experimental Tags component to serve as an alternative to aggregation->association collections.
*/
export function Tags<P, T> (props: TagsProps<P, T>) {
*/
export function Tags<P, T>(props: TagsProps<P, T>) {
const {
id,
label,
Expand All @@ -67,10 +68,11 @@ export function Tags<P, T> (props: TagsProps<P, T>) {
createDialogTitle,
createDialogIcon = 'file-document-plus',
onClearDialogsClick,
clearTitle= 'Clear',
clearTitle = 'Clear',
clearIcon = 'close',
additionalMaskAttributes = [],
limitOptions = 10,
identifierAttribute,
} = props;
const [options, setOptions] = useState<any[]>([]);
const [loading, setLoading] = useState<boolean>(false);
Expand All @@ -79,24 +81,21 @@ export function Tags<P, T> (props: TagsProps<P, T>) {
const handleSearch = async (searchText: string) => {
try {
setLoading(true);
const filter: FilterByTypesString[] = (ownerData[name] as T[] ?? []).map((c: any) => ({
value: c[autoCompleteAttribute]!,
operator: StringOperation.notEqual,
}));
const filter: FilterByTypesString[] = [];
if (searchText) {
filter.push({
value: `%${searchText}%`,
operator: StringOperation.like,
});
}
const queryCustomizer: QueryCustomizer<any> = {
_mask: `{${autoCompleteAttribute as string}${additionalMaskAttributes.length ? (',' + additionalMaskAttributes.join(',')) : ''}}`,
_mask: `{${autoCompleteAttribute as string}${additionalMaskAttributes.length ? ',' + additionalMaskAttributes.join(',') : ''}}`,
[autoCompleteAttribute]: filter,
_orderBy: [
{
attribute: autoCompleteAttribute as string,
descending: false,
}
},
],
_seek: {
limit: limitOptions,
Expand All @@ -122,21 +121,27 @@ export function Tags<P, T> (props: TagsProps<P, T>) {
[ownerData],
);

const onChange = useCallback((event: SyntheticEvent, value: (string | any)[]) => {
// prevent useEffect below from triggering recursion
prevValues.current = value;
onValueChange(value as any);
}, [ownerData, onValueChange]);
const onChange = useCallback(
(event: SyntheticEvent, value: (string | any)[]) => {
// prevent useEffect below from triggering recursion
prevValues.current = value;
onValueChange(value as any);
},
[ownerData, onValueChange],
);

const onChipClicked = useCallback((event: MouseEvent) => {
const label = (event.target as HTMLSpanElement).textContent;
if (label) {
const data = (ownerData[name] as T[] ?? []).find((c: any) => c[autoCompleteAttribute] === label);
if (data && onItemClick) {
onItemClick(data);
const onChipClicked = useCallback(
(event: MouseEvent) => {
const label = (event.target as HTMLSpanElement).textContent;
if (label) {
const data = ((ownerData[name] as T[]) ?? []).find((c: any) => c[autoCompleteAttribute] === label);
if (data && onItemClick) {
onItemClick(data);
}
}
}
}, [ownerData, onItemClick]);
},
[ownerData, onItemClick],
);

useEffect(() => {
// prevent recursion
Expand All @@ -156,10 +161,11 @@ export function Tags<P, T> (props: TagsProps<P, T>) {
readOnly={readOnly}
options={options}
loading={loading}
value={ownerData[name] as T[] ?? []}
value={(ownerData[name] as T[]) ?? []}
disableClearable={true}
getOptionKey={(option) => option[identifierAttribute]}
getOptionLabel={(option) => option[autoCompleteAttribute] ?? ''}
isOptionEqualToValue={(option, value) => option[autoCompleteAttribute] === value[autoCompleteAttribute]}
isOptionEqualToValue={(option, value) => option[identifierAttribute] === value[identifierAttribute]}
onOpen={ () => {
setOptions([]); // always start with a clean slate
handleSearch('');
Expand Down Expand Up @@ -187,28 +193,22 @@ export function Tags<P, T> (props: TagsProps<P, T>) {
'TagsButtonGroup': true,
})}
>
{loading ? (
<CircularProgress color="inherit" size="1rem" className="TagsLoading" />
) : null}
{loading ? <CircularProgress color="inherit" size="1rem" className="TagsLoading" /> : null}
{!readOnly && onClearDialogsClick ? (
<IconButton disabled={disabled} onClick={onClearDialogsClick} title={clearTitle}>
<MdiIcon path={clearIcon} />
</IconButton>
) : null}
{(!readOnly && onCreateDialogsClick) ? <IconButton
disabled={disabled}
onClick={onCreateDialogsClick}
title={createDialogTitle}
>
<MdiIcon path={createDialogIcon} />
</IconButton> : null}
{(!readOnly && onSearchDialogsClick) ? <IconButton
disabled={disabled}
onClick={onSearchDialogsClick}
title={searchDialogTitle}
>
<MdiIcon path={searchDialogIcon} />
</IconButton> : null}
{!readOnly && onCreateDialogsClick ? (
<IconButton disabled={disabled} onClick={onCreateDialogsClick} title={createDialogTitle}>
<MdiIcon path={createDialogIcon} />
</IconButton>
) : null}
{!readOnly && onSearchDialogsClick ? (
<IconButton disabled={disabled} onClick={onSearchDialogsClick} title={searchDialogTitle}>
<MdiIcon path={searchDialogIcon} />
</IconButton>
) : null}
</ButtonGroup>
</InputAdornment>
),
Expand All @@ -221,4 +221,4 @@ export function Tags<P, T> (props: TagsProps<P, T>) {
} }
/>
);
};
}

0 comments on commit 08ddb45

Please sign in to comment.