Commit 332c9526 authored by Maksym Tishchenko's avatar Maksym Tishchenko
Browse files

Filtering by Created by, Created date, Modified by, and Modified date.

parent ee4bcf4d
import * as QueryString from 'query-string';
import { AxiosInstance, AxiosRequestConfig } from 'axios';
import AclSid from "@gringlobal-ce/client/model/acl/AclSid";
const URL_AUTOCOMPLETE_ACL_SID = `/api/v1/aclsid/autocomplete`;
/**
* AclSid service
*
* GRIN-Global CE API
*/
class AclSidService {
private _axios: AxiosInstance;
public constructor(axios: AxiosInstance) {
this._axios = axios;
}
/**
* autocompleteAclSid at /api/v1/aclsid/autocomplete
*
* @param term undefined
* @param xhrConfig additional xhr config
*/
public autocompleteAclSid = (term?: string, xhrConfig?: AxiosRequestConfig): Promise<AclSid[]> => {
const qs = QueryString.stringify({
term: term || undefined,
}, {});
const apiUrl = URL_AUTOCOMPLETE_ACL_SID + (qs ? `?${qs}` : '');
// console.log(`Fetching from ${apiUrl}`);
const content = { /* No content in request body */ };
return this._axios.request({
...xhrConfig,
url: apiUrl,
method: 'GET',
...content,
}).then(({ data }) => data as AclSid[]);
}
}
export default AclSidService;
......@@ -30,7 +30,7 @@ class OAuthManagementService {
* @param filter filter
* @param page = paged query
*/
public filter = (filter: string | OAuthClientFilter, page: IPageRequest, xhrConfig?: AxiosRequestConfig): Promise<OAuthClientFilteredPage> => {
public filter = (filter: string | Partial<OAuthClientFilter>, page: IPageRequest, xhrConfig?: AxiosRequestConfig): Promise<OAuthClientFilteredPage> => {
const qs = QueryString.stringify({
f: typeof filter === 'string' ? filter : undefined,
......
import AclSidService from "@gringlobal-ce/client/service/AclSidService";
import AuditLogService from '@gringlobal-ce/client/service/AuditLogService';
import CooperatorService from '@gringlobal-ce/client/service/CooperatorService';
import UserService from '@gringlobal-ce/client/service/UserService';
......@@ -108,6 +109,7 @@ export const reconfigureServiceAxios = ({ apiUrl, accessToken, origin, timeout,
const ConfiguredSecurityService = new SecurityService();
const ConfiguredUISecurity = makeUISecurity(ConfiguredSecurityService);
const ConfiguredAclSidService = new AclSidService(serviceAxios)
const ConfiguredAuditLogService = new AuditLogService(serviceAxios)
const ConfiguredTaxonomyService = new TaxonomyService(serviceAxios);
const ConfiguredCooperatorService = new CooperatorService(serviceAxios);
......@@ -151,6 +153,7 @@ const ConfiguredGenesysService = new GenesysService(serviceAxios)
export {
ConfiguredSecurityService as SecurityService,
ConfiguredUISecurity as UISecurity,
ConfiguredAclSidService as AclSidService,
ConfiguredAuditLogService as AuditLogService,
ConfiguredCooperatorService as CooperatorService,
ConfiguredUserService as UserService,
......
......@@ -5,6 +5,7 @@ import { useTranslation } from 'react-i18next';
// UI
import { withFilters, TextFilter, StringArrFilter, NumberFilter, DateFilter, BooleanFilter, CVFilter , SiteFilter } from 'ui/common/filter';
import AccessionInvGroupFilter from "common/AccessionInvGroupFilter";
import AclSidFilter from "common/AclSidFilter";
export function AccessionFiltersEmbedded({ prefix = '', withFullText = true }: { prefix?: string, withFullText?: boolean }) {
const { t } = useTranslation();
......@@ -105,6 +106,22 @@ export function AccessionFiltersEmbedded({ prefix = '', withFullText = true }: {
label={ t(['client:model.Accession.isWebVisible', 'client:model._.isWebVisible']) }
name={ `${prefix}webVisible` }
/>
<AclSidFilter
label={ t('client:model._.createdBy') }
name={ `${prefix}createdBy` }
/>
<DateFilter
label={ t('client:model._.createdDate') }
name={ `${prefix}createdDate` }
/>
<AclSidFilter
label={ t('client:model._.modifiedBy') }
name={ `${prefix}modifiedBy` }
/>
<DateFilter
label={ t('client:model._.modifiedDate') }
name={ `${prefix}modifiedDate` }
/>
</>
);
}
......
import * as React from 'react';
import { createUseStyles } from 'react-jss';
import { HighlightOff as Clear } from '@material-ui/icons';
import { Field, FieldProps, useForm } from 'react-final-form';
import { FieldArray } from 'react-final-form-arrays';
// ui
import { WithStyles } from '@material-ui/core/styles';
import { AclSidService, OAuthManagementService, UserService } from "@gringlobal-ce/client/service";
import { OAuthClient, SysUser } from "@gringlobal-ce/client/model/gringlobal";
import Autocomplete from "@gringlobal-ce/client/ui/common/form/Autocomplete";
const useStyles = createUseStyles((theme) => ({
stringArrElement: {
margin: '.2rem 0',
padding: '.2rem 1rem',
backgroundColor: '#e8e5e1',
color: '#202222',
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
},
stringArrElementText: {
display: 'inline-block',
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
},
removeIcon: {
cursor: 'pointer',
color: '#6f6f6f',
fontSize: '20px',
},
}));
interface IAclSidFilter extends FieldProps<any, any> {
name: string;
label: string;
placeholder?: string;
}
const StringArrElement = ({ arrElem, remove, classes }: { arrElem: string, remove: () => void } & WithStyles) => {
return <div>
<div className={ classes.stringArrElement }>
<span className={ classes.stringArrElementText }>
{arrElem}
</span>
<div className="font-bold float-right" onClick={ remove }><Clear className={ classes.removeIcon }/></div>
</div>
</div>
};
const AclSidFilter = ({ name, label, endAdornment, ...other }: IAclSidFilter) => {
// util
const classes = useStyles();
const { mutators, change, getFieldState } = useForm();
const [ clientsData, setClientsData ] = React.useState([])
// effect
React.useEffect( () => {
const fieldValue = getFieldState(name)?.value
if (!fieldValue) {
return
}
getClientsData(fieldValue)
.catch((err) => {
console.log('Could not fetch users list', err);
})
}, []);
const getClientsData = async (fieldValue) => {
try {
const users = await UserService.listUsers({ id: fieldValue }, { size: 500 })
const clients = await OAuthManagementService.filter({ id: fieldValue }, { size: 500 })
setClientsData([ ...users.content, ...clients.content ]);
} catch (err) {
console.log('Could not fetch users list', err);
}
}
// callback
const maybeAdd = React.useCallback((val: SysUser) => {
if (!val) {
return;
}
if (getFieldState(name)?.value?.length > 0 && getFieldState(name)?.value.includes(val.id)) {
change('temp', undefined);
return;
}
setClientsData([ ...clientsData, val ])
mutators.push(name, val.id);
change('temp', undefined);
}, [ mutators, clientsData, setClientsData, name ]);
const maybeRemove = React.useCallback((index) => {
mutators.remove(name, index);
}, [ clientsData, setClientsData ])
const handleKeyPress = React.useCallback((event: KeyboardEvent) => {
if (event.key === 'Enter') {
if (getFieldState(`temp.${name}`).value) {
event.preventDefault();
maybeAdd(getFieldState(`temp.${name}`).value);
}
}
}, [ name, maybeAdd ]);
const renderOption = (data: SysUser | OAuthClient, state?: any) => <>{ data.fullName }</>
const optionLabel = (data: SysUser | OAuthClient): string => `${data.fullName}`;
const mapOptions = (page) => page;
const autocomplete = (text: string) => {
return AclSidService.autocompleteAclSid(text)
};
const transformOption = (option: SysUser | OAuthClient | number[]): any => {
return typeof option[0] === 'number' ? {id: option[0]} : option;
}
return (
<>
<Field
name={ `temp.${name}` }
component={ Autocomplete }
label={ label }
autocomplete={ autocomplete }
renderOption={ renderOption }
mapOptions={ mapOptions }
transformOption={ transformOption }
getOptionLabel={ optionLabel }
onBlur={ () => maybeAdd(getFieldState(`temp.${name}`).value) }
onKeyPress={ handleKeyPress }
{ ...other }
/>
<FieldArray name={ name }>
{({ fields }) => (
<>
{fields?.value && fields.value.map((field, index) => {
const client = clientsData.find((clientData) => +clientData.id === +field)
return <StringArrElement
arrElem={ client ? `${client.sid}` : field }
remove={ () => maybeRemove(index) }
classes={ classes }
key={ `${field}-${index}` }
/>
})}
</>
)}
</FieldArray>
</>
);
}
export default AclSidFilter;
......@@ -6,6 +6,7 @@ import { Inventory } from '@gringlobal-ce/client/model/gringlobal';
// UI
import { withFilters, TextFilter, StringArrFilter, NumberFilter, DateFilter, BooleanFilter, CVFilter, SiteFilter, IMPFilter } from 'ui/common/filter';
import AccessionInvGroupFilter from "common/AccessionInvGroupFilter";
import AclSidFilter from "common/AclSidFilter";
export function InventoryFiltersEmbedded({ prefix = '', allowSystem = true, withFullText = true }: { prefix?: string, allowSystem?: boolean, withFullText?: boolean }) {
const { t } = useTranslation();
......@@ -47,10 +48,10 @@ export function InventoryFiltersEmbedded({ prefix = '', allowSystem = true, with
label={ t([ 'client:model.Accession.accessionNumber', 'client:model._.accessionNumber' ]) }
name={ `${prefix}accession.accessionNumber` }
/>
<AccessionInvGroupFilter
label={ t([ 'client:model.AccessionInvGroup.groupName', 'client:model._.groupName' ]) }
name={ `${prefix}accessionInvGroup` }
/>
<AccessionInvGroupFilter
label={ t([ 'client:model.AccessionInvGroup.groupName', 'client:model._.groupName' ]) }
name={ `${prefix}accessionInvGroup` }
/>
<NumberFilter
label={ t([ 'client:model.Inventory.quantityOnHand' ]) }
name={ `${prefix}quantityOnHand` }
......@@ -101,6 +102,22 @@ export function InventoryFiltersEmbedded({ prefix = '', allowSystem = true, with
label={ t([ 'client:model.Inventory.storageLocationPart4' ]) }
name={ `${prefix}storageLocationPart4.eq` }
/>
<AclSidFilter
label={ t('client:model._.createdBy') }
name={ `${prefix}createdBy` }
/>
<DateFilter
label={ t('client:model._.createdDate') }
name={ `${prefix}createdDate` }
/>
<AclSidFilter
label={ t('client:model._.modifiedBy') }
name={ `${prefix}modifiedBy` }
/>
<DateFilter
label={ t('client:model._.modifiedDate') }
name={ `${prefix}modifiedDate` }
/>
</>
);
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment