-
Notifications
You must be signed in to change notification settings - Fork 9
#3723 Made Add Rule/Add Rule Section Box #3838
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
644443c
bea4397
25a8982
fc138c1
8320f23
f35c01f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,6 +14,9 @@ import RuleActions from './RuleActions'; | |
| import { Rule } from 'shared'; | ||
| import ErrorPage from '../ErrorPage'; | ||
| import LoadingIndicator from '../../components/LoadingIndicator'; | ||
| import AddRuleSectionModal from './components/AddRuleSectionModal'; | ||
| import AddRuleModal from './components/AddRuleModal'; | ||
| import { AddRuleBox } from './components/AddRuleBox'; | ||
| import AssignRulesTab from './AssignRulesTab'; | ||
|
|
||
| /** | ||
|
|
@@ -161,6 +164,14 @@ const RulesetEditPage: React.FC = () => { | |
| const [tabValue, setTabValue] = useState(0); | ||
| const defaultTab = 'edit-rules'; | ||
|
|
||
| const [showAddMenu, setShowAddMenu] = useState(false); | ||
| const [addMenuAnchorEl, setAddMenuAnchorEl] = useState<HTMLElement | null>(null); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if I'm understanding this correctly this useState is to keep track of which element the addMenu is on, in which case keeping track of the html element is too tightly coupling this component with its children. Instead I think it might make more sense to just have a single optional useState for which rule to show the addMenu on |
||
| const [activeRuleId, setActiveRuleId] = useState<string | null>(null); | ||
|
|
||
| // temporary placeholder useState fns for the add rule section and add rule modals | ||
| const [showAddRuleSectionModal, setShowAddRuleSectionModal] = useState(false); | ||
| const [showAddRuleModal, setShowAddRuleModal] = useState(false); | ||
|
|
||
| const { data: ruleset, isError, error, isLoading } = useSingleRuleset(rulesetId); | ||
|
|
||
| const tabs = [ | ||
|
|
@@ -180,9 +191,32 @@ const RulesetEditPage: React.FC = () => { | |
| // Placeholder | ||
| }; | ||
|
|
||
| const handleAddRule = (ruleId: string) => { | ||
| // Placeholder | ||
| console.log('Add rule to:', ruleId); | ||
| const handleOpenAddMenu = (ruleId: string, anchorEl: HTMLElement) => { | ||
| // trying to make tests run lol this comment can get deleted later | ||
| if (showAddMenu && addMenuAnchorEl === anchorEl) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should be handled in the child component because it should know whether or not it has a menu open. This will also make it so we don't have to pass the anchor element through at all |
||
| handleCloseAddMenu(); | ||
| return; | ||
| } | ||
|
|
||
| setActiveRuleId(ruleId); | ||
| setAddMenuAnchorEl(anchorEl); | ||
| setShowAddMenu(true); | ||
| }; | ||
|
|
||
| const handleCloseAddMenu = () => { | ||
| setShowAddMenu(false); | ||
| setAddMenuAnchorEl(null); | ||
| }; | ||
|
|
||
| const handleAddRuleSectionFromMenu = () => { | ||
| setShowAddRuleSectionModal(true); | ||
| handleCloseAddMenu(); | ||
| }; | ||
|
|
||
| const handleAddRuleFromMenu = () => { | ||
| console.log('Add rule to:', activeRuleId); | ||
| setShowAddRuleModal(true); | ||
| handleCloseAddMenu(); | ||
| }; | ||
|
|
||
| const handleRemoveRule = (ruleId: string) => { | ||
|
|
@@ -227,7 +261,7 @@ const RulesetEditPage: React.FC = () => { | |
| rightContent={(currentRule) => ( | ||
| <RuleActions | ||
| ruleId={currentRule.ruleId} | ||
| onAdd={handleAddRule} | ||
| onAdd={handleOpenAddMenu} | ||
| onRemove={handleRemoveRule} | ||
| onEdit={handleEditRule} | ||
| iconColor="#000000" | ||
|
|
@@ -244,6 +278,17 @@ const RulesetEditPage: React.FC = () => { | |
| </Table> | ||
| </TableContainer> | ||
|
|
||
| <AddRuleBox | ||
| open={showAddMenu} | ||
| anchorEl={addMenuAnchorEl} | ||
| onClose={handleCloseAddMenu} | ||
| onAddRuleSection={handleAddRuleSectionFromMenu} | ||
| onAddRule={handleAddRuleFromMenu} | ||
| /> | ||
|
|
||
| <AddRuleSectionModal open={showAddRuleSectionModal} onClose={() => setShowAddRuleSectionModal(false)} /> | ||
| <AddRuleModal open={showAddRuleModal} onClose={() => setShowAddRuleModal(false)} /> | ||
|
|
||
| <Box | ||
| sx={{ | ||
| backgroundColor: '#121313', | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| import * as React from 'react'; | ||
| import { Box, Popover, useTheme } from '@mui/material'; | ||
| import { NERButton } from '../../../components/NERButton'; | ||
|
|
||
| type AddRuleBoxProps = { | ||
| open: boolean; | ||
| anchorEl: HTMLElement | null; | ||
| onClose: () => void; | ||
| onAddRuleSection: () => void; | ||
| onAddRule: () => void; | ||
| }; | ||
|
|
||
| export const AddRuleBox: React.FC<AddRuleBoxProps> = ({ open, anchorEl, onClose, onAddRuleSection, onAddRule }) => { | ||
| const theme = useTheme(); | ||
|
|
||
| return ( | ||
| <Popover | ||
| open={open} | ||
| anchorEl={anchorEl} | ||
| onClose={onClose} | ||
| disableRestoreFocus | ||
| anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }} | ||
| transformOrigin={{ vertical: 'top', horizontal: 'right' }} | ||
| PaperProps={{ | ||
| sx: { | ||
| backgroundColor: 'transparent', | ||
| boxShadow: 'none' | ||
| } | ||
| }} | ||
| > | ||
| <Box | ||
| sx={{ | ||
| display: 'flex', | ||
| flexDirection: 'column', | ||
| backgroundColor: theme.palette.grey[700], | ||
| borderRadius: '8px', | ||
| overflow: 'hidden', | ||
| border: '1px solid rgba(0,0,0,0.4)', | ||
| minWidth: 'auto' | ||
| }} | ||
| > | ||
| <NERButton | ||
| onClick={onAddRuleSection} | ||
| sx={{ | ||
| borderRadius: 0, | ||
| backgroundColor: 'transparent', | ||
| color: theme.palette.common.white, | ||
| lineHeight: 1.1, | ||
| justifyContent: 'flex-end', | ||
| '&:hover': { backgroundColor: 'rgba(255,255,255,0.12)' } | ||
| }} | ||
| > | ||
| Add Rule Section | ||
| </NERButton> | ||
|
|
||
| <Box sx={{ height: 1, backgroundColor: 'rgba(255,255,255,0.18)' }} /> | ||
|
|
||
| <NERButton | ||
| onClick={onAddRule} | ||
| sx={{ | ||
| borderRadius: 0, | ||
| borderTop: '1px solid black', | ||
| backgroundColor: 'transparent', | ||
| color: theme.palette.common.white, | ||
| lineHeight: 1.1, | ||
| justifyContent: 'flex-end', | ||
| '&:hover': { backgroundColor: 'rgba(255,255,255,0.12)' } | ||
| }} | ||
| > | ||
| Add Rule | ||
| </NERButton> | ||
| </Box> | ||
| </Popover> | ||
| ); | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| import { Box, Typography } from '@mui/material'; | ||
| import { useToast } from '../../../hooks/toasts.hooks'; | ||
| import NERFormModal from '../../../components/NERFormModal'; | ||
| import { useForm } from 'react-hook-form'; | ||
|
|
||
| interface AddRuleModalProps { | ||
| open: boolean; | ||
| onClose: () => void; | ||
| } | ||
|
|
||
| const AddRuleModal: React.FC<AddRuleModalProps> = ({ open, onClose }) => { | ||
| const toast = useToast(); | ||
|
|
||
| const { handleSubmit, reset } = useForm({ defaultValues: {} }); | ||
|
|
||
| const onSubmit = async () => { | ||
| toast.success('Add Rule submitted (placeholder)'); | ||
| onClose(); | ||
| }; | ||
|
|
||
| return ( | ||
| <NERFormModal | ||
| open={open} | ||
| onHide={onClose} | ||
| reset={() => reset({})} | ||
| title="Add Rule" | ||
| handleUseFormSubmit={handleSubmit} | ||
| onFormSubmit={onSubmit} | ||
| formId="add-rule-form" | ||
| showCloseButton | ||
| > | ||
| <Box sx={{ py: 2 }}> | ||
| <Typography variant="body2" color="text.secondary"> | ||
| This is a temporary placeholder modal for creating a new rule. The full rule creation form will be implemented | ||
| later. | ||
| </Typography> | ||
| </Box> | ||
| </NERFormModal> | ||
| ); | ||
| }; | ||
|
|
||
| export default AddRuleModal; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| import { Box, Typography } from '@mui/material'; | ||
| import NERFormModal from '../../../components/NERFormModal'; | ||
| import { useToast } from '../../../hooks/toasts.hooks'; | ||
| import { useForm } from 'react-hook-form'; | ||
|
|
||
| interface AddRuleSectionModalProps { | ||
| open: boolean; | ||
| onClose: () => void; | ||
| } | ||
|
|
||
| const AddRuleSectionModal: React.FC<AddRuleSectionModalProps> = ({ open, onClose }) => { | ||
| const toast = useToast(); | ||
|
|
||
| const { handleSubmit, reset } = useForm({ defaultValues: {} }); | ||
|
|
||
| const onSubmit = async () => { | ||
| toast.success('Add Rule Section submitted (placeholder)'); | ||
| onClose(); | ||
| }; | ||
|
|
||
| return ( | ||
| <NERFormModal | ||
| open={open} | ||
| onHide={onClose} | ||
| reset={() => reset({})} | ||
| title="Add Rule Section" | ||
| handleUseFormSubmit={handleSubmit} | ||
| onFormSubmit={onSubmit} | ||
| formId="add-rule-section-form" | ||
| showCloseButton | ||
| > | ||
| <Box sx={{ py: 2 }}> | ||
| <Typography variant="body2" color="text.secondary"> | ||
| This is a temporary placeholder modal for creating a new rule section. Form fields will be added in a future | ||
| ticket. | ||
| </Typography> | ||
| </Box> | ||
| </NERFormModal> | ||
| ); | ||
| }; | ||
|
|
||
| export default AddRuleSectionModal; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a prop shouldn't take in an anchorEl because it tightly couples this component with its parent. Instead, we need to figure out what information the onAdd needs, and extract that from the element before passing it through (if we need it at all)