Skip to content

Commit 5dca057

Browse files
committed
CR-147:Remove MP Name attribute from table, pull name from title
1 parent e0b6155 commit 5dca057

File tree

9 files changed

+38
-209
lines changed

9 files changed

+38
-209
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"""remove_management_plan_name_attribute
2+
3+
Revision ID: f1a2b3c4d5e6
4+
Revises: 0b5a70026d28
5+
Create Date: 2026-03-03 00:00:00.000000
6+
7+
"""
8+
from alembic import op
9+
import sqlalchemy as sa
10+
11+
12+
# revision identifiers, used by Alembic.
13+
revision = 'f1a2b3c4d5e6'
14+
down_revision = '0b5a70026d28'
15+
branch_labels = None
16+
depends_on = None
17+
18+
19+
def upgrade():
20+
# condition_attributes rows that reference this key are deleted automatically
21+
# via the ON DELETE CASCADE foreign key constraint.
22+
op.execute(
23+
"""
24+
DELETE FROM condition.attribute_keys
25+
WHERE key_name = 'Management plan name(s)';
26+
"""
27+
)
28+
29+
30+
def downgrade():
31+
op.execute(
32+
"""
33+
INSERT INTO condition.attribute_keys (id, key_name, external_key, sort_order, created_date)
34+
VALUES (3, 'Management plan name(s)', 'management_plan_name', 3, NOW())
35+
ON CONFLICT (id) DO NOTHING;
36+
"""
37+
)

condition-api/src/condition_api/services/attribute_key_service.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ def get_all_attributes(condition_id, management_plan_id=None):
5555
AttributeKeys.PARTIES_REQUIRED_TO_BE_SUBMITTED.value,
5656
AttributeKeys.DELIVERABLE_NAME.value,
5757
AttributeKeys.MANAGEMENT_PLAN_ACRONYM.value,
58-
AttributeKeys.MANAGEMENT_PLAN_NAME.value,
5958
]),
6059
)
6160
.order_by(attribute_keys.sort_order)

condition-api/src/condition_api/services/condition_attribute_service.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -250,12 +250,10 @@ def _handle_requires_management_plan(condition_id, management_plan_id):
250250
).first()
251251

252252
if not existing_attribute:
253-
# Check if the current key is MANAGEMENT_PLAN_NAME
254-
attribute_value = '{}' if key.key_name == AttributeKeys.MANAGEMENT_PLAN_NAME.value else None
255253
new_attribute = ConditionAttribute(
256254
condition_id=condition_id,
257255
attribute_key_id=key.id,
258-
attribute_value=attribute_value,
256+
attribute_value=None,
259257
management_plan_id=management_plan_id
260258
)
261259
db.session.add(new_attribute)

condition-api/src/condition_api/services/condition_service.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1027,7 +1027,6 @@ def _fetch_condition_attributes_external(
10271027
AttributeKeys.PARTIES_REQUIRED_TO_BE_CONSULTED.value,
10281028
AttributeKeys.MILESTONES_RELATED_TO_PLAN_SUBMISSION.value,
10291029
AttributeKeys.MILESTONES_RELATED_TO_PLAN_IMPLEMENTATION.value,
1030-
AttributeKeys.MANAGEMENT_PLAN_NAME.value,
10311030
}
10321031

10331032
query = db.session.query(

condition-api/src/condition_api/utils/enums.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ class AttributeKeys(str, Enum):
3333
"""Attribute Keys — values match key_name in the attribute_keys table."""
3434

3535
REQUIRES_CONSULTATION = "Requires consultation"
36-
MANAGEMENT_PLAN_NAME = "Management plan name(s)"
3736
MANAGEMENT_PLAN_ACRONYM = "Management plan acronym(s)"
3837
PARTIES_REQUIRED_TO_BE_SUBMITTED = "Parties required to be submitted"
3938
PARTIES_REQUIRED_TO_BE_CONSULTED = "Parties required to be consulted"
@@ -71,7 +70,6 @@ def required_attribute_keys() -> List[str]:
7170
"""Required attribute key_names for Management Plan"""
7271
return [
7372
AttributeKeys.SUBMITTED_TO_EAO_FOR.value,
74-
AttributeKeys.MANAGEMENT_PLAN_NAME.value,
7573
AttributeKeys.MANAGEMENT_PLAN_ACRONYM.value,
7674
AttributeKeys.MILESTONES_RELATED_TO_PLAN_SUBMISSION.value,
7775
AttributeKeys.MILESTONES_RELATED_TO_PLAN_IMPLEMENTATION.value,

condition-web/src/components/ConditionDetails/ConditionAttribute/Constants.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ export const CONDITION_KEYS = {
66
TIME_ASSOCIATED_WITH_SUBMISSION_MILESTONE: "Time associated with submission milestone",
77
PARTIES_REQUIRED: "Parties required to be consulted",
88
MANAGEMENT_PLAN_ACRONYM: "Management plan acronym(s)",
9-
MANAGEMENT_PLAN_NAME: "Management plan name(s)",
109
REQUIRES_IEM_TERMS_OF_ENGAGEMENT: "Requires IEM Terms of Engagement",
1110
DELIVERABLE_NAME: "Deliverable name"
1211
};
@@ -91,7 +90,6 @@ export const SELECT_OPTIONS = {
9190

9291
export const managementRequiredKeys = [
9392
CONDITION_KEYS.SUBMITTED_TO_EAO_FOR,
94-
CONDITION_KEYS.MANAGEMENT_PLAN_NAME,
9593
CONDITION_KEYS.MILESTONES_RELATED_TO_PLAN_SUBMISSION,
9694
CONDITION_KEYS.MILESTONES_RELATED_TO_PLAN_IMPLEMENTATION,
9795
CONDITION_KEYS.TIME_ASSOCIATED_WITH_SUBMISSION_MILESTONE,

condition-web/src/components/ConditionDetails/ConditionAttribute/DynamicFieldRenderer.tsx

Lines changed: 0 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,6 @@ type DynamicFieldRendererProps = {
3737
milestones: string[];
3838
setMilestones: (value: string[]) => void;
3939
};
40-
planNamesData: {
41-
planNames: string[];
42-
setPlanNames: (value: string[]) => void;
43-
};
4440
otherData: {
4541
otherValue: string;
4642
setOtherValue: (value: string) => void;
@@ -55,7 +51,6 @@ const DynamicFieldRenderer: React.FC<DynamicFieldRendererProps> = ({
5551
chipsData,
5652
submissionMilestonesData,
5753
milestonesData,
58-
planNamesData,
5954
otherData,
6055
}) => {
6156
const [timeUnit, setTimeUnit] = useState<string>("");
@@ -65,10 +60,8 @@ const DynamicFieldRenderer: React.FC<DynamicFieldRendererProps> = ({
6560
const [error, setError] = useState(false);
6661
const [showCustomSubmissionInput, setShowCustomSubmissionInput] = useState(false);
6762
const [showCustomInput, setShowCustomInput] = useState(false);
68-
const [showCustomPlanNames, setShowCustomPlanNames] = useState(false);
6963
const [customSubmissionMilestone, setCustomSubmissionMilestone] = useState("");
7064
const [customMilestone, setCustomMilestone] = useState("");
71-
const [additionalPlanNames, setAdditionalPlanNames] = useState("");
7265
const [dynamicSubmissionWidth, setDynamicSubmissionWidth] = useState<number>(100);
7366
const [dynamicWidth, setDynamicWidth] = useState<number>(100);
7467
const textRef = useRef<HTMLDivElement>(null);
@@ -541,125 +534,6 @@ const DynamicFieldRenderer: React.FC<DynamicFieldRendererProps> = ({
541534
);
542535
}
543536

544-
if (attributeData.key === CONDITION_KEYS.MANAGEMENT_PLAN_NAME) {
545-
const handleAddAdditionalPlanNames = () => {
546-
if (additionalPlanNames.trim()) {
547-
planNamesData.setPlanNames([...planNamesData.planNames, additionalPlanNames]);
548-
setAdditionalPlanNames(""); // Clear the input field
549-
setShowCustomPlanNames(false); // Hide the custom input field
550-
}
551-
};
552-
553-
const handleDeleteChip = (chipToDelete: string) => {
554-
setShowCustomPlanNames(false);
555-
planNamesData.setPlanNames(
556-
planNamesData.planNames.filter((chip) => chip !== chipToDelete)
557-
);
558-
};
559-
560-
const shouldRenderChipInput =
561-
planNamesData.planNames.length === 0 ||
562-
(planNamesData.planNames.length === 1 && planNamesData.planNames[0] === "");
563-
564-
return (
565-
<>
566-
{shouldRenderChipInput ? (
567-
// Render the ChipInput component if no plan names exist
568-
<ChipInput
569-
chips={planNamesData.planNames}
570-
setChips={(newChips) => planNamesData.setPlanNames(newChips)}
571-
placeholder="Add a management plan name"
572-
inputWidth={editMode ? "30%" : "100%"}
573-
/>
574-
) : (
575-
// Render chips if there are plan names
576-
<div>
577-
{/* Chips displayed in a flexible row */}
578-
<div style={{ display: "flex", flexWrap: "wrap", gap: "8px", marginBottom: "8px" }}>
579-
{planNamesData.planNames
580-
.filter((chip) => chip.trim() !== "")
581-
.map((name, index) => (
582-
<Chip
583-
key={index}
584-
label={name}
585-
onDelete={() => handleDeleteChip(name)}
586-
sx={{
587-
backgroundColor: "#e0e0e0",
588-
color: "black",
589-
fontSize: "14px",
590-
}}
591-
/>
592-
))}
593-
</div>
594-
595-
{/* "+ Add name for another Management Plan" appears on the next line */}
596-
<div>
597-
<Typography
598-
variant="body2"
599-
color="primary"
600-
onClick={() => setShowCustomPlanNames(true)}
601-
sx={{
602-
cursor: "pointer",
603-
textDecoration: "underline",
604-
}}
605-
>
606-
+ Add name for another Management Plan
607-
</Typography>
608-
</div>
609-
</div>
610-
)}
611-
612-
{showCustomPlanNames && (
613-
<div
614-
style={{
615-
marginTop: "8px",
616-
display: "flex",
617-
alignItems: "center",
618-
gap: "8px",
619-
}}
620-
>
621-
<TextField
622-
value={additionalPlanNames}
623-
onChange={(e) => setAdditionalPlanNames(e.target.value)}
624-
placeholder="Add a management plan name"
625-
size="small"
626-
fullWidth
627-
sx={{
628-
flex: "0 0 auto",
629-
width: editMode ? "30%" : "100%",
630-
}}
631-
InputProps={{
632-
endAdornment: additionalPlanNames ? (
633-
<InputAdornment
634-
position="end"
635-
sx={{ marginRight: "-5px" }}
636-
>
637-
<IconButton
638-
onClick={handleAddAdditionalPlanNames}
639-
sx={{
640-
padding: 0,
641-
borderRadius: "50%",
642-
backgroundColor: "green",
643-
color: "white",
644-
"&:hover": { backgroundColor: "darkgreen" },
645-
}}
646-
>
647-
<AddIcon
648-
sx={{
649-
fontSize: "20px",
650-
}}
651-
/>
652-
</IconButton>
653-
</InputAdornment>
654-
) : null,
655-
}}
656-
/>
657-
</div>
658-
)}
659-
</>
660-
);
661-
}
662-
663537
if (options) {
664538
return (
665539
<Stack direction="column">

condition-web/src/components/ConditionDetails/ConditionAttribute/Independent/ConditionAttributeRow.tsx

Lines changed: 0 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -111,20 +111,6 @@ const ConditionAttributeRow: React.FC<ConditionAttributeRowProps> = ({
111111
: []
112112
);
113113

114-
const [planNames, setPlanNames] = useState<string[]>(
115-
conditionKey === CONDITION_KEYS.MANAGEMENT_PLAN_NAME
116-
? attributeValue
117-
?.replace(/[{}]/g, "") // Remove curly braces
118-
.match(/"(?:\\.|[^"\\])*"|[^,]+/g) // Match quoted strings or standalone words
119-
?.map((item) =>
120-
item
121-
.trim()
122-
.replace(/^"(.*)"$/, "$1") // Remove surrounding quotes
123-
.replace(/\\"/g, '"') // Fix escaped quotes
124-
) || []
125-
: []
126-
);
127-
128114
useEffect(() => {
129115
setEditableValue(conditionAttributeItem.value ?? "");
130116
if (conditionKey === CONDITION_KEYS.PARTIES_REQUIRED) {
@@ -141,19 +127,6 @@ const ConditionAttributeRow: React.FC<ConditionAttributeRowProps> = ({
141127
);
142128
}
143129

144-
if (conditionKey === CONDITION_KEYS.MANAGEMENT_PLAN_NAME) {
145-
setPlanNames(
146-
conditionAttributeItem.value
147-
?.replace(/[{}]/g, "") // Remove curly braces
148-
.match(/"(?:\\.|[^"\\])*"|[^,]+/g) // Match quoted strings or standalone words
149-
?.map((item) =>
150-
item
151-
.trim()
152-
.replace(/^"(.*)"$/, "$1") // Remove surrounding quotes
153-
.replace(/\\"/g, '"') // Fix escaped quotes
154-
) || []
155-
);
156-
}
157130
}, [conditionAttributeItem, conditionKey]);
158131

159132
const escapeValue = (value: string) => {
@@ -173,11 +146,6 @@ const ConditionAttributeRow: React.FC<ConditionAttributeRowProps> = ({
173146
.filter((chip) => chip !== null && chip !== "")
174147
.map((chip) => escapeValue(chip)) // Add escape to all values
175148
.join(",")}}`
176-
: conditionKey === CONDITION_KEYS.MANAGEMENT_PLAN_NAME
177-
? `{${planNames
178-
.filter((planName) => planName !== null && planName !== "")
179-
.map((planName) => escapeValue(planName))
180-
.join(",")}}`
181149
: conditionKey === CONDITION_KEYS.MILESTONES_RELATED_TO_PLAN_SUBMISSION
182150
? submissionMilestones.map((submissionMilestone) => `${submissionMilestone}`).join(",")
183151
: conditionKey === CONDITION_KEYS.MILESTONES_RELATED_TO_PLAN_IMPLEMENTATION
@@ -203,21 +171,6 @@ const ConditionAttributeRow: React.FC<ConditionAttributeRowProps> = ({
203171
setChips(parsedChips);
204172
}
205173

206-
if (conditionKey === CONDITION_KEYS.MANAGEMENT_PLAN_NAME) {
207-
const parsedPlanNames =
208-
updatedValue
209-
?.replace(/[{}]/g, "") // Remove curly braces
210-
.match(/"(?:\\.|[^"\\])*"|[^,]+/g) // Match quoted strings or standalone words
211-
?.map((item) =>
212-
item
213-
.trim()
214-
.replace(/^"(.*)"$/, "$1") // Remove surrounding quotes
215-
.replace(/\\"/g, '"') // Fix escaped quotes
216-
) || []
217-
218-
setPlanNames(parsedPlanNames);
219-
}
220-
221174
setOtherValue("");
222175
};
223176

@@ -234,7 +187,6 @@ const ConditionAttributeRow: React.FC<ConditionAttributeRowProps> = ({
234187
chipsData={{ chips, setChips }}
235188
submissionMilestonesData={{ submissionMilestones, setSubmissionMilestones }}
236189
milestonesData={{ milestones, setMilestones }}
237-
planNamesData={{ planNames, setPlanNames }}
238190
otherData={{ otherValue, setOtherValue }}
239191
options={options}
240192
/>
@@ -273,16 +225,6 @@ const ConditionAttributeRow: React.FC<ConditionAttributeRowProps> = ({
273225
);
274226
}
275227

276-
if (conditionKey === CONDITION_KEYS.MANAGEMENT_PLAN_NAME) {
277-
return (
278-
<ul style={{ margin: 0, paddingLeft: "16px" }}>
279-
{planNames?.map((item, index) => (
280-
<li key={index}>{item}</li>
281-
))}
282-
</ul>
283-
);
284-
}
285-
286228
const options = SELECT_OPTIONS[conditionKey];
287229
if (options) {
288230
const selectedOption = options.find((option) => option.value === editableValue);

condition-web/src/components/ConditionDetails/ConditionAttribute/Independent/ConditionAttributeTable.tsx

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -228,19 +228,6 @@ const ConditionAttributeTable = memo(({
228228
) || []
229229
: []
230230
);
231-
const [planNames, setPlanNames] = useState<string[]>(
232-
selectedAttribute === CONDITION_KEYS.MANAGEMENT_PLAN_NAME
233-
? attributeValue
234-
?.replace(/[{}]/g, "") // Remove curly braces
235-
.match(/"(?:\\.|[^"\\])*"|[^,]+/g) // Match quoted strings or standalone words
236-
?.map((item) =>
237-
item
238-
.trim()
239-
.replace(/^"(.*)"$/, "$1") // Remove surrounding quotes
240-
.replace(/\\"/g, '"') // Fix escaped quotes
241-
) || []
242-
: []
243-
);
244231
const [submissionMilestones, setSubmissionMilestones] = useState<string[]>([]);
245232
const [milestones, setMilestones] = useState<string[]>([]);
246233

@@ -251,7 +238,6 @@ const ConditionAttributeTable = memo(({
251238
setOtherValue("");
252239
setMilestones([]);
253240
setSubmissionMilestones([]);
254-
setPlanNames([]);
255241
setChips([]);
256242

257243
queryClient.invalidateQueries({
@@ -299,7 +285,6 @@ const ConditionAttributeTable = memo(({
299285
setSelectedAttribute("");
300286
setAttributeValue("");
301287
setChips([]);
302-
setPlanNames([]);
303288
setOtherValue("");
304289
};
305290

@@ -316,7 +301,6 @@ const ConditionAttributeTable = memo(({
316301
chipsData={{ chips, setChips }}
317302
submissionMilestonesData={{ submissionMilestones, setSubmissionMilestones }}
318303
milestonesData={{ milestones, setMilestones }}
319-
planNamesData={{ planNames, setPlanNames }}
320304
otherData={{ otherValue, setOtherValue }}
321305
options={options}
322306
/>

0 commit comments

Comments
 (0)