-
Notifications
You must be signed in to change notification settings - Fork 252
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
uik: Single dialog for default actions (#4193)
* feat: enhance form and destination components with edit functionality and improved UI * fix: update default action parameters to fallback on request body values * refactor: remove DefaultActionEditDialog component and associated logic * refactor: comment out setRuleActions logic for future API change * fix: add data-testid to no actions message for improved testing
- Loading branch information
1 parent
960fbf5
commit a504b73
Showing
8 changed files
with
248 additions
and
142 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
96 changes: 0 additions & 96 deletions
96
web/src/app/services/UniversalKey/DefaultActionEditDialog.tsx
This file was deleted.
Oops, something went wrong.
165 changes: 165 additions & 0 deletions
165
web/src/app/services/UniversalKey/UniversalKeyActionDialog.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
import React, { useState } from 'react' | ||
import { gql, useMutation, useQuery } from 'urql' | ||
import { | ||
Action, | ||
ActionInput, | ||
IntegrationKey, | ||
UpdateKeyConfigInput, | ||
} from '../../../schema' | ||
import FormDialog from '../../dialogs/FormDialog' | ||
import DynamicActionForm, { Value } from '../../selection/DynamicActionForm' | ||
import { useDefaultAction } from '../../util/RequireConfig' | ||
import { useErrorConsumer } from '../../util/ErrorConsumer' | ||
|
||
type UniversalKeyActionDialogProps = { | ||
keyID: string | ||
|
||
/* The rule ID to add or edit an action for. If not set, operate on the default actions. */ | ||
ruleID?: string | ||
|
||
/* The action index to edit. If not set, add a new action. */ | ||
actionIndex?: number | ||
|
||
onClose: () => void | ||
disablePortal?: boolean | ||
} | ||
|
||
const query = gql` | ||
query GetKey($keyID: ID!) { | ||
integrationKey(id: $keyID) { | ||
id | ||
config { | ||
rules { | ||
id | ||
actions { | ||
dest { | ||
type | ||
args | ||
} | ||
params | ||
} | ||
} | ||
defaultActions { | ||
dest { | ||
type | ||
args | ||
} | ||
params | ||
} | ||
} | ||
} | ||
} | ||
` | ||
|
||
const updateKeyConfig = gql` | ||
mutation UpdateKeyConfig($input: UpdateKeyConfigInput!) { | ||
updateKeyConfig(input: $input) | ||
} | ||
` | ||
|
||
function actionToInput(action: Action): ActionInput { | ||
return { | ||
dest: action.dest, | ||
params: action.params, | ||
} | ||
} | ||
|
||
export function UniversalKeyActionDialog( | ||
props: UniversalKeyActionDialogProps, | ||
): React.ReactNode { | ||
const defaultAction = useDefaultAction() | ||
const [q] = useQuery<{ integrationKey: IntegrationKey }>({ | ||
query, | ||
variables: { keyID: props.keyID }, | ||
}) | ||
if (q.error) throw q.error | ||
|
||
const config = q.data?.integrationKey.config | ||
if (!config) throw new Error('missing config') | ||
|
||
const rule = config.rules.find((r) => r.id === props.ruleID) || null | ||
if (props.ruleID && !rule) throw new Error('missing rule') | ||
const actions = rule ? rule.actions : config.defaultActions | ||
const action = | ||
props.actionIndex !== undefined ? actions[props.actionIndex] : null | ||
const [value, setValue] = useState<Value>({ | ||
destType: action?.dest.type || defaultAction.dest.type, | ||
staticParams: action?.dest.args || {}, | ||
dynamicParams: action?.params || defaultAction.params, | ||
}) | ||
const [m, commit] = useMutation(updateKeyConfig) | ||
|
||
const verb = action ? 'Edit' : 'Add' | ||
const title = `${verb} ${rule ? '' : 'Default '}Action${rule?.name ? ` for Rule "${rule.name}"` : ''}` | ||
|
||
const input = { keyID: props.keyID } as UpdateKeyConfigInput | ||
const newAction = { | ||
dest: { | ||
type: value.destType + 'brok', | ||
args: value.staticParams, | ||
}, | ||
params: value.dynamicParams, | ||
} | ||
if (rule && props.actionIndex !== undefined) { | ||
// Edit rule action | ||
// TODO: Commented out until next PR when this API change is introduced | ||
// input.setRuleActions = { | ||
// id: rule.id, | ||
// actions: actions | ||
// .map(actionToInput) | ||
// .map((a, idx) => (idx === props.actionIndex ? newAction : a)), | ||
// } | ||
} else if (rule) { | ||
// Add rule action | ||
// TODO: Commented out until next PR when this API change is introduced | ||
// input.setRuleActions = { | ||
// id: rule.id, | ||
// actions: actions.map(actionToInput).concat(newAction), | ||
// } | ||
} else if (props.actionIndex !== undefined) { | ||
// Edit default action | ||
input.defaultActions = actions | ||
.map(actionToInput) | ||
.map((a, idx) => (idx === props.actionIndex ? newAction : a)) | ||
} else { | ||
// Add default action | ||
input.defaultActions = actions.map(actionToInput).concat(newAction) | ||
} | ||
|
||
const errs = useErrorConsumer(m.error) | ||
|
||
return ( | ||
<FormDialog | ||
title={title} | ||
onClose={props.onClose} | ||
loading={m.fetching} | ||
maxWidth='md' | ||
errors={errs.remainingLegacyCallback()} | ||
onSubmit={() => | ||
commit({ input }, { additionalTypenames: ['KeyConfig'] }).then( | ||
(res) => { | ||
if (res.error) return | ||
|
||
props.onClose() | ||
}, | ||
) | ||
} | ||
form={ | ||
<DynamicActionForm | ||
disablePortal={props.disablePortal} | ||
value={value} | ||
onChange={setValue} | ||
staticParamErrors={errs.getErrorMap('updateKeyConfig')} | ||
dynamicParamErrors={errs.getErrorMap( | ||
/updateKeyConfig.input.defaultActions.\d+.params/, | ||
)} | ||
/> | ||
} | ||
PaperProps={{ | ||
sx: { | ||
minHeight: '500px', | ||
}, | ||
}} | ||
/> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.