Skip to content

Commit 0a392d6

Browse files
authored
Merge pull request #156 from don-aot/CONDITIONS-task#147
CR-147:Remove MP Name attribute from table, pull name from title
2 parents 0a41bb6 + 5dca057 commit 0a392d6

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
};
@@ -93,7 +92,6 @@ export const SELECT_OPTIONS = {
9392

9493
export const managementRequiredKeys = [
9594
CONDITION_KEYS.SUBMITTED_TO_EAO_FOR,
96-
CONDITION_KEYS.MANAGEMENT_PLAN_NAME,
9795
CONDITION_KEYS.MILESTONES_RELATED_TO_PLAN_SUBMISSION,
9896
CONDITION_KEYS.MILESTONES_RELATED_TO_PLAN_IMPLEMENTATION,
9997
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);
@@ -580,125 +573,6 @@ const DynamicFieldRenderer: React.FC<DynamicFieldRendererProps> = ({
580573
);
581574
}
582575

583-
if (attributeData.key === CONDITION_KEYS.MANAGEMENT_PLAN_NAME) {
584-
const handleAddAdditionalPlanNames = () => {
585-
if (additionalPlanNames.trim()) {
586-
planNamesData.setPlanNames([...planNamesData.planNames, additionalPlanNames]);
587-
setAdditionalPlanNames(""); // Clear the input field
588-
setShowCustomPlanNames(false); // Hide the custom input field
589-
}
590-
};
591-
592-
const handleDeleteChip = (chipToDelete: string) => {
593-
setShowCustomPlanNames(false);
594-
planNamesData.setPlanNames(
595-
planNamesData.planNames.filter((chip) => chip !== chipToDelete)
596-
);
597-
};
598-
599-
const shouldRenderChipInput =
600-
planNamesData.planNames.length === 0 ||
601-
(planNamesData.planNames.length === 1 && planNamesData.planNames[0] === "");
602-
603-
return (
604-
<>
605-
{shouldRenderChipInput ? (
606-
// Render the ChipInput component if no plan names exist
607-
<ChipInput
608-
chips={planNamesData.planNames}
609-
setChips={(newChips) => planNamesData.setPlanNames(newChips)}
610-
placeholder="Add a management plan name"
611-
inputWidth={editMode ? "30%" : "100%"}
612-
/>
613-
) : (
614-
// Render chips if there are plan names
615-
<div>
616-
{/* Chips displayed in a flexible row */}
617-
<div style={{ display: "flex", flexWrap: "wrap", gap: "8px", marginBottom: "8px" }}>
618-
{planNamesData.planNames
619-
.filter((chip) => chip.trim() !== "")
620-
.map((name, index) => (
621-
<Chip
622-
key={index}
623-
label={name}
624-
onDelete={() => handleDeleteChip(name)}
625-
sx={{
626-
backgroundColor: "#e0e0e0",
627-
color: "black",
628-
fontSize: "14px",
629-
}}
630-
/>
631-
))}
632-
</div>
633-
634-
{/* "+ Add name for another Management Plan" appears on the next line */}
635-
<div>
636-
<Typography
637-
variant="body2"
638-
color="primary"
639-
onClick={() => setShowCustomPlanNames(true)}
640-
sx={{
641-
cursor: "pointer",
642-
textDecoration: "underline",
643-
}}
644-
>
645-
+ Add name for another Management Plan
646-
</Typography>
647-
</div>
648-
</div>
649-
)}
650-
651-
{showCustomPlanNames && (
652-
<div
653-
style={{
654-
marginTop: "8px",
655-
display: "flex",
656-
alignItems: "center",
657-
gap: "8px",
658-
}}
659-
>
660-
<TextField
661-
value={additionalPlanNames}
662-
onChange={(e) => setAdditionalPlanNames(e.target.value)}
663-
placeholder="Add a management plan name"
664-
size="small"
665-
fullWidth
666-
sx={{
667-
flex: "0 0 auto",
668-
width: editMode ? "30%" : "100%",
669-
}}
670-
InputProps={{
671-
endAdornment: additionalPlanNames ? (
672-
<InputAdornment
673-
position="end"
674-
sx={{ marginRight: "-5px" }}
675-
>
676-
<IconButton
677-
onClick={handleAddAdditionalPlanNames}
678-
sx={{
679-
padding: 0,
680-
borderRadius: "50%",
681-
backgroundColor: "green",
682-
color: "white",
683-
"&:hover": { backgroundColor: "darkgreen" },
684-
}}
685-
>
686-
<AddIcon
687-
sx={{
688-
fontSize: "20px",
689-
}}
690-
/>
691-
</IconButton>
692-
</InputAdornment>
693-
) : null,
694-
}}
695-
/>
696-
</div>
697-
)}
698-
</>
699-
);
700-
}
701-
702576
if (options) {
703577
return (
704578
<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)