diff --git a/src/actions.js b/src/actions.js index b261a96..060cbf5 100644 --- a/src/actions.js +++ b/src/actions.js @@ -17,6 +17,7 @@ const TASK_GROUP_PROJECTION = () => [ 'code', 'completionPolicy', 'taskexecutorSet { edges { node { user { id username lastName } } } }', + 'taskAllowedSources', ]; const TASK_FULL_PROJECTION = () => [ @@ -64,6 +65,7 @@ export const formatTaskGroupGQL = (taskGroup) => { ${taskGroup?.id ? `id: "${taskGroup.id}"` : ''} ${taskGroup?.taskexecutorSet ? `userIds: ${executorsString}` : 'userIds: []'} ${taskGroup?.taskSources ? `taskSources: ${taskSourcesString}` : 'taskSources: []'} + ${taskGroup?.taskAllowedSources ? `taskAllowedSources: ${taskSourcesString}` : 'taskAllowedSources: []'} `; }; @@ -122,6 +124,7 @@ export function fetchTaskGroup(modulesManager, variables) { completionPolicy jsonExt taskexecutorSet { edges { node { user { id username lastName } } } }, + taskAllowedSources } } } diff --git a/src/components/TaskHeadPanel.js b/src/components/TaskHeadPanel.js index b27618a..ff0fc0b 100644 --- a/src/components/TaskHeadPanel.js +++ b/src/components/TaskHeadPanel.js @@ -89,6 +89,7 @@ class TaskHeadPanel extends FormPanel { readOnly={!rights.includes(TASK_UPDATE) || [TASK_STATUS.COMPLETED, TASK_STATUS.FAILED].includes(task.status)} withNull + source={task?.source} value={task?.taskGroup} onChange={(taskGroup) => this.updateAttribute('taskGroup', taskGroup)} /> diff --git a/src/components/groups-management/TaskGroupHeadPanel.js b/src/components/groups-management/TaskGroupHeadPanel.js index c3ef633..1f85f9a 100644 --- a/src/components/groups-management/TaskGroupHeadPanel.js +++ b/src/components/groups-management/TaskGroupHeadPanel.js @@ -11,6 +11,8 @@ import { withTheme, withStyles } from '@material-ui/core/styles'; import TaskExecutorsPicker from '../../pickers/TaskExecutorsPicker'; import GroupPolicyPicker from '../../pickers/GroupPolicyPicker'; import TaskSourcePicker from '../../pickers/TaskSourcePicker'; +import TaskSourceAllowedPicker from '../../pickers/TaskSourceAllowedPicker'; +import { TASK_GROUP_UPDATE, TASK_GROUP_CREATE } from '../../constants'; const styles = (theme) => ({ tableTitle: theme.table.title, @@ -43,9 +45,16 @@ const renderHeadPanelTitle = (classes) => ( class TaskGroupHeadPanel extends FormPanel { render() { const { - edited, classes, readOnly, + edited, classes, readOnly, rights, } = this.props; const taskGroup = { ...edited }; + const filterAllowedSources = (options) => { + if (!taskGroup?.taskAllowedSources?.length) { + return options; + } + const sourcesIds = taskGroup.taskAllowedSources.map((source) => source.id); + return options.filter((option) => sourcesIds.includes(option.id)); + }; return ( <> {renderHeadPanelTitle(classes)} @@ -86,6 +95,14 @@ class TaskGroupHeadPanel extends FormPanel { readOnly={readOnly} value={taskGroup?.taskSources} onChange={(sources) => this.updateAttribute('taskSources', sources)} + filterOptions={filterAllowedSources} + /> + + + this.updateAttribute('taskAllowedSources', allowedSources)} /> diff --git a/src/pickers/TaskGroupPicker.js b/src/pickers/TaskGroupPicker.js index 5b1f938..cb3850e 100644 --- a/src/pickers/TaskGroupPicker.js +++ b/src/pickers/TaskGroupPicker.js @@ -1,10 +1,7 @@ import React, { useState } from 'react'; import { - useModulesManager, - useTranslations, - Autocomplete, - useGraphqlQuery, + useModulesManager, useTranslations, Autocomplete, useGraphqlQuery, } from '@openimis/fe-core'; function TaskGroupPicker(props) { @@ -16,6 +13,7 @@ function TaskGroupPicker(props) { withPlaceholder, value, label, + source = null, filterOptions, filterSelectedOptions, placeholder, @@ -35,6 +33,7 @@ function TaskGroupPicker(props) { id code completionPolicy + taskAllowedSources } } } @@ -45,6 +44,16 @@ function TaskGroupPicker(props) { }, ); + const options = data?.taskGroup?.edges.map((edge) => edge.node) ?? []; + + const filteredOptionsWithAllowedSources = options.filter((option) => { + const parsedResponse = JSON.parse(option.taskAllowedSources); + const allowedSources = typeof parsedResponse === 'object' ? [parsedResponse] : parsedResponse; + const usersAllowedSources = allowedSources.flatMap((source) => source.task_allowed_sources); + + return usersAllowedSources.includes(source); + }); + return ( edge.node) ?? []} + options={filteredOptionsWithAllowedSources} isLoading={isLoading} value={value} getOptionLabel={(option) => `${option.code}`} diff --git a/src/pickers/TaskSourceAllowedPicker.js b/src/pickers/TaskSourceAllowedPicker.js new file mode 100644 index 0000000..6fd7838 --- /dev/null +++ b/src/pickers/TaskSourceAllowedPicker.js @@ -0,0 +1,35 @@ +import React from 'react'; +import { Autocomplete, useTranslations, useModulesManager } from '@openimis/fe-core'; +import { TASK_CONTRIBUTION_KEY } from '../constants'; + +function TaskSourceAllowedPicker({ + onChange, readOnly, required, withLabel, value, +}) { + const modulesManager = useModulesManager(); + const { formatMessage } = useTranslations('tasksManagement'); + const contributions = modulesManager.getContribs(TASK_CONTRIBUTION_KEY); + const allowedSources = contributions.flatMap((contribution) => { + const source = contribution.taskSource; + return source ? source.map((item) => ({ id: item, name: item })) : []; + }); + + return ( + `${source.name}`} + onChange={onChange} + filterSelectedOptions + onInputChange={() => {}} + /> + ); +} + +export default TaskSourceAllowedPicker; diff --git a/src/pickers/TaskSourcePicker.js b/src/pickers/TaskSourcePicker.js index 93ea99f..3d94051 100644 --- a/src/pickers/TaskSourcePicker.js +++ b/src/pickers/TaskSourcePicker.js @@ -12,6 +12,7 @@ function TaskSourcePicker({ required, withLabel, value, + filterOptions, }) { const modulesManager = useModulesManager(); const { formatMessage } = useTranslations('tasksManagement'); @@ -34,7 +35,7 @@ function TaskSourcePicker({ value={value} getOptionLabel={(source) => `${source.name}`} onChange={onChange} - filterSelectedOptions + filterOptions={filterOptions} onInputChange={() => {}} /> ); diff --git a/src/reducer.js b/src/reducer.js index 8be83b1..d81e26e 100644 --- a/src/reducer.js +++ b/src/reducer.js @@ -166,6 +166,10 @@ function reducer( taskSources: taskGroup?.jsonExt ? JSON.parse(taskGroup.jsonExt).task_sources.map((source) => ({ id: source, name: source })) : [], + taskAllowedSources: taskGroup?.taskAllowedSources + ? JSON.parse(taskGroup?.taskAllowedSources).task_allowed_sources.map( + (source) => ({ id: source, name: source }), + ) : [], }))?.[0], fetchingTaskGroup: false, errorTaskGroup: formatGraphQLError(action.payload), diff --git a/src/translations/en.json b/src/translations/en.json index e4f352b..2d39117 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -53,6 +53,8 @@ "tasksManagement.menu.taskExecutionerGroups": "Task Executioner Groups", "tasksManagement.TaskSourcePicker.label": "Task Sources", "tasksManagement.TaskSourcePicker.placeholder": "Search for task sources...", + "tasksManagement.TaskSourceAllowedPicker.label": "Allowed Task Sources", + "tasksManagement.TaskSourceAllowedPicker.placeholder": "Search for allowed task sources...", "tasksManagement.entries.tasksManagementAllView": "All Tasks", "tasksManagement.task.source.mutationLabel": "Resolving task", "tasksManagement.task.source.IndividualService": "Individual Service",