-
+
diff --git a/src/components/ThirdPartyImage/ThirdPartyImage.module.css b/src/components/ThirdPartyImage/ThirdPartyImage.module.css
new file mode 100644
index 000000000..30395d61e
--- /dev/null
+++ b/src/components/ThirdPartyImage/ThirdPartyImage.module.css
@@ -0,0 +1,4 @@
+.main {
+ width: 48px;
+ height: 48px;
+}
diff --git a/src/components/ThirdPartyImage/ThirdPartyImage.tsx b/src/components/ThirdPartyImage/ThirdPartyImage.tsx
new file mode 100644
index 000000000..0063ec75c
--- /dev/null
+++ b/src/components/ThirdPartyImage/ThirdPartyImage.tsx
@@ -0,0 +1,9 @@
+import { Blockie } from 'decentraland-ui'
+import classNames from 'classnames'
+import styles from './ThirdPartyImage.module.css'
+import { Props } from './ThirdPartyImage.types'
+
+export const ThirdPartyImage = (props: Props) => {
+ const { thirdPartyId, className, shape } = props
+ return
+}
diff --git a/src/components/ThirdPartyImage/ThirdPartyImage.types.ts b/src/components/ThirdPartyImage/ThirdPartyImage.types.ts
new file mode 100644
index 000000000..a866ade10
--- /dev/null
+++ b/src/components/ThirdPartyImage/ThirdPartyImage.types.ts
@@ -0,0 +1,5 @@
+export type Props = {
+ className?: string
+ thirdPartyId: string
+ shape?: 'circle' | 'square'
+}
diff --git a/src/components/ThirdPartyImage/index.ts b/src/components/ThirdPartyImage/index.ts
new file mode 100644
index 000000000..130c7a89e
--- /dev/null
+++ b/src/components/ThirdPartyImage/index.ts
@@ -0,0 +1,2 @@
+export * from './ThirdPartyImage'
+export * from './ThirdPartyImage.types'
diff --git a/src/modules/collection/selectors.spec.ts b/src/modules/collection/selectors.spec.ts
index e05bcdd71..4e76745c8 100644
--- a/src/modules/collection/selectors.spec.ts
+++ b/src/modules/collection/selectors.spec.ts
@@ -223,6 +223,8 @@ describe('when getting the authorized collections', () => {
[thirdPartyId]: {
id: thirdPartyId,
managers: [address],
+ root: '',
+ isApproved: true,
contracts: [],
name: 'aName',
description: 'aDescription',
diff --git a/src/modules/curations/itemCuration/reducer.spec.ts b/src/modules/curations/itemCuration/reducer.spec.ts
index 282e8b98e..0a4420697 100644
--- a/src/modules/curations/itemCuration/reducer.spec.ts
+++ b/src/modules/curations/itemCuration/reducer.spec.ts
@@ -42,6 +42,8 @@ describe('when an action of type PUBLISH_THIRD_PARTY_ITEMS_REQUEST is called', (
thirdParty = {
id: '1',
name: 'a third party',
+ root: '',
+ isApproved: true,
description: 'some desc',
managers: ['0x1', '0x2'],
contracts: [],
@@ -72,6 +74,8 @@ describe('when an action of type PUBLISH_AND_PUSH_CHANGES_THIRD_PARTY_ITEMS_REQU
thirdParty = {
id: '1',
name: 'a third party',
+ root: '',
+ isApproved: true,
description: 'some desc',
managers: ['0x1', '0x2'],
contracts: [],
@@ -99,6 +103,8 @@ describe('when an action of type PUBLISH_THIRD_PARTY_ITEMS_SUCCESS is called', (
thirdParty = {
id: '1',
name: 'a third party',
+ root: '',
+ isApproved: true,
description: 'some desc',
managers: ['0x1', '0x2'],
contracts: [],
@@ -182,6 +188,8 @@ describe('when an action of type PUBLISH_THIRD_PARTY_ITEMS_FAILURE is called', (
thirdParty = {
id: '1',
name: 'a third party',
+ root: '',
+ isApproved: true,
description: 'some desc',
managers: ['0x1', '0x2'],
contracts: [],
@@ -208,6 +216,8 @@ describe('when an action of type PUBLISH_AND_PUSH_CHANGES_THIRD_PARTY_ITEMS_FAIL
thirdParty = {
id: '1',
name: 'a third party',
+ root: '',
+ isApproved: true,
description: 'some desc',
managers: ['0x1', '0x2'],
contracts: [],
diff --git a/src/modules/thirdParty/actions.ts b/src/modules/thirdParty/actions.ts
index eef8377d4..fdd1ea5b1 100644
--- a/src/modules/thirdParty/actions.ts
+++ b/src/modules/thirdParty/actions.ts
@@ -151,3 +151,18 @@ export const deployBatchedThirdPartyItemsFailure = (errors: ThirdPartyError[], e
export type DeployBatchedThirdPartyItemsRequestAction = ReturnType
export type DeployBatchedThirdPartyItemsSuccessAction = ReturnType
export type DeployBatchedThirdPartyItemsFailureAction = ReturnType
+
+// Disable Third Party
+
+export const DISABLE_THIRD_PARTY_REQUEST = '[Request] Disable Third Party'
+export const DISABLE_THIRD_PARTY_SUCCESS = '[Success] Disable Third Party'
+export const DISABLE_THIRD_PARTY_FAILURE = '[Failure] Disable Third Party'
+
+export const disableThirdPartyRequest = (thirdPartyId: ThirdParty['id']) => action(DISABLE_THIRD_PARTY_REQUEST, { thirdPartyId })
+export const disableThirdPartySuccess = (thirdPartyId: ThirdParty['id'], chainId: ChainId, txHash: string, thirdPartyName: string) =>
+ action(DISABLE_THIRD_PARTY_SUCCESS, { thirdPartyId, ...buildTransactionPayload(chainId, txHash, { thirdPartyId, thirdPartyName }) })
+export const disableThirdPartyFailure = (error: string) => action(DISABLE_THIRD_PARTY_FAILURE, { error })
+
+export type DisableThirdPartyRequestAction = ReturnType
+export type DisableThirdPartySuccessAction = ReturnType
+export type DisableThirdPartyFailureAction = ReturnType
diff --git a/src/modules/thirdParty/reducer.spec.ts b/src/modules/thirdParty/reducer.spec.ts
index aa074352b..28294aeac 100644
--- a/src/modules/thirdParty/reducer.spec.ts
+++ b/src/modules/thirdParty/reducer.spec.ts
@@ -10,10 +10,14 @@ import {
DEPLOY_BATCHED_THIRD_PARTY_ITEMS_SUCCESS,
deployBatchedThirdPartyItemsSuccess,
deployBatchedThirdPartyItemsFailure,
- DEPLOY_BATCHED_THIRD_PARTY_ITEMS_FAILURE
+ DEPLOY_BATCHED_THIRD_PARTY_ITEMS_FAILURE,
+ disableThirdPartyRequest,
+ disableThirdPartySuccess,
+ disableThirdPartyFailure
} from './actions'
import { INITIAL_STATE, thirdPartyReducer, ThirdPartyState } from './reducer'
import { ThirdParty } from './types'
+import { ChainId } from '@dcl/schemas'
describe('when an action of type FETCH_THIRD_PARTIES_REQUEST is called', () => {
it('should add a fetchThirdPartiesRequest to the loading array', () => {
@@ -29,6 +33,8 @@ describe('when an action of type FETCH_THIRD_PARTIES_SUCCESS is called', () => {
beforeEach(() => {
thirdParty = {
id: '1',
+ root: '',
+ isApproved: true,
name: 'a third party',
description: 'some desc',
managers: ['0x1', '0x2'],
@@ -115,3 +121,85 @@ describe('when reducing an DEPLOY_BATCHED_THIRD_PARTY_ITEMS_FAILURE action', ()
})
})
})
+
+describe('when reducing a DISABLE_THIRD_PARTY_REQUEST action', () => {
+ let state: ThirdPartyState
+
+ beforeEach(() => {
+ state = {
+ ...INITIAL_STATE,
+ error: 'Some error',
+ errors: [new ThirdPartyDeploymentError(mockedItem)]
+ }
+ })
+
+ it('should add the action to the loading array and clear the errors', () => {
+ expect(thirdPartyReducer(state, disableThirdPartyRequest('anId'))).toStrictEqual({
+ ...INITIAL_STATE,
+ loading: [disableThirdPartyRequest('anId')],
+ error: null,
+ errors: []
+ })
+ })
+})
+
+describe('when reducing a DISABLE_THIRD_PARTY_SUCCESS action', () => {
+ let state: ThirdPartyState
+ let thirdParty: ThirdParty
+
+ beforeEach(() => {
+ thirdParty = {
+ id: 'anId',
+ root: '',
+ isApproved: true,
+ name: 'a third party',
+ description: 'some desc',
+ managers: ['0x1', '0x2'],
+ contracts: [],
+ maxItems: '0',
+ totalItems: '0'
+ }
+ state = {
+ ...INITIAL_STATE,
+ loading: [disableThirdPartyRequest('anId')],
+ data: {
+ anId: thirdParty
+ }
+ }
+ })
+
+ it('should remove the corresponding request action from the loading state and set the third party as not approved', () => {
+ expect(thirdPartyReducer(state, disableThirdPartySuccess('anId', ChainId.MATIC_MAINNET, 'aTxHash', 'thirdPartyName'))).toStrictEqual({
+ ...INITIAL_STATE,
+ data: {
+ anId: {
+ ...thirdParty,
+ isApproved: false
+ }
+ },
+ loading: []
+ })
+ })
+})
+
+describe('when reducing a DISABLE_THIRD_PARTY_FAILURE action', () => {
+ let state: ThirdPartyState
+ let error: string
+
+ beforeEach(() => {
+ error = 'anError'
+ state = {
+ ...INITIAL_STATE,
+ loading: [disableThirdPartyRequest('anId')],
+ data: {}
+ }
+ })
+
+ it('should remove the corresponding request action from the loading state and set the error', () => {
+ expect(thirdPartyReducer(state, disableThirdPartyFailure(error))).toStrictEqual({
+ ...INITIAL_STATE,
+ loading: [],
+ error
+ })
+ })
+})
diff --git a/src/modules/thirdParty/reducer.ts b/src/modules/thirdParty/reducer.ts
index 22caa8fa0..889e2c040 100644
--- a/src/modules/thirdParty/reducer.ts
+++ b/src/modules/thirdParty/reducer.ts
@@ -19,7 +19,13 @@ import {
DeployBatchedThirdPartyItemsFailureAction,
DEPLOY_BATCHED_THIRD_PARTY_ITEMS_REQUEST,
DEPLOY_BATCHED_THIRD_PARTY_ITEMS_FAILURE,
- DEPLOY_BATCHED_THIRD_PARTY_ITEMS_SUCCESS
+ DEPLOY_BATCHED_THIRD_PARTY_ITEMS_SUCCESS,
+ DisableThirdPartySuccessAction,
+ DisableThirdPartyFailureAction,
+ DisableThirdPartyRequestAction,
+ DISABLE_THIRD_PARTY_SUCCESS,
+ DISABLE_THIRD_PARTY_REQUEST,
+ DISABLE_THIRD_PARTY_FAILURE
} from './actions'
import { ThirdParty } from './types'
@@ -50,11 +56,15 @@ type ThirdPartyReducerAction =
| DeployBatchedThirdPartyItemsRequestAction
| DeployBatchedThirdPartyItemsSuccessAction
| DeployBatchedThirdPartyItemsFailureAction
+ | DisableThirdPartySuccessAction
+ | DisableThirdPartyFailureAction
+ | DisableThirdPartyRequestAction
export function thirdPartyReducer(state: ThirdPartyState = INITIAL_STATE, action: ThirdPartyReducerAction): ThirdPartyState {
switch (action.type) {
case DEPLOY_BATCHED_THIRD_PARTY_ITEMS_REQUEST:
case FETCH_THIRD_PARTY_AVAILABLE_SLOTS_REQUEST:
+ case DISABLE_THIRD_PARTY_REQUEST:
case FETCH_THIRD_PARTIES_REQUEST: {
return {
...state,
@@ -78,6 +88,20 @@ export function thirdPartyReducer(state: ThirdPartyState = INITIAL_STATE, action
error: null
}
}
+ case DISABLE_THIRD_PARTY_SUCCESS: {
+ const { thirdPartyId } = action.payload
+ return {
+ ...state,
+ data: {
+ ...state.data,
+ [thirdPartyId]: {
+ ...state.data[thirdPartyId],
+ isApproved: false
+ }
+ },
+ loading: loadingReducer(state.loading, action)
+ }
+ }
case FETCH_THIRD_PARTY_AVAILABLE_SLOTS_SUCCESS: {
const { thirdPartyId, availableSlots } = action.payload
return {
@@ -100,6 +124,7 @@ export function thirdPartyReducer(state: ThirdPartyState = INITIAL_STATE, action
error: null
}
}
+ case DISABLE_THIRD_PARTY_FAILURE:
case FETCH_THIRD_PARTY_AVAILABLE_SLOTS_FAILURE:
case FETCH_THIRD_PARTIES_FAILURE: {
return {
diff --git a/src/modules/thirdParty/sagas.spec.ts b/src/modules/thirdParty/sagas.spec.ts
index 11ed72b62..983076ebb 100644
--- a/src/modules/thirdParty/sagas.spec.ts
+++ b/src/modules/thirdParty/sagas.spec.ts
@@ -12,6 +12,8 @@ import { ToastType } from 'decentraland-ui'
import { SHOW_TOAST } from 'decentraland-dapps/dist/modules/toast/actions'
import { Wallet } from 'decentraland-dapps/dist/modules/wallet/types'
import { closeModal } from 'decentraland-dapps/dist/modules/modal/actions'
+import { getChainIdByNetwork } from 'decentraland-dapps/dist/lib'
+import { sendTransaction } from 'decentraland-dapps/dist/modules/wallet/utils'
import { loginSuccess } from 'modules/identity/actions'
import { BuilderAPI } from 'lib/api/builder'
import { ThirdParty } from './types'
@@ -33,7 +35,10 @@ import {
publishAndPushChangesThirdPartyItemsSuccess,
deployBatchedThirdPartyItemsRequest,
deployBatchedThirdPartyItemsFailure,
- deployBatchedThirdPartyItemsSuccess
+ deployBatchedThirdPartyItemsSuccess,
+ disableThirdPartyFailure,
+ disableThirdPartyRequest,
+ disableThirdPartySuccess
} from './actions'
import { mockedItem } from 'specs/item'
import { getCollection } from 'modules/collection/selectors'
@@ -54,6 +59,9 @@ import { ThirdPartyAction } from 'modules/ui/thirdparty/types'
import { Item } from 'modules/item/types'
import { thirdPartySaga } from './sagas'
import { getPublishItemsSignature } from './utils'
+import { getThirdParty } from './selectors'
+import { ContractData, ContractName, getContract } from 'decentraland-transactions'
+import { ChainId, Network } from '@dcl/schemas'
jest.mock('modules/item/export')
jest.mock('@dcl/crypto')
@@ -81,6 +89,8 @@ beforeEach(() => {
thirdParty = {
id: '1',
name: 'test',
+ root: '',
+ isApproved: true,
description: 'aDescription',
managers: [],
contracts: [],
@@ -130,13 +140,25 @@ describe('when fetching third parties', () => {
{
id: '1',
name: 'a third party',
+ root: '',
+ isApproved: true,
description: 'some desc',
managers: ['0x1', '0x2'],
maxItems: '0',
totalItems: '0',
contracts: []
},
- { id: '2', name: 'a third party', description: 'some desc', managers: ['0x3'], maxItems: '0', totalItems: '0', contracts: [] }
+ {
+ id: '2',
+ name: 'a third party',
+ description: 'some desc',
+ managers: ['0x3'],
+ maxItems: '0',
+ totalItems: '0',
+ contracts: [],
+ root: '',
+ isApproved: true
+ }
]
})
@@ -647,3 +669,51 @@ describe('when handling the batched deployment of third party items', () => {
})
})
})
+
+describe('when handling the disabling of a third party', () => {
+ let contract: ContractData
+
+ beforeEach(() => {
+ contract = { address: '0xcontract', abi: [], version: '1', name: 'name', chainId: ChainId.MATIC_MAINNET }
+ })
+
+ describe('and the transaction fails', () => {
+ let errorMessage: string
+ beforeEach(() => {
+ errorMessage = 'Some Error Message'
+ })
+
+ it('should put a disable third party failure action with the error', () => {
+ return expectSaga(thirdPartySaga, mockBuilder, mockCatalystClient)
+ .provide([
+ [call(getChainIdByNetwork, Network.MATIC), ChainId.MATIC_MAINNET],
+ [select(getThirdParty, thirdParty.id), thirdParty],
+ [call(getContract, ContractName.ThirdPartyRegistry, ChainId.MATIC_MAINNET), contract],
+ [call(sendTransaction as any, contract, 'reviewThirdParties', [[thirdParty.id, false, []]]), throwError(new Error(errorMessage))]
+ ])
+ .put(disableThirdPartyFailure(errorMessage))
+ .dispatch(disableThirdPartyRequest(thirdParty.id))
+ .run({ silenceTimeout: true })
+ })
+ })
+
+ describe('and the transaction succeeds', () => {
+ let txHash: string
+ beforeEach(() => {
+ txHash = '0xtxHash'
+ })
+
+ it('should put a successful disable third party action with the transaction data', () => {
+ return expectSaga(thirdPartySaga, mockBuilder, mockCatalystClient)
+ .provide([
+ [select(getThirdParty, thirdParty.id), thirdParty],
+ [call(getChainIdByNetwork, Network.MATIC), ChainId.MATIC_MAINNET],
+ [call(getContract, ContractName.ThirdPartyRegistry, ChainId.MATIC_MAINNET), contract],
+ [call(sendTransaction as any, contract, 'reviewThirdParties', [[thirdParty.id, false, []]]), txHash]
+ ])
+ .put(disableThirdPartySuccess(thirdParty.id, ChainId.MATIC_MAINNET, txHash, thirdParty.name))
+ .dispatch(disableThirdPartyRequest(thirdParty.id))
+ .run({ silenceTimeout: true })
+ })
+ })
+})
diff --git a/src/modules/thirdParty/sagas.ts b/src/modules/thirdParty/sagas.ts
index 9244adf79..ab45eda70 100644
--- a/src/modules/thirdParty/sagas.ts
+++ b/src/modules/thirdParty/sagas.ts
@@ -69,10 +69,15 @@ import {
PUSH_CHANGES_THIRD_PARTY_ITEMS_SUCCESS,
PUSH_CHANGES_THIRD_PARTY_ITEMS_FAILURE,
PUBLISH_AND_PUSH_CHANGES_THIRD_PARTY_ITEMS_FAILURE,
- PUBLISH_AND_PUSH_CHANGES_THIRD_PARTY_ITEMS_SUCCESS
+ PUBLISH_AND_PUSH_CHANGES_THIRD_PARTY_ITEMS_SUCCESS,
+ DISABLE_THIRD_PARTY_REQUEST,
+ DisableThirdPartyRequestAction,
+ disableThirdPartyFailure,
+ disableThirdPartySuccess
} from './actions'
import { getPublishItemsSignature } from './utils'
import { ThirdParty } from './types'
+import { getThirdParty } from './selectors'
export function* getContractInstance(
contract: ContractName.ThirdPartyRegistry | ContractName.ChainlinkOracle,
@@ -95,6 +100,7 @@ export function* thirdPartySaga(builder: BuilderAPI, catalystClient: CatalystCli
yield takeEvery(PUBLISH_AND_PUSH_CHANGES_THIRD_PARTY_ITEMS_REQUEST, handlePublishAndPushChangesThirdPartyItemRequest)
yield takeEvery(PUBLISH_THIRD_PARTY_ITEMS_SUCCESS, handlePublishThirdPartyItemSuccess)
yield takeLatest(REVIEW_THIRD_PARTY_REQUEST, handleReviewThirdPartyRequest)
+ yield takeEvery(DISABLE_THIRD_PARTY_REQUEST, handleDisableThirdPartyRequest)
yield takeEvery(actionProgressChannel, handleUpdateApprovalFlowProgress)
yield takeEvery(
[
@@ -340,4 +346,17 @@ export function* thirdPartySaga(builder: BuilderAPI, catalystClient: CatalystCli
yield put(deployBatchedThirdPartyItemsSuccess(collection, deployedItemsCurations))
}
}
+
+ function* handleDisableThirdPartyRequest(action: DisableThirdPartyRequestAction) {
+ const { thirdPartyId } = action.payload
+ try {
+ const maticChainId: ChainId = yield call(getChainIdByNetwork, Network.MATIC)
+ const thirdParty: ThirdParty | null = yield select(getThirdParty, thirdPartyId)
+ const thirdPartyContract: ContractData = yield call(getContract, ContractName.ThirdPartyRegistry, maticChainId)
+ const txHash: string = yield call(sendTransaction as any, thirdPartyContract, 'reviewThirdParties', [[thirdPartyId, false, []]])
+ yield put(disableThirdPartySuccess(thirdPartyId, maticChainId, txHash, thirdParty?.name ?? 'Unknown Third Party Name'))
+ } catch (error) {
+ yield put(disableThirdPartyFailure(isErrorWithMessage(error) ? error.message : 'Unknown error'))
+ }
+ }
}
diff --git a/src/modules/thirdParty/selectors.spec.ts b/src/modules/thirdParty/selectors.spec.ts
index ea45bc32c..490881f20 100644
--- a/src/modules/thirdParty/selectors.spec.ts
+++ b/src/modules/thirdParty/selectors.spec.ts
@@ -1,13 +1,21 @@
import { Collection } from 'modules/collection/types'
import { RootState } from 'modules/common/types'
-import { DEPLOY_BATCHED_THIRD_PARTY_ITEMS_REQUEST, fetchThirdPartiesRequest } from './actions'
+import {
+ DEPLOY_BATCHED_THIRD_PARTY_ITEMS_REQUEST,
+ DISABLE_THIRD_PARTY_SUCCESS,
+ disableThirdPartyRequest,
+ fetchThirdPartiesRequest
+} from './actions'
import {
isThirdPartyManager,
getWalletThirdParties,
getCollectionThirdParty,
getItemThirdParty,
isDeployingBatchedThirdPartyItems,
- isLoadingThirdParties
+ isLoadingThirdParties,
+ getThirdParty,
+ isDisablingThirdParty,
+ hasPendingDisableThirdPartyTransaction
} from './selectors'
import { ThirdParty } from './types'
@@ -23,29 +31,35 @@ describe('Third Party selectors', () => {
thirdParty1 = {
id: 'urn:decentraland:mumbai:collections-thirdparty:thirdparty1',
name: 'a third party',
+ root: '',
description: 'some desc',
maxItems: '0',
totalItems: '0',
contracts: [],
- managers: [address, '0xa']
+ managers: [address, '0xa'],
+ isApproved: true
}
thirdParty2 = {
id: 'urn:decentraland:mumbai:collections-thirdparty:thirdparty2',
name: 'a third party',
+ root: '',
description: 'some desc',
maxItems: '0',
totalItems: '0',
contracts: [],
- managers: [address, '0xb']
+ managers: [address, '0xb'],
+ isApproved: true
}
thirdParty3 = {
id: 'urn:decentraland:mumbai:collections-thirdparty:thirdparty3',
name: 'a third party',
+ root: '',
description: 'some desc',
maxItems: '0',
totalItems: '0',
contracts: [],
- managers: ['0xc']
+ managers: ['0xc'],
+ isApproved: true
}
baseState = {
wallet: {
@@ -289,4 +303,147 @@ describe('Third Party selectors', () => {
})
})
})
+
+ describe('when getting a third party', () => {
+ describe('and the third party exists', () => {
+ let state: RootState
+
+ beforeEach(() => {
+ state = {
+ ...baseState,
+ thirdParty: {
+ data: {
+ [thirdParty1.id]: thirdParty1
+ }
+ }
+ } as any
+ })
+
+ it('should return the third party', () => {
+ expect(getThirdParty(state, thirdParty1.id)).toBe(thirdParty1)
+ })
+ })
+
+ describe('and the third party does not exist', () => {
+ let state: RootState
+
+ beforeEach(() => {
+ state = {
+ ...baseState,
+ thirdParty: {
+ data: {}
+ }
+ } as any
+ })
+
+ it('should return null', () => {
+ expect(getThirdParty(state, thirdParty1.id)).toBe(null)
+ })
+ })
+ })
+
+ describe('when checking if a third party is being disabled', () => {
+ let state: RootState
+
+ describe('and the disable third party request is being processed', () => {
+ beforeEach(() => {
+ state = {
+ ...baseState,
+ thirdParty: {
+ ...baseState.thirdParty,
+ loading: [disableThirdPartyRequest(thirdParty1.id)]
+ }
+ }
+ })
+
+ it('should return true', () => {
+ expect(isDisablingThirdParty(state)).toBe(true)
+ })
+ })
+
+ describe('and the disable third party request is not being processed', () => {
+ beforeEach(() => {
+ state = {
+ ...baseState,
+ thirdParty: {
+ ...baseState.thirdParty,
+ loading: []
+ }
+ }
+ })
+
+ it('should return false', () => {
+ expect(isDisablingThirdParty(state)).toBe(false)
+ })
+ })
+ })
+
+ describe('when checking if a disable third party transaction is pending', () => {
+ beforeEach(() => {
+ baseState = {
+ ...baseState,
+ transaction: {
+ ...baseState.transaction,
+ data: [
+ {
+ events: [],
+ hash: '0x123',
+ nonce: 1,
+ actionType: DISABLE_THIRD_PARTY_SUCCESS,
+ payload: { thirdPartyId: thirdParty1.id },
+ status: null,
+ from: address,
+ replacedBy: null,
+ timestamp: 0,
+ url: 'url',
+ isCrossChain: false,
+ chainId: 1
+ }
+ ]
+ }
+ } as RootState
+ })
+
+ describe('and the transaction is pending', () => {
+ beforeEach(() => {
+ baseState = {
+ ...baseState,
+ transaction: {
+ ...baseState.transaction,
+ data: [
+ {
+ ...baseState.transaction.data[0],
+ status: null
+ }
+ ]
+ }
+ } as RootState
+ })
+
+ it('should return true', () => {
+ expect(hasPendingDisableThirdPartyTransaction(baseState, thirdParty1.id)).toBe(true)
+ })
+ })
+
+ describe('and the transaction is not pending', () => {
+ beforeEach(() => {
+ baseState = {
+ ...baseState,
+ transaction: {
+ ...baseState.transaction,
+ data: [
+ {
+ ...baseState.transaction.data[0],
+ status: 'confirmed'
+ }
+ ]
+ }
+ } as RootState
+ })
+
+ it('should return false', () => {
+ expect(hasPendingDisableThirdPartyTransaction(baseState, thirdParty1.id)).toBe(false)
+ })
+ })
+ })
})
diff --git a/src/modules/thirdParty/selectors.ts b/src/modules/thirdParty/selectors.ts
index ef93bfd39..df5809788 100644
--- a/src/modules/thirdParty/selectors.ts
+++ b/src/modules/thirdParty/selectors.ts
@@ -3,10 +3,17 @@ import { getAddress } from 'decentraland-dapps/dist/modules/wallet/selectors'
import { isLoadingType } from 'decentraland-dapps/dist/modules/loading/selectors'
import { RootState } from 'modules/common/types'
import { Collection } from 'modules/collection/types'
+import { getPendingTransactions, Transaction } from 'decentraland-dapps/dist/modules/transaction'
import { Item } from 'modules/item/types'
import { ThirdPartyState } from './reducer'
import { ThirdParty } from './types'
-import { DEPLOY_BATCHED_THIRD_PARTY_ITEMS_REQUEST, FETCH_THIRD_PARTIES_REQUEST, FETCH_THIRD_PARTY_AVAILABLE_SLOTS_REQUEST } from './actions'
+import {
+ DEPLOY_BATCHED_THIRD_PARTY_ITEMS_REQUEST,
+ DISABLE_THIRD_PARTY_SUCCESS,
+ FETCH_THIRD_PARTIES_REQUEST,
+ DISABLE_THIRD_PARTY_REQUEST,
+ FETCH_THIRD_PARTY_AVAILABLE_SLOTS_REQUEST
+} from './actions'
import { getThirdPartyForCollection, getThirdPartyForItem, isUserManagerOfThirdParty } from './utils'
export const getState = (state: RootState) => state.thirdParty
@@ -28,6 +35,21 @@ export const getWalletThirdParties = createSelector Object.values(thirdParties).filter(thirdParty => thirdParty.managers.includes(address))
)
+export const hasPendingDisableThirdPartyTransaction = (state: RootState, thirdPartyId: string): boolean => {
+ const userAddress = getAddress(state)
+ return (
+ userAddress !== undefined &&
+ getPendingTransactions(state, userAddress).some(
+ (transaction: Transaction) =>
+ [DISABLE_THIRD_PARTY_SUCCESS].includes(transaction.actionType) && transaction.payload.thirdPartyId === thirdPartyId
+ )
+ )
+}
+
+export const getThirdParty = (state: RootState, id: string): ThirdParty | null => getData(state)[id] ?? null
+
+export const isDisablingThirdParty = (state: RootState): boolean => isLoadingType(getLoading(state), DISABLE_THIRD_PARTY_REQUEST)
+
export const getCollectionThirdParty = (state: RootState, collection: Collection): ThirdParty | null =>
getThirdPartyForCollection(getData(state), collection) ?? null
diff --git a/src/modules/thirdParty/types.ts b/src/modules/thirdParty/types.ts
index 9cc73f082..2a6483a53 100644
--- a/src/modules/thirdParty/types.ts
+++ b/src/modules/thirdParty/types.ts
@@ -2,9 +2,11 @@ import { ContractNetwork } from '@dcl/schemas'
export type ThirdParty = {
id: string
+ root: string
managers: string[]
name: string
description: string
+ isApproved: boolean
contracts: LinkedContract[]
maxItems: string
totalItems: string
diff --git a/src/modules/translation/languages/en.json b/src/modules/translation/languages/en.json
index efa7700b5..6f4853726 100644
--- a/src/modules/translation/languages/en.json
+++ b/src/modules/translation/languages/en.json
@@ -1423,7 +1423,8 @@
"disallowed_claim_mana": "Disallowed MANA to claim a new name",
"claim_name": "Claimed new name: \"{name}\".",
"reclaim_name": "Reclaimed the name: \"{subdomain}\".",
- "rescue_items": "Approved content of {count} {count, plural, one {item} other {items}} for {collectionName}"
+ "rescue_items": "Approved content of {count} {count, plural, one {item} other {items}} for {collectionName}",
+ "disable_third_party": "Disabled third party: {name}"
},
"transfer_page": {
"title": "Transfer",
@@ -1979,6 +1980,12 @@
"subtitle": "The collection will not be available anymore. Don't worry, you will be able to enable it again later.",
"tx_pending": "Waiting for the disable collection transaction to confirm",
"action": "Disable"
+ },
+ "disable_third_party": {
+ "title": "Disable Third Party",
+ "subtitle": "This third party will not be available anymore. This include all collections under this third party. Don't worry, you'll be able to enable it again later.",
+ "tx_pending": "Waiting for the disable third party transaction to confirm",
+ "action": "Disable"
}
}
},
diff --git a/src/modules/translation/languages/es.json b/src/modules/translation/languages/es.json
index cfa9eda35..642ddda71 100644
--- a/src/modules/translation/languages/es.json
+++ b/src/modules/translation/languages/es.json
@@ -1430,7 +1430,8 @@
"allowed_claim_mana": "Permitió el uso de MANA para reclamar un nuevo nombre",
"disallowed_claim_mana": "No permitió el uso de MANA para reclamar un nuevo nombre",
"claim_name": "Haz reclamado el nombre: \"{name}\".",
- "rescue_items": "Has aprobado el contenido de {count} {count, plural, one {item} other {items}} para la collección {collectionName}"
+ "rescue_items": "Has aprobado el contenido de {count} {count, plural, one {item} other {items}} para la collección {collectionName}",
+ "disable_third_party": "Has deshabilitado el proveedor: {name}"
},
"transfer_page": {
"title": "Transferir",
@@ -1997,6 +1998,12 @@
"subtitle": "Esta colleccion no estara mas disponible. Puedes habilitarla nuevamente en el futuro.",
"tx_pending": "Esperando a que se confirme la transacción de deshabilitado",
"action": "Deshabilitar"
+ },
+ "disable_third_party": {
+ "title": "Deshabilitar proveedor",
+ "subtitle": "Éste proveedor no estará más disponible. Ésto incluye todas las collecciones bajo éste proveedor. No te preocupes, podrás habilitarlo nuevamente luego.",
+ "tx_pending": "Esperando a la confirmación de la transacción para deshabilitar el proveedor",
+ "action": "Deshabilitar"
}
}
},
diff --git a/src/modules/translation/languages/zh.json b/src/modules/translation/languages/zh.json
index a70d7a179..d8003a911 100644
--- a/src/modules/translation/languages/zh.json
+++ b/src/modules/translation/languages/zh.json
@@ -1413,7 +1413,8 @@
"allowed_claim_mana": "允许MANA声明新名称",
"disallowed_claim_mana": "不允许MANA申请新名称",
"claim_name": "声明新名称:\"{name}\"。",
- "rescue_items": "您已批准 {count} 项目 的内容,用于 {collectionName} 集合"
+ "rescue_items": "您已批准 {count} 项目 的内容,用于 {collectionName} 集合",
+ "disable_third_party": "已禁用第三方:{name}"
},
"transfer_page": {
"title": "转移",
@@ -1979,6 +1980,12 @@
"subtitle": "此集合将不再可用。将来可以再次启用它。",
"tx_pending": "等待已禁用的交易得到确认。",
"action": "禁用"
+ },
+ "disable_third_party": {
+ "title": "禁用第三方",
+ "subtitle": "此第三方将不再可用。这包括此第三方下的所有集合。别担心,您稍后可以再次启用它。",
+ "tx_pending": "等待禁用第三方交易确认",
+ "action": "禁用"
}
}
},