lodash#uniq JavaScript Examples
The following examples show how to use
lodash#uniq.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: MappingProfilesFormContainer.js From ui-data-export with Apache License 2.0 | 6 votes |
isValidRecordTypesMatching = (selectedTransformations = [], selectedRecordTypes = []) => {
const isOnlySrsSelected = selectedRecordTypes.length === 1 && selectedRecordTypes[0] === FOLIO_RECORD_TYPES.SRS.type;
if (isEmpty(selectedTransformations) && !isOnlySrsSelected) {
return false;
}
const recordTypesInTransformations = uniq(selectedTransformations.map(({ recordType }) => recordType));
const validatedRecords = selectedRecordTypes.filter(recordType => recordType !== FOLIO_RECORD_TYPES.SRS.type);
return isEmpty(difference(recordTypesInTransformations, validatedRecords))
&& isEmpty(difference(validatedRecords, recordTypesInTransformations));
}
Example #2
Source File: networkService.js From web-wallet with Apache License 2.0 | 6 votes |
async getAllTransactions () {
try {
const rawTransactions = await this.childChain.getTransactions({ address: this.account });
const currencies = uniq(flatten(rawTransactions.map(i => i.inputs.map(input => input.currency))));
await Promise.all(currencies.map(i => getToken(i)));
return rawTransactions.map(i => {
return {
...i,
metadata: OmgUtil.transaction.decodeMetadata(String(i.metadata))
};
});
} catch (error) {
throw new WebWalletError({
originalError: error,
reportToSentry: false,
reportToUi: false
});
}
}
Example #3
Source File: index.js From hzero-front with Apache License 2.0 | 6 votes |
static getDerivedStateFromProps(nextProps, prevState) {
const { prevActiveMenus, openMenuKeys = [] } = prevState;
const { mainMenu, activeMenus = [] } = nextProps;
const curActiveMainMenu = activeMenus[activeMenus.length - 1];
if (
mainMenu === curActiveMainMenu || // 切换的Tab 属于当前菜单
prevActiveMenus !== activeMenus // 需要保证 不会每次都变化
) {
const selectedKeys = [];
const openKeys = [];
for (let i = 0; i < activeMenus.length - 1; i++) {
selectedKeys.push(`${activeMenus[i].id}`);
openKeys.push(`${activeMenus[i].id}`);
}
openKeys.pop();
return {
selectedKeys,
openMenuKeys: uniq([...openMenuKeys, ...openKeys]),
};
}
return null;
}
Example #4
Source File: index.js From hzero-front with Apache License 2.0 | 6 votes |
/**
* fetchList - 查询列表数据
* @param {object} [params = {}] - 查询参数
* @param {string} params.name - 目录/菜单名
* @param {string} params.parentName - 上级目录
*/
fetchList(params = {}, flag) {
const { dispatch } = this.props;
dispatch({ type: 'menuConfig/queryTreeList', params }).then((res) => {
if (res) {
const { rowKeys } = this.getRowKeys(res, params);
if (flag) {
this.setState({
expandedRowKeys: rowKeys,
});
window.sessionStorage.removeItem('hiam-menuConfig-expandedRowKeys');
} else {
const { expandedRowKeys } = this.state;
const arr = uniq(rowKeys.concat(expandedRowKeys));
this.setState({
expandedRowKeys: arr,
});
}
}
});
}
Example #5
Source File: index.js From hzero-front with Apache License 2.0 | 5 votes |
// 流量控制
@Bind()
async handleFlowLimit(record) {
const { monitorRuleId, urlPattern, timeWindowSize } = record.toData();
this.displayFormDS.create({ urlPattern, timeWindowSize });
this.flowLimitFormDS.setQueryParameter('monitorRuleId', monitorRuleId);
this.flowLimitFormDS.query();
Modal.open({
title: intl.get('hadm.apiLimit.view.title.flowControl').d('流量控制'),
drawer: true,
width: 520,
children: (
<div>
<Form dataSet={this.displayFormDS}>
<TextField name="urlPattern" disabled />
<TextField name="timeWindowSize" disabled />
</Form>
<Form dataSet={this.flowLimitFormDS}>
<SelectBox name="listMode">
<Option value="BLACK">
{intl.get('hadm.apiLimit.model.apiLimit.black').d('黑名单')}
</Option>
<Option value="WHITE">
{intl.get('hadm.apiLimit.model.apiLimit.white').d('白名单')}
</Option>
</SelectBox>
<TextField className={styles['input-item-style']} name="valueList" />
<NumberField
name="blacklistThreshold"
step={1}
help={intl
.get('hadm.apiLimit.model.apiLimit.autoAddToBlacklist')
.d('请求量超过该值,自动进入黑名单')}
showHelp="tooltip"
renderer={({ value }) => value}
/>
<Switch name="enabledFlag" />
</Form>
</div>
),
onOk: async () => {
if (await this.flowLimitFormDS.validate()) {
const {
apiLimitId = '',
blacklistThreshold = '',
enabledFlag = '',
listMode = '',
objectVersionNumber = '',
valueList = '',
_token = '',
} = this.flowLimitFormDS.current.toData();
const res = await flowLimit({
apiLimitId,
blacklistThreshold,
enabledFlag,
listMode,
monitorRuleId,
objectVersionNumber,
valueList: uniq(valueList),
_token,
});
this.tableDS.query();
return res;
} else {
return false;
}
},
onCancel: () => true,
afterClose: () => this.flowLimitFormDS.reset(),
});
}
Example #6
Source File: RequestsContainer.js From covidsos with MIT License | 5 votes |
fetchRequests() {
const {type} = this.state;
const isAuthorisedUser = isAuthorisedUserLoggedIn();
let url = isAuthorisedUser ? config.adminAllRequests : config.pendingRequests;
if (type) {
switch (type) {
case 'new':
url = config.newRequests;
break;
case 'in-progress':
url = config.inProgressRequests;
break;
case 'completed':
url = isAuthorisedUser ? config.adminCompletedRequests : config.completedRequests;
break;
default:
url = isAuthorisedUser ? config.adminPendingRequests : config.pendingRequests;
break;
}
}
makeApiCall(url, 'GET', {}, (response) => {
let allRequests = [];
if (type || !isAuthorisedUser) {
allRequests = this.addToArray(allRequests, response, type);
} else {
allRequests = this.addToArray(allRequests, response.unverified_requests, 'new');
allRequests = this.addToArray(allRequests, response.assigned_requests, 'in-progress');
allRequests = this.addToArray(allRequests, response.pending_requests, 'pending');
allRequests = this.addToArray(allRequests, response.completed_requests, 'completed');
}
let filterData = {
source: uniq(map(allRequests, 'source')),
city: uniq(map(allRequests, 'city')),
managed_by: uniqBy(
map(allRequests, ({managed_by, managed_by_id}) => ({managed_by, managed_by_id})),
'managed_by_id')
}
allRequests = this.sortRequestsByTime(allRequests);
this.setState({allRequests, requestsToDisplay: allRequests, filterData, isLoading: false});
}, false);
}
Example #7
Source File: index.js From cord-19 with Apache License 2.0 | 5 votes |
function Article({ id }) {
const url = new URL(window.location);
const { loading, response, error } = Get(
`/document/v1/covid-19/doc/docid/${id}`
).state();
if (loading) return <Loading message="Loading..." />;
if (error)
return <Error message={error.message || `Failed to load article #${id}`} />;
console.log(response);
const citations = uniq([
...(response.fields.cited_by || []),
...(response.fields.citations_inbound || [])
.map(c => c.source_id)
.filter(c => !isNaN(c)),
]);
const panes = [
{
menuItem: 'Similar articles by Sent-SciBERT',
render: () => <Related id={response.fields.id} specter={false} />,
},
{
menuItem: 'Similar articles by SPECTER',
render: () => <Related id={response.fields.id} specter={true} />,
},
{
menuItem: {
key: 'citations',
content: `${citations.length} citing articles`,
disabled: citations.length === 0,
},
render: () => (
<CitedBy
citedBy={citations}
offset={parseInt(url.searchParams.get('offset')) || 0}
total={citations.length}
onOffsetChange={offset => {
url.searchParams.set('offset', offset);
navigate(url);
}}
/>
),
},
];
return (
<React.Fragment>
<ContainerContent>
<Content {...response.fields} />
<Tab
panes={panes}
defaultActiveIndex={url.searchParams.get('tab') || 0}
onTabChange={(e, tabInfo) => {
// Reset all query params when changing tab
[...url.searchParams.keys()].forEach(k =>
url.searchParams.delete(k)
);
url.searchParams.set('tab', tabInfo.activeIndex);
navigate(url);
}}
/>
</ContainerContent>
<Footer />
</React.Fragment>
);
}
Example #8
Source File: cadastrapp.js From mapstore2-cadastrapp with GNU General Public License v3.0 | 4 votes |
/**
* Holds the state of cadastrapp.
* The shape of the state is the following:
* ```
* {
* loading: true | false // general loading flag
* loadingFlags: {} // object that contain loading flag, for various parts of the application.
* searchType: undefined // one of constant.SEARCH_TOOLS
* selectionType: undefined // one of constant.SELECTION_TYPE
* plots: [{ // an entry for each tab of the plot selection
* data: [{parcelle: "12345", ...}] // data of the tab
* selected: [parcelle1, parcelle2]
* }],
* configuration: { // the configuration from server. e.g.
* cadastreLayerIdParcelle: "geo_parcelle"
* cadastreWFSLayerName: "qgis:cadastrapp_parcelle"
* cadastreWFSURL: "https://domain.org/geoserver/wfs"
* cadastreWMSLayerName: "qgis:cadastrapp_parcelle"
* cadastreWMSURL: "https://domain.org/geoserver/wms"
* cnil1RoleName: "ROLE_EL_APPLIS_CAD_CNIL1"
* cnil2RoleName: "ROLE_EL_APPLIS_CAD_CNIL2"
* dateValiditeEDIGEO: "01/01/2018"
* dateValiditeMajic: "01/01/2018"
* maxRequest: "8"
* minNbCharForSearch: "3"
* minParacelleIdLength: "14"
* organisme: "Un service fourni par "
* pdfbasemapthumbnails: [{,…}, {,…}]
* pdfbasemaptitles: [{value: "Cadastre", key: "pdf.baseMap.0.title"},…]
* uFWFSLayerName: "qgis:cadastrapp_unite_fonciere"
* uFWFSURL: "https://domain.org/geoserver/wfs"
* }
* }
* ```
*
* @param {object} state the application state
* @param {object} action a redux action
*/
export default function cadastrapp(state = DEFAULT_STATE, action) {
const type = action.type;
switch (type) {
case SETUP:
return set('pluginCfg', action.cfg, state);
case SET_CONFIGURATION:
return set('configuration', action.configuration, state);
case LOADING: {
let newValue = action.value;
if (action.mode === 'count') {
const oldValue = get(state, `loadFlags.${action.name}`) ?? 0;
newValue = isNumber(newValue)
? newValue // set with passed value if number
: newValue
? oldValue + 1 // increment if true
: Math.max(oldValue - 1, 0); // decrement if false
}
// anyway sets loading to true
return set(action.name === "loading" ? "loading" : `loadFlags.${action.name}`, newValue, state);
}
case TOGGLE_SELECTION: {
const {selectionType} = action;
// if the current selection button is clicked, it turns off selection
return set("selectionType", selectionType, state);
}
case TOGGLE_SEARCH: {
const { searchType } = action;
// if the current search button is clicked, it closes the search section
return set("searchType", searchType, state);
}
case ADD_PLOTS: {
const { plots, target, activate = true } = action;
const {activePlotSelection = 0 } = state;
let targetPlotSelection = activePlotSelection;
let newState = state;
if (!isNil(target)) {
const targetIndex = isObject(target) ? findIndex(state.plots, {id: target.id}) : target;
// create
if (targetIndex < 0) {
newState = set(`plots`, [...state.plots, { ...EMPTY_PLOT_SELECTION, ...target }], state);
targetPlotSelection = newState.plots.length - 1;
} else {
newState = set(`plots[${targetIndex}]`, {...state.plots[targetIndex], ...target});
targetPlotSelection = targetIndex;
}
}
if (activate) {
newState = set(`activePlotSelection`, targetPlotSelection, newState);
}
// get the current selection or create a new one if it not exists.
let currentSelection = newState?.plots?.[targetPlotSelection] ?? EMPTY_PLOT_SELECTION;
// add every plot received and toggle selection if exist
plots.map(({ parcelle, ...other}) => {
// if exists, toggle selection
currentSelection = toggleSelection(currentSelection, parcelle);
// update/insert the value at the en
currentSelection = arrayUpsert(`data`, { parcelle, ...other }, {parcelle}, currentSelection);
});
// update with new values the state
return set(`plots[${targetPlotSelection}]`, currentSelection, newState);
}
case REMOVE_PLOTS: {
const { parcelles = []} = action;
const {activePlotSelection = 0 } = state;
// get the current selection or create a new one if it not exists.
let currentSelection = state?.plots?.[activePlotSelection] ?? EMPTY_PLOT_SELECTION;
currentSelection = {
...currentSelection,
data: currentSelection.data.filter(({ parcelle }) => !parcelles.includes(parcelle)),
selected: currentSelection.selected.filter(parcelle => !parcelles.includes(parcelle))
};
// update with new values the state
return set(`plots[${activePlotSelection}]`, currentSelection, state);
}
case SELECT_PLOTS:
case DESELECT_PLOTS: {
const { activePlotSelection = 0 } = state;
let currentSelection = state?.plots?.[activePlotSelection] ?? EMPTY_PLOT_SELECTION;
const {plots = []} = action;
const parcelles = plots.map(({ parcelle }) => parcelle);
const selected = action.type === SELECT_PLOTS
? uniq([...(currentSelection.selected || []), ...parcelles])
: (currentSelection.selected || []).filter(id => !parcelles.includes(id));
currentSelection = {
...currentSelection,
selected
};
return set(`plots[${activePlotSelection}]`, currentSelection, state);
}
case ADD_PLOT_SELECTION: {
const {plot = {}} = action;
const currentPlots = state?.plots ?? [];
return compose(
set(`plots`, [...currentPlots, { ...EMPTY_PLOT_SELECTION, ...plot}]),
set(`activePlotSelection`, state?.plots?.length ?? 0) // select the new tab
)(state);
}
case REMOVE_PLOT_SELECTION: {
const active = action.active ?? state.activePlotSelection;
const newPlots = [...state.plots.filter((_, i) => i !== active)];
return compose(
set(`plots`, newPlots),
set(`activePlotSelection`, Math.max(state.activePlotSelection - 1, 0))
)(state);
}
case SET_ACTIVE_PLOT_SELECTION: {
return set('activePlotSelection', action.active, state);
}
case SET_LAYER_STYLE: {
return set(`styles.${action.styleType}`, action.value, state);
}
case UPDATE_LAYER_STYLE: {
return set(`styles.${action.styleType}`, {...(state?.styles?.[action.styleType] ?? {}), ...action.values}, state);
}
case SET_STYLES: {
return set('styles', action.styles, state);
}
case SHOW_OWNERS: {
return compose(
set('owners.data', action.owners),
set('owners.show', true)
)(state);
}
case CLEAR_OWNERS: {
return set('owners', undefined, state);
}
case SHOW_LANDED_PROPERTIES_INFORMATION: {
return set('landedProperty.parcelle', action.parcelle, state);
}
case INFORMATION_UPDATE: {
return set(
`informationData["${action.parcelle}"]${action.path ? '.' + action.path : ''}`, action.data, state
);
}
case INFORMATION_CLEAR: {
return set(
`informationData`, undefined, state
);
}
case SAVE_BUBBLE_INFO: {
return set('infoBulle', action.data, state);
}
case PRINT_RESPONSE: {
return {...state, requestFormData: {...state.requestFormData, allowDocument: action.allowDocument, requestId: action.requestId}};
}
default:
return state;
}
}
Example #9
Source File: Home.js From web-wallet with Apache License 2.0 | 4 votes |
function Home () {
const dispatch = useDispatch();
const [ mobileMenuOpen, setMobileMenuOpen ] = useState(false);
const depositModalState = useSelector(selectModalState('depositModal'));
const transferModalState = useSelector(selectModalState('transferModal'));
const exitModalState = useSelector(selectModalState('exitModal'));
const mergeModalState = useSelector(selectModalState('mergeModal'));
const ledgerConnectModalState = useSelector(selectModalState('ledgerConnectModal'));
const walletMethod = useSelector(selectWalletMethod());
const transactions = useSelector(selectChildchainTransactions, isEqual);
const ethDeposits = useSelector(selectEthDeposits, isEqual);
const erc20Deposits = useSelector(selectErc20Deposits, isEqual);
const transactedTokens = useMemo(() => {
const depositedTokens = erc20Deposits.map(e => e.tokenInfo.currency);
if (ethDeposits.length !== 0) {
depositedTokens.push(eth);
}
const xputs = flatten(transactions
.filter(i => i.status !== 'Pending')
.map(i => [ ...i.inputs, ...i.outputs ])
);
const txTokens = xputs.map(i => i.currency);
return uniq([ ...txTokens, ...depositedTokens ]);
}, [ transactions ]);
useEffect(() => {
const body = document.getElementsByTagName('body')[0];
mobileMenuOpen
? body.style.overflow = 'hidden'
: body.style.overflow = 'auto';
}, [ mobileMenuOpen ]);
useEffect(() => {
for (const token of transactedTokens) {
dispatch(getExitQueue(token));
}
}, [ dispatch, transactedTokens ]);
// calls only on boot
useEffect(() => {
window.scrollTo(0, 0);
dispatch(fetchDeposits());
dispatch(fetchExits());
}, [ dispatch, transactedTokens ]);
useInterval(() => {
batch(() => {
// infura call
dispatch(fetchEthStats());
dispatch(checkPendingDepositStatus());
dispatch(checkPendingExitStatus());
// watcher only calls
dispatch(checkWatcherStatus());
dispatch(fetchBalances());
dispatch(fetchTransactions());
});
}, POLL_INTERVAL);
useInterval(() => {
dispatch(fetchFees());
dispatch(fetchGas());
}, POLL_INTERVAL * 10);
return (
<>
<DepositModal open={depositModalState} />
<TransferModal open={transferModalState} />
<ExitModal open={exitModalState} />
<MergeModal open={mergeModalState} />
<LedgerConnect
open={walletMethod === 'browser'
? ledgerConnectModalState
: false
}
/>
<div className={styles.Home}>
<div className={styles.sidebar}>
<img className={styles.logo} src={logo} alt='omg-network' />
<Status />
</div>
<div className={styles.main}>
<MobileHeader
mobileMenuOpen={mobileMenuOpen}
onHamburgerClick={() => setMobileMenuOpen(open => !open)}
/>
<MobileMenu mobileMenuOpen={mobileMenuOpen} />
<Account/>
<Transactions/>
</div>
</div>
</>
);
}
Example #10
Source File: apiManagementGroupDS.js From hzero-front with Apache License 2.0 | 4 votes |
function tableDS(formRecord) {
return {
dataKey: 'content',
cacheSelection: true,
fields: [
{
name: 'id',
type: 'string',
label: intl.get('hiam.apiManagement.model.apiManagement.id').d('权限id'),
unique: true,
},
{
name: 'code',
type: 'string',
label: intl.get('hiam.apiManagement.model.apiManagement.code').d('权限编码'),
},
{
name: 'path',
type: 'string',
label: intl.get('hiam.apiManagement.model.apiManagement.path').d('路径'),
},
{
name: 'method',
type: 'string',
label: intl.get('hiam.apiManagement.model.apiManagement.method').d('请求方式'),
},
{
name: 'methodMeaning',
type: 'string',
label: intl.get('hiam.apiManagement.model.apiManagement.methodMeaning').d('请求方式'),
},
{
name: 'fdLevel',
type: 'string',
label: intl.get('hiam.apiManagement.model.apiManagement.fieldLevel').d('权限层级'),
},
{
name: 'levelMeaning',
type: 'string',
label: intl.get('hiam.apiManagement.model.apiManagement.levelMeaning').d('权限层级'),
},
{
name: 'description',
type: 'intl',
label: intl.get('hiam.apiManagement.model.apiManagement.description').d('描述'),
maxLength: 1024,
},
{
name: 'action',
type: 'string',
label: intl.get('hiam.apiManagement.model.apiManagement.action').d('方法名'),
},
{
name: 'resource',
type: 'string',
label: intl.get('hiam.apiManagement.model.apiManagement.resource').d('资源类型'),
},
{
name: 'serviceName',
type: 'string',
label: intl.get('hiam.apiManagement.model.apiManagement.serviceName').d('服务名称'),
},
{
name: 'publicAccess',
type: 'number',
label: intl.get('hiam.apiManagement.model.apiManagement.publicAccess').d('是否公开接口'),
},
{
name: 'loginAccess',
type: 'number',
label: intl.get('hiam.apiManagement.model.apiManagement.loginAccess').d('是否登录可访问'),
},
{
name: 'within',
type: 'number',
label: intl.get('hiam.apiManagement.model.apiManagement.within').d('是否内部接口'),
},
{
name: 'signAccess',
type: 'number',
label: intl.get('hiam.apiManagement.model.apiManagement.signAccess').d('是否签名接口'),
},
{
name: 'objectVersionNumber',
type: 'number',
label: intl.get('hiam.apiManagement.model.apiManagement.objectVersionNumber').d('版本'),
},
{
name: 'tag',
type: 'string',
label: intl.get('hiam.apiManagement.model.apiManagement.tag').d('标签'),
},
{
name: 'pageTag',
type: 'string',
label: intl.get('hiam.apiManagement.model.apiManagement.pageTag').d('API标签'),
bind: 'apiTags.PAGE',
},
// {
// name: 'backgroundTag',
// type: 'string',
// label: intl.get('hiam.apiManagement.model.apiManagement.backgroundTag').d('后端API标识'),
// bind: 'apiTags.BACKEND',
// },
],
events: {
query: ({ dataSet }) => {
dataSet.unSelectAll();
dataSet.clearCachedSelected();
},
update: ({ record, dataSet, value, oldValue }) => {
// if (!isEmpty(dataSet.frontLabels)) {
if (isArray(value) || isArray(oldValue)) {
if ((value || []).sort().toString() !== (oldValue || []).sort().toString()) {
if (isEmpty(value)) {
const PAGE = uniq(
oldValue.filter((item) => {
return (dataSet.frontLabels || []).includes(item);
})
);
record.set('apiTags', { PAGE, BACKEND: [] });
} else if ((dataSet.frontLabels || []).includes(difference(oldValue, value)[0])) {
record.set('apiTags', { PAGE: oldValue, BACKEND: [] });
} else {
record.set('apiTags', { PAGE: value.sort(), BACKEND: [] });
}
}
} else if (isArray(value) && !isArray(oldValue)) {
record.set('apiTags', { PAGE: value.sort(), BACKEND: [] });
}
// }
},
},
transport: {
read: (config) => {
const { params } = config;
const url = isTenantRoleLevel()
? `${HZERO_IAM}/hzero/v1/${organizationId}/permissions`
: `${HZERO_IAM}/hzero/v1/permissions`;
let data = {};
if (formRecord.toData()[0]) {
const {
code = '',
path = '',
serviceName = '',
fdLevel = '',
method = '',
labels = '',
publicAccess = undefined,
loginAccess = undefined,
within = undefined,
signAccess = undefined,
} = formRecord.toData()[0];
const obj = {
publicAccess:
isUndefined(publicAccess) || publicAccess === null ? undefined : !!publicAccess,
loginAccess:
isUndefined(loginAccess) || loginAccess === null ? undefined : !!loginAccess,
within: isUndefined(within) || within === null ? undefined : !!within,
signAccess: isUndefined(signAccess) || signAccess === null ? undefined : !!signAccess,
};
data = filterNullValueObject({
code,
path,
serviceName,
fdLevel,
method,
labels,
...obj,
});
}
return {
data,
params,
url,
method: 'GET',
};
},
update: (config) => {
const url = isTenantRoleLevel()
? `${HZERO_IAM}/hzero/v1/${organizationId}/permissions/update`
: `${HZERO_IAM}/hzero/v1/permissions/update`;
const { data = [], dataSet } = config;
const { _status, apiTags, pageTag, ...other } = data[0];
const tags = (dataSet.labelList || [])
.filter((item) => {
return (data[0].apiTags.PAGE || []).includes(item.name);
})
.map((item) => ({ id: item.id, _token: item._token }));
return {
data: {
...other,
labels: tags,
},
url,
method: 'PUT',
};
},
destroy: (config) => {
const url = isTenantRoleLevel()
? `${HZERO_IAM}/hzero/v1/${organizationId}/permissions`
: `${HZERO_IAM}/hzero/v1/permissions`;
const { params = {}, data = [] } = config;
return {
data,
params,
url,
method: 'DELETE',
};
},
},
};
}