lodash#extend TypeScript Examples
The following examples show how to use
lodash#extend.
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: containerModule.ts From redux-with-domain with MIT License | 5 votes |
export default function createContainerModule<
State = {},
Selectors extends SelectorsOf<State> = SelectorsOf<State>,
Reducers extends ReducerOf<State> = ReducerOf<State>,
Effects = {},
ActionCreators = {}
>(
namespace: string,
pkg: {
initialState?: State
selectors?: Selectors
reducers?: Reducers
defaultReducer?: DefaultReducer<State>
effects?: EffectsOf<Selectors, Reducers, Effects>
effectLoading?: boolean
actionCreators?: ActionsOf<ActionCreators, Reducers, Effects, Selectors>
}
): KopContainerModule<Selectors, Reducers, Effects, ActionCreators> {
const module = initModule(pkg, namespace, CONTAINER_MODULE) as any
initInitialState(module, pkg)
initSelectors(module, pkg, namespace, CONTAINER_MODULE)
module.actions = {}
const { actions, effects, _reducers, event, actionCreators } = initActions(
module,
pkg,
namespace,
CONTAINER_MODULE,
getAuthCheck[CONTAINER_MODULE]
)
extend(module.actions, actionCreators, actions)
module._reducers = _reducers
module._defaultReducer = pkg.defaultReducer
module.event = event
if (effects) {
module.effects = effects
}
return module
}
Example #2
Source File: globalModule.ts From redux-with-domain with MIT License | 5 votes |
export default function createGlobalModule<
State = {},
Selectors extends SelectorsOf<State> = SelectorsOf<State>,
Reducers extends ReducerOf<State> = ReducerOf<State>,
Effects = {},
ActionCreators = {}
>(
namespace: string,
pkg: {
initialState?: State
selectors?: Selectors
reducers?: Reducers
effects?: EffectsOf<Selectors, Reducers, Effects>
effectLoading?: boolean
actionCreators?: ActionsOf<ActionCreators, Reducers, Effects, Selectors>
}
): KopGlobalModule<Selectors, Reducers, Effects, ActionCreators> {
const type = GLOBAL_MODULE
const module = initModule(pkg, namespace, type) as any
initInitialState(module, pkg)
initSelectors(module, pkg, namespace, type)
module.actions = {}
const { actions, effects, _reducers, event, actionCreators } = initActions(
module,
pkg,
namespace,
type,
getAuthCheck[type]
)
extend(module.actions, actionCreators, actions)
module._reducers = _reducers
module.event = event
if (effects) {
module.effects = effects
}
return module
}
Example #3
Source File: effects.ts From redux-with-domain with MIT License | 5 votes |
export default function createEffectsAndActions(
namespace: string,
normalActions,
selectors,
events,
effectsOpt
) {
const allActions = {}
const effectActions = {}
const sagaEffects = decorateSagaEffects(effects)
const moduleEffects = effectsOpt(allActions, selectors, sagaEffects, events)
const sagas: Function[] = []
forEach({ ...moduleEffects }, (value, type) => {
invariant(
!normalActions[type],
`Module ${namespace} action ${type} duplicated`
)
const actionType = getActionTypeWithNamespace(namespace, type)
let generator
let helper = effects.takeEvery // default helper is takeEvery
let args: Array<any> = []
if (isArray(value)) {
const helperName = value[1] // effect function
generator = value[0] // saga function
helper = effects[helperName]
invariant(
helper,
`Module ${namespace} effect ${type} use invalid helper ${helperName}`
)
if (!isUndefined(value[2])) {
args = value.slice(2)
}
} else {
generator = value
}
sagas.push(function*() {
// fix redux-saga's bug
// https://github.com/redux-saga/redux-saga/issues/1482
yield (helper as any)(actionType, generator, ...args)
})
effectActions[type] = createAction({
namespace,
actionType: type,
actionKind: ACTION_KIND.EFFECT,
kopFunction: generator
})
})
extend(allActions, normalActions, effectActions) // merge actions
return {
effectActions,
allActions,
effects: sagas
}
}
Example #4
Source File: effects.ts From redux-with-domain with MIT License | 5 votes |
// internal method for get effects and actions
function _getEffectsAndActions(
namespace,
normalActions,
selectors,
events,
effectsOpt,
moduleType,
effectLoading
) {
const allActions = {}
const { enhancer, sagaEffects } = getWrappedEffectOptions(
moduleType,
namespace,
events
)
const moduleEffects = effectsOpt({
enhancer,
selectors,
actions: allActions,
sagaEffects
})
const { sagaFns, effectActions } = transformEffects({
moduleEffects,
normalActions,
namespace,
moduleType,
effectLoading
})
extend(allActions, normalActions, effectActions) // merge actions
return {
effectActions,
allActions,
effects: sagaFns
}
}
Example #5
Source File: pageModule.ts From redux-with-domain with MIT License | 5 votes |
export default function createPageModule<
State,
Selectors extends SelectorsOf<State> = SelectorsOf<State>,
Reducers extends ReducerOf<State> = ReducerOf<State>,
Effects = {},
Watchers = {},
ActionCreators = {}
>(
namespace: string,
pkg: PageOptions<
State,
Selectors,
Reducers,
Effects,
Watchers,
ActionCreators
>
): KopPageModule<Selectors, Reducers, Effects, ActionCreators> {
const module = initModule(pkg, namespace, PAGE_MODULE) as any
initInitialState(module, pkg)
initSelectors(module, pkg, namespace, PAGE_MODULE)
initInjectModules(module, pkg)
module.actions = {}
const { actions, effects, _reducers, event, actionCreators } = initActions(
module,
pkg,
namespace,
PAGE_MODULE,
getAuthCheck[PAGE_MODULE]
)
extend(module.actions, actionCreators, actions)
if (effects) {
module.effects = effects
}
module._reducers = _reducers
module._defaultReducer = pkg.defaultReducer
module.event = event
initPageWatchers(module, pkg)
return module
}
Example #6
Source File: createApp.tsx From redux-with-domain with MIT License | 4 votes |
export default function createApp(createOpt: CreateOpt = {}) {
let app: App
const { initialReducer, onError } = createOpt
// internal map for modules
const _modules: Modules = {}
let _router = <div />
const _middleWares: Middleware<{}>[] = [...defaultMiddleWares]
const sagaMiddleware: SagaMiddleware<{}> = createSagaMiddleware()
_middleWares.push(sagaMiddleware)
function hasSubModule(module: Module) {
let flag = false
forEach(module, value => {
if (isModule(value)) {
flag = true
}
})
return flag
}
function _addModule(m: Module) {
invariant(!_modules[m.namespace], `kop nodule ${m.namespace} exists`)
if (!isEmpty(m.entities)) {
forEach(m.entities, e => {
_addModule(e)
})
}
_modules[m.namespace] = m
}
// create reducer
// http://redux.js.org/docs/recipes/reducers/RefactoringReducersExample.html
function createReducer(
initialState = {},
handlers: ReducerHandler,
defaultReducer?: DefaultReducer<any>
) {
return (state = initialState, action: Action) => {
if (
Object.prototype.hasOwnProperty.call(handlers, action.type) &&
isFunction(handlers[action.type])
) {
const handler = handlers[action.type]
return handler(state, action)
}
if (defaultReducer && isFunction(defaultReducer)) {
return defaultReducer(state, action)
}
return state
}
}
function loopCombineReducer(
tree: any,
combineRootreducer = true,
parentNode?: string | ParentNode
) {
const childReducer: any = mapValues(tree, node => {
if (!isModule(node)) {
return loopCombineReducer(node)
}
if (hasSubModule(node)) {
const subModuleMap = pickBy(node, value => isModule(value))
return loopCombineReducer(subModuleMap, true, node)
}
return createReducer(
node._initialState,
node._reducers,
node._defaultReducer
)
})
let result
if (isEmpty(parentNode)) {
result = {
...childReducer
}
} else if (parentNode === 'root') {
invariant(
!initialReducer || isPlainObject(initialReducer),
'initialReducer should be object'
)
const noDuplicatedKeys = !hasDuplicatedKeys(
initialReducer,
childReducer,
'router'
)
invariant(
noDuplicatedKeys,
'initialReducer has reduplicate keys with other reducers'
)
result = {
...initialReducer,
...childReducer
}
} else {
result = {
base: createReducer(
(parentNode as ParentNode)._initialState,
(parentNode as ParentNode)._reducers,
(parentNode as ParentNode)._defaultReducer
),
...childReducer
}
}
if (parentNode === 'root' && !combineRootreducer) return result
return combineReducers(result)
}
function addModule(module: Module | Module[]) {
if (isArray(module)) {
module.forEach(m => {
_addModule(m)
})
} else {
_addModule(module)
}
}
function initInjectModules(presenter: Presenter) {
forEach(presenter.injectModules, (name: string) => {
invariant(_modules[name], `please check the kop-module ${name} is added`)
extend(_modules[name].presenter, {
loaded: true, // 标记已被装载,在module中会注入 presentor 的 seletor
selectors: presenter.selectors,
actions: presenter.actions
})
})
}
function createRootReducer(combineRootreducer = true) {
const moduleData = cloneDeepWith(_modules)
const moduleTree = reduce(
moduleData,
(result, value, key) => {
const module = get(result, toStorePath(key))
if (isModule(value)) {
if (module) {
return set(result, `${toStorePath(key)}.base`, value)
}
return set(result, toStorePath(key), value)
}
return result
},
{}
)
return loopCombineReducer(moduleTree, combineRootreducer, 'root')
}
function addPage(pageModule: Module, opt: PageOption = {}) {
const { containers } = opt
if (containers && containers.length > 0) {
addModule(containers)
}
if (pageModule.injectModules && pageModule.injectModules.length > 0) {
initInjectModules(pageModule)
}
addModule(pageModule)
}
function addDomain(module: Module) {
addModule(module)
}
const addGlobal = _addModule
function removeModule(module: Module | Module[]) {
const _remove = (m: Module) => {
invariant(
_modules[m.namespace],
`error: the kop-module - ${m.namespace} is not existed`
)
// hack redux-devtools's bug
if (
m &&
m.actions &&
!isPresenter(m) &&
m.type !== DOMAIN_MODULE &&
(window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
) {
_store.dispatch(m.actions.__reset())
}
delete _modules[m.namespace]
_store.dispatch({ type: `${m.namespace}/@@KOP_CANCEL_EFFECTS` })
}
if (isArray(module)) {
module.forEach(m => {
_remove(m)
})
_store.replaceReducer(createRootReducer() as Reducer)
} else if (module) {
_remove(module)
_store.replaceReducer(createRootReducer() as Reducer)
}
}
function addRouter(r: JSX.Element) {
_router = r
}
function addMiddleWare(middleWare: Middleware) {
const add = (m: Middleware) => {
_middleWares.push(m)
}
add(middleWare)
}
function getStore() {
return _store
}
function createAppStore() {
// inject chrome redux devtools
let composeEnhancers
if (
process.env.NODE_ENV !== 'production' &&
(window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
) {
composeEnhancers = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
} else {
composeEnhancers = compose
}
const enhancer = composeEnhancers(applyMiddleware(..._middleWares))
const rootReducer = createRootReducer()
return createStore(rootReducer as Reducer, enhancer)
}
function getArguments(...args: any[]) {
let domSelector: string | null = null
let callback = noop
if (args.length === 1) {
// app.start(false) means jump render phase and return early
if (args[0] === false) {
return {
domSelector: '',
callback: noop,
shouldRender: false
}
}
if (isString(args[0])) {
domSelector = args[0]
}
if (isFunction(args[0])) {
callback = args[0]
}
}
if (args.length === 2) {
domSelector = args[0]
callback = args[1]
}
return {
domSelector,
callback,
shouldRender: true
}
}
function renderAppElement(
domSelector: string | null,
callback: Function,
shouldRender: boolean
) {
const $elem = <Provider store={_store}>{_router}</Provider>
// skip render when shouldRender is false
if (shouldRender) {
if (isString(domSelector)) {
render($elem, document.querySelector(domSelector), () => {
callback()
})
} else if (isElement(domSelector)) {
render($elem, domSelector, () => {
callback()
})
} else {
callback()
}
}
return $elem
}
function _onError(e: Error) {
if (!onError) {
console.error(e)
} else {
onError(e)
}
}
// create root saga
function createSaga(module: Module) {
return function*() {
if (isArray(module.effects)) {
for (let i = 0, k = module.effects.length; i < k; i++) {
const task = yield effects.fork(function*(): any {
try {
if (module.effects) {
yield module.effects[i]()
}
} catch (e) {
_onError(e)
}
})
yield effects.fork(function*() {
yield effects.take(`${module.namespace}/@@KOP_CANCEL_EFFECTS`)
yield effects.cancel(task)
})
}
}
if (isArray(module.watchers)) {
for (let i = 0, k = module.watchers.length; i < k; i++) {
const task = yield effects.fork(function*(): any {
try {
if (module.watchers) {
yield module.watchers[i]()
}
} catch (e) {
_onError(e)
}
})
yield effects.fork(function*() {
yield effects.take(`${module.namespace}/@@KOP_CANCEL_EFFECTS`)
yield effects.cancel(task)
})
}
}
}
}
function start(...args: any[]) {
const { domSelector, callback, shouldRender } = getArguments(...args)
_store = createAppStore()
initSelectorHelper(_store)
app._store = _store
window[KOP_GLOBAL_STORE_REF] = _store
app._modules = _modules
forEach(app._modules, (m: Module) => {
if (m.type === ENTITY_MODULE) {
m._store = _store // 提供domainModel的遍历action
}
})
app._middleWares = _middleWares
app._router = _router
forEach(_modules, module => {
sagaMiddleware.run(createSaga(module))
})
return renderAppElement(domSelector, callback, shouldRender)
}
// 集成模式初始化,返回 saga,reducer 等等
function _init() {
const rootReducer = createRootReducer(false)
return {
rootReducer,
sagaMiddleware
}
}
// 集成模式启动,由外部 Redux 控制 App 渲染流程
function _run(store: Store<any, AnyAction>) {
initSelectorHelper(store)
app._store = store
window[KOP_GLOBAL_STORE_REF] = store
app._modules = _modules
forEach(app._modules, (m: Module) => {
if (m.type === ENTITY_MODULE) {
m._store = store
}
})
app._router = _router
forEach(_modules, module => {
sagaMiddleware.run(createSaga(module))
})
}
app = {
addModule, // register container module
addPage, // register page module
addDomain, // register domain module
addGlobal, // register global module
addRouter,
addMiddleWare,
start,
getStore,
removeModule,
_init,
_run
}
return app
}
Example #7
Source File: test-case.ts From erda-ui with GNU Affero General Public License v3.0 | 4 votes |
testCaseStore = createStore({
name: 'testCase',
state: initState,
effects: {
async getCaseDetail(
{ call, update, getParams },
payload: Merge<TEST_CASE.QueryCaseDetail, { scope: 'testPlan' | 'testCase' }>,
) {
const { testPlanId } = getParams();
let issueBugs: TEST_CASE.RelatedBug[] = [];
let caseDetail = {} as TEST_CASE.CaseDetail;
if (payload.scope === 'testPlan') {
const {
issueBugs: relationBugs,
execStatus,
apiCount,
testCaseID,
id,
} = await call(getDetailRelations, {
...payload,
testPlanID: testPlanId,
});
const detail = await call(getDetail, { id: testCaseID, testPlanID: testPlanId });
caseDetail = {
...detail,
id,
planRelationCaseID: id,
testCaseID,
execStatus,
apiCount,
};
issueBugs = relationBugs;
} else {
caseDetail = await call(getDetail, { ...payload, testPlanID: testPlanId });
caseDetail = {
testCaseID: caseDetail.id,
...caseDetail,
};
}
update({ caseDetail, issueBugs });
return caseDetail;
},
async getDetailRelations({ call, update, getParams }, payload: TEST_CASE.QueryCaseDetail) {
const { testPlanId } = getParams();
const { issueBugs } = await call(getDetailRelations, { ...payload, testPlanID: testPlanId });
update({ issueBugs });
},
async editPartial({ call, getParams }, detailCase: TEST_CASE.CaseBody) {
const { projectId: projectID } = getParams();
await call(editPartial, { ...detailCase, projectID });
},
async getFields({ call }) {
const fields = await call(getFields);
testCaseStore.reducers.dealFields(fields);
},
async exportFile({ call }, fileType: TEST_CASE.CaseFileType) {
const { testCaseIDs, ...rest } = await testCaseStore.effects.getSelectedCaseIds();
const query = routeInfoStore.getState((s) => s.query);
const temp = { recycled: query.recycled === 'true' };
const exportQuery = formatQuery({
...rest,
...temp,
fileType,
testCaseID: testCaseIDs,
}) as any as TEST_CASE.ExportFileQuery;
return call(exportFileInTestCase, exportQuery);
},
async importTestCase({ call, getParams, getQuery }, payload: { file: any }) {
const { projectId: projectID } = getParams();
const { testSetID } = getQuery();
const { file } = payload;
let fileType: TEST_CASE.CaseFileType = 'excel';
let reloadTestSetInfo = { isMove: false, testSetID: 0, parentID: 0, projectID } as IReloadTestSetInfo;
if (regRules.xmind.pattern.test(file.name)) {
reloadTestSetInfo = { ...reloadTestSetInfo, parentID: testSetID, testSetID };
fileType = 'xmind';
}
const formData = convertToFormData({ file });
const res = await call(importFileInTestCase, { payload: formData, query: { testSetID, projectID, fileType } });
testCaseStore.effects.getCases();
testSetStore.reducers.updateReloadTestSet(reloadTestSetInfo);
return res;
},
async importAutoTestCase({ call, getParams }, payload: { file: File }) {
const { projectId: projectID } = getParams();
const { file } = payload;
const fileType: TEST_CASE.CaseFileType = 'excel';
const query = { projectID, fileType };
const formData = convertToFormData({ file });
const res = await call(importFileInAutoTestCase, { payload: formData, query });
return res;
},
async importAutoTestCaseSet({ call, getParams }, payload: { file: File }) {
const { projectId: projectID, spaceId: spaceID } = getParams();
const { file } = payload;
const fileType: TEST_CASE.CaseFileType = 'excel';
const query = { projectID, fileType, spaceID };
const formData = convertToFormData({ file });
const res = await call(importFileInAutoTestCaseSet, { payload: formData, query });
return res;
},
async create({ call, getParams }, payload: any) {
const { projectId: strProjectId } = getParams();
const {
breadcrumbInfo: { testSetID, testPlanID },
} = testSetStore.getState((s) => s);
const projectID = parseInt(strProjectId, 10);
const res = await call(
create,
{
...payload,
testSetID: testSetID || 0,
projectID,
recycled: false,
},
testPlanID,
{ successMsg: i18n.t('created successfully') },
);
return res;
},
async getSelectedCaseIds({ getParams, select }, mode?: TEST_CASE.PageScope): Promise<ISelected> {
// 用例列表中选中的测试用例
const { projectId: projectID } = getParams();
const testCase = select((s) => s);
const testSet = testSetStore.getState((s) => s);
const routeInfo = routeInfoStore.getState((s) => s);
const { isAll, exclude, primaryKeys } = testCase[getChoosenName(mode)];
const { testSetID } = testSet.breadcrumbInfo;
if (mode === 'caseModal') {
if (isAll) {
return { exclude, testCaseIDs: primaryKeys };
}
return { testCaseIDs: primaryKeys };
}
if (isAll) {
return { ...routeInfo.query, testSetID, projectID, testCaseIDs: primaryKeys, exclude };
}
return { ...routeInfo.query, projectID, testCaseIDs: primaryKeys };
},
async changeExecutionResult(_, status: string) {
const { testCaseIDs: relationIDs } = await testCaseStore.effects.getSelectedCaseIds();
const payload: Omit<TEST_PLAN.PlanBatch, 'testPlanID'> = { execStatus: status, relationIDs };
testPlanStore.effects.updateCasesStatus(payload);
},
async moveCase({ call }, payload: Omit<TEST_CASE.BatchUpdate, 'priority'>) {
const res = await call(batchUpdateCase, payload);
testCaseStore.reducers.removeChoosenIds(payload.testCaseIDs);
message.success(i18n.t('dop:update completed'));
testCaseStore.effects.getCases();
return res;
},
// 更新优先级
async updatePriority({ call, select }, priority: TEST_CASE.Priority) {
const { primaryKeys } = select((s) => s.choosenInfo);
const payload: Omit<TEST_CASE.BatchUpdate, 'recycled' | 'moveToTestSetID'> = {
testCaseIDs: primaryKeys,
priority,
};
const res = await call(batchUpdateCase, payload);
testCaseStore.reducers.removeChoosenIds(payload.testCaseIDs);
message.success(i18n.t('dop:update completed'));
testCaseStore.effects.getCases();
return res;
},
// 移至回收站
async toggleToRecycle({ call }, payload: Omit<TEST_CASE.BatchUpdate, 'priority'>) {
const res = await call(batchUpdateCase, payload);
testCaseStore.reducers.removeChoosenIds(payload.testCaseIDs);
message.success(i18n.t('deleted successfully'));
testCaseStore.effects.getCases();
return res;
},
async deleteEntirely({ call }, id?: number) {
let tempIds = [];
if (id) {
// 单条
tempIds = [id];
await call(deleteEntirely, { testCaseIDs: tempIds });
} else {
// 批量
const newQuery = await testCaseStore.effects.getSelectedCaseIds();
tempIds = newQuery.testCaseIDs || [];
await call(deleteEntirely, { testCaseIDs: tempIds });
}
testCaseStore.reducers.removeChoosenIds(tempIds);
message.success(i18n.t('deleted successfully'));
testCaseStore.effects.getCases();
},
async emptyListByTestSetId({ update }, targetTestSetId: number) {
const { testSetID } = testSetStore.getState((s) => s.breadcrumbInfo);
if (targetTestSetId !== testSetID) {
return;
}
update({ caseList: [], caseTotal: 0 });
testCaseStore.reducers.triggerChoosenAll({ isAll: false, scope: 'testCase' });
},
async updateCases({ call }, { query, payload }: { query: TEST_CASE.CaseFilter; payload: TEST_CASE.CaseBodyPart }) {
await call(updateCases, { query, payload });
message.success(i18n.t('updated successfully'));
testCaseStore.effects.getCases();
},
async copyCases({ call, getParams }, payload: Omit<TEST_CASE.BatchCopy, 'projectID'>) {
const { projectId } = getParams();
await call(copyCases, { ...payload, projectID: +projectId });
message.success(i18n.t('copied successfully'));
testCaseStore.effects.getCases();
},
async getCases(
{ call, select, update, getParams },
payload?: Merge<TEST_CASE.QueryCase, { scope: TEST_CASE.PageScope }>,
) {
const { scope, ...rest } = payload || ({} as Merge<TEST_CASE.QueryCase, { scope: TEST_CASE.PageScope }>);
const breadcrumbInfo = testSetStore.getState((s) => s.breadcrumbInfo);
const oldQuery = select((s) => s.oldQuery);
const query = routeInfoStore.getState((s) => s.query);
const { projectId: projectID, testPlanId } = getParams();
let { testSetID } = breadcrumbInfo;
// 先取传过来的,再取url上的
if (rest.testSetID !== undefined) {
testSetID = rest.testSetID;
} else if (query.testSetID !== undefined) {
testSetID = query.testSetID;
}
// 1、当筛选器、表格的page、sorter发生变更时
// 2、及时性的筛选信息
if (scope === 'caseModal') {
// 如果是在计划详情中的用例弹框时,传入的参数覆盖url上的参数
const newQuery = { ...query, ...rest, testSetID, projectID, query: undefined }; // Set the query outside the modal to undefined, prevent to filter modal data
const { testSets, total } = await call(getCases, formatQuery({ pageSize: 15, ...newQuery }));
update({ modalCaseList: testSets, modalCaseTotal: total });
testCaseStore.reducers.triggerChoosenAll({ isAll: false, scope });
return;
}
const fetchData = testPlanId ? getCasesRelations : getCases;
const newQuery = { ...rest, testSetID, ...query, projectID, testPlanID: testPlanId };
const { testSets, total } = await call(fetchData, formatQuery({ pageSize: 15, ...newQuery }));
update({ caseList: testSets, caseTotal: total, oldQuery: newQuery });
if (checkNeedEmptyChoosenIds(newQuery, oldQuery)) {
testCaseStore.reducers.triggerChoosenAll({ isAll: false, scope });
}
},
async attemptTestApi({ call }, payload: TEST_CASE.TestApi) {
const result = await call(attemptTestApi, payload);
return result;
},
async removeRelation({ call, getParams }, payload: Omit<TEST_CASE.RemoveRelation, 'testPlanID'>) {
const { testPlanId } = getParams();
const res = await call(
removeRelation,
{ ...payload, testPlanID: testPlanId },
{ successMsg: i18n.t('dop:disassociated successfully') },
);
return res;
},
async addRelation({ call, getParams }, payload: Omit<TEST_CASE.AddRelation, 'testPlanID'>) {
const { testPlanId } = getParams();
const res = await call(
addRelation,
{ ...payload, testPlanID: testPlanId },
{ successMsg: i18n.t('dop:associated successfully') },
);
return res;
},
async getImportExportRecords({ call, getParams }, payload: { types: TEST_CASE.ImportOrExport[] }) {
const { projectId } = getParams();
const res = await call(getImportExportRecords, { projectId, ...payload });
return res;
},
},
reducers: {
openNormalModal(state, caseAction) {
state.caseAction = caseAction;
},
closeNormalModal(state) {
state.caseAction = '';
},
triggerChoosenAll(state, { isAll, scope }: { isAll: boolean; scope: TEST_CASE.PageScope }) {
if (scope === 'temp') {
return;
}
const keyName = getChoosenName(scope);
const listName = getCaseListName(scope);
let nextIsAll = isAll;
if (!isBoolean(isAll)) {
nextIsAll = !state[keyName].isAll;
}
let testCaseIDs: number[] = [];
if (nextIsAll) {
testCaseIDs = flatMapDeep(state[listName], ({ testCases }) => flatMapDeep(testCases, 'id'));
}
state[keyName] = { isAll: nextIsAll, exclude: [], primaryKeys: nextIsAll ? testCaseIDs : [] };
},
removeChoosenIds(state, ids) {
if (!ids) {
return;
}
const { primaryKeys } = state.choosenInfo;
remove(primaryKeys, (caseId) => includes(ids, caseId));
state.choosenInfo = { ...state.choosenInfo, isAll: false, primaryKeys };
},
clearChoosenInfo(state, { mode }: { mode: TEST_CASE.PageScope }) {
const keyName = getChoosenName(mode);
state[keyName] = {
isAll: false,
primaryKeys: [],
exclude: [],
};
},
updateChoosenInfo(state, { id, mode, checked }) {
const keyName = getChoosenName(mode);
const { isAll, primaryKeys } = state[keyName];
const copy = [...primaryKeys];
let nextIsAll = isAll;
if (checked) {
const listName = getCaseListName(mode);
const caseCount = flatMapDeep(state[listName], ({ testCases }) => flatMapDeep(testCases, 'id')).length;
copy.push(id);
nextIsAll = copy.length === caseCount;
} else {
nextIsAll = false;
if (includes(copy, id)) {
// 已经选中时
remove(copy, (caseId) => caseId === id);
}
}
state[keyName] = { isAll: nextIsAll, exclude: [], primaryKeys: [...copy] };
},
resetStore() {
return initState;
},
toggleCasePanel(state, visible) {
state.currCase = { ...state.currCase, visible };
state.currDetailCase = { ...state.currDetailCase, visible: false };
},
toggleDetailPanel(state, { visible, detailCase }) {
state.currDetailCase = { visible, case: { ...state.currDetailCase.case, ...detailCase } };
state.currCase = { ...state.currCase, visible: false };
},
setCurrCase(state, currCase) {
state.currCase = { ...state.currCase, case: { ...currCase } };
},
setDetailCase(state, detailCase) {
state.currDetailCase = { ...state.currDetailCase, case: { ...detailCase } };
},
dealFields(state, fields) {
let fieldsVal = [...DEFAULT_FIELDS];
fieldsVal = map(fieldsVal, (defaultField) => {
const metaField = find(fields, (filedItem) => filedItem.uniqueName === defaultField.uniqueName);
if (metaField) {
return metaField;
}
return defaultField;
});
state.fields = fieldsVal;
state.metaFields = fields;
},
dealDetail(state, { payload }) {
const { detailCase } = payload;
const { attachmentObjects: attachments } = detailCase;
attachments.map((value: any) => {
if (!isImage(value.name)) {
// eslint-disable-next-line no-param-reassign
value.thumbUrl = defaultFileTypeImg;
}
extend(value, {
uid: value.id,
name: value.name,
status: 'done',
url: value.url,
response: [{ ...value }],
thumbUrl: value.thumbUrl || undefined,
});
return value;
});
detailCase.attachments = attachments;
const desc = detailCase.desc && detailCase.desc !== '<p></p>' ? detailCase.desc : '';
const preCondition =
detailCase.preCondition && detailCase.preCondition !== '<p></p>' ? detailCase.preCondition : '';
detailCase.desc = desc;
detailCase.preCondition = preCondition;
state.currDetailCase = {
...state.currDetailCase,
case: { ...detailCase, descIssues: detailCase.descIssues || [] },
};
state.oldBugIds = detailCase.bugs && detailCase.bugs.map(({ id }: any) => id);
},
clearCurrCase(state) {
state.currCase = tempNewCase;
},
clearCurrDetailCase(state) {
state.currDetailCase = tempNewCase;
},
clearCaseDetail(state) {
state.caseDetail = {} as TEST_CASE.CaseDetail;
},
},
})