Skip to content

Commit 091ffb3

Browse files
ATLAS-5169: Atlas UI creates multi-valued Business Metadata with SINGLE cardinality
1 parent e35c819 commit 091ffb3

16 files changed

+460
-53
lines changed

dashboard/src/views/BusinessMetadata/BusinessMetadataAtrributeForm.tsx

Lines changed: 78 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ import {
3737
tooltipClasses,
3838
TooltipProps,
3939
styled,
40-
FilterOptionsState
40+
FilterOptionsState,
41+
ToggleButton,
42+
ToggleButtonGroup
4143
} from "@mui/material";
4244
import { customSortBy, isEmpty, serverError } from "@utils/Utils";
4345
import { Controller, useForm } from "react-hook-form";
@@ -463,41 +465,82 @@ const BusinessMetadataAttributeForm = ({
463465
watched?.[index] &&
464466
watched?.[index]?.multiValueSelect) ||
465467
isEmpty(editbmAttribute)) && (
466-
<Controller
467-
control={control}
468-
name={`attributeDefs.${index}.multiValueSelect` as const}
469-
key={`attributeDefs.${index}.multiValueSelect`}
470-
data-cy={`attributeDefs.${index}.multiValueSelect`}
471-
defaultValue={field?.multiValueSelect}
472-
render={({ field: { value, onChange } }) => (
473-
<>
474-
<Grid
475-
container
476-
columnSpacing={{ xs: 1, sm: 2, md: 2 }}
477-
marginBottom="1rem"
478-
alignItems="center"
479-
>
480-
<Grid item md={3} textAlign="right">
481-
<InputLabel>Enable Multivalues</InputLabel>
482-
</Grid>
483-
<Grid item md={7}>
484-
{" "}
485-
<FormControlLabel
486-
control={
487-
<Checkbox
488-
disabled={isEmpty(editbmAttribute) ? false : true}
489-
size="small"
490-
checked={value}
491-
onChange={onChange}
468+
<>
469+
<Controller
470+
control={control}
471+
name={`attributeDefs.${index}.multiValueSelect` as const}
472+
key={`attributeDefs.${index}.multiValueSelect`}
473+
data-cy={`attributeDefs.${index}.multiValueSelect`}
474+
defaultValue={field?.multiValueSelect}
475+
render={({ field: { value, onChange } }) => (
476+
<>
477+
<Grid
478+
container
479+
columnSpacing={{ xs: 1, sm: 2, md: 2 }}
480+
marginBottom="1rem"
481+
alignItems="center"
482+
>
483+
<Grid item md={3} textAlign="right">
484+
<InputLabel>Enable Multivalues</InputLabel>
485+
</Grid>
486+
<Grid item md={7}>
487+
<Stack direction="row" spacing={2} alignItems="center">
488+
<FormControlLabel
489+
control={
490+
<Checkbox
491+
disabled={isEmpty(editbmAttribute) ? false : true}
492+
size="small"
493+
checked={value}
494+
onChange={(e) => {
495+
onChange(e.target.checked);
496+
// Reset cardinality toggle when multivalues is unchecked
497+
if (!e.target.checked) {
498+
attributeDefsSetValue(
499+
`attributeDefs.${index}.cardinalityToggle`,
500+
"SET"
501+
);
502+
}
503+
}}
504+
/>
505+
}
506+
label={undefined}
492507
/>
493-
}
494-
label={undefined}
495-
/>
496-
</Grid>{" "}
497-
</Grid>
498-
</>
499-
)}
500-
/>
508+
{value && (
509+
<Controller
510+
control={control}
511+
name={`attributeDefs.${index}.cardinalityToggle` as const}
512+
key={`attributeDefs.${index}.cardinalityToggle`}
513+
defaultValue={field?.cardinalityToggle || "SET"}
514+
render={({ field: { value: toggleValue, onChange: toggleOnChange } }) => (
515+
<ToggleButtonGroup
516+
size="small"
517+
value={toggleValue || "SET"}
518+
exclusive
519+
disabled={!isEmpty(editbmAttribute)}
520+
onChange={(e, newValue) => {
521+
if (newValue !== null) {
522+
toggleOnChange(newValue);
523+
}
524+
}}
525+
aria-label="cardinality toggle"
526+
>
527+
<ToggleButton value="SET" aria-label="SET">
528+
SET
529+
</ToggleButton>
530+
<ToggleButton value="LIST" aria-label="LIST">
531+
LIST
532+
</ToggleButton>
533+
</ToggleButtonGroup>
534+
)}
535+
/>
536+
)}
537+
</Stack>
538+
</Grid>
539+
</Grid>
540+
</>
541+
)}
542+
/>
543+
</>
501544
)}
502545
{watched?.[index] && watched?.[index]?.typeName == "string" && (
503546
<Controller

dashboard/src/views/BusinessMetadata/BusinessMetadataForm.tsx

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,9 @@ const BusinessMetaDataForm = ({
115115
...(currentTypeName == "enumeration" && {
116116
enumValues: enumTypeOptions
117117
}),
118-
multiValueSelect: str.indexOf("<") != -1 ? true : false
118+
multiValueSelect: str.indexOf("<") != -1 ? true : false,
119+
// Set cardinalityToggle based on existing cardinality (SET or LIST), default to SET
120+
cardinalityToggle: editbmAttribute?.cardinality === "LIST" ? "LIST" : "SET"
119121
}
120122
];
121123
const dispatchState = useAppDispatch();
@@ -142,6 +144,7 @@ const BusinessMetaDataForm = ({
142144
},
143145
isOptional: true,
144146
cardinality: "SINGLE",
147+
cardinalityToggle: "SET", // Default toggle value when multivalues is enabled
145148
valuesMinCount: 0,
146149
valuesMaxCount: 1,
147150
isUnique: false,
@@ -157,7 +160,7 @@ const BusinessMetaDataForm = ({
157160
control,
158161
name: "attributeDefs",
159162
rules: {
160-
required: true
163+
required: false // Allow creating BM without attributes
161164
}
162165
});
163166

@@ -203,7 +206,9 @@ const BusinessMetaDataForm = ({
203206
...(currentTypeName == "enumeration" && {
204207
enumValues: enumTypeOptions
205208
}),
206-
multiValueSelect: str.indexOf("<") != -1 ? true : false
209+
multiValueSelect: str.indexOf("<") != -1 ? true : false,
210+
// Set cardinalityToggle based on existing cardinality (SET or LIST), default to SET
211+
cardinalityToggle: editbmAttribute?.cardinality === "LIST" ? "LIST" : "SET"
207212
}
208213
];
209214
if (!isEmpty(editbmAttribute)) {
@@ -255,10 +260,19 @@ const BusinessMetaDataForm = ({
255260

256261
let attributes = !isEmpty(attributeDefsData)
257262
? attributeDefsData.map((item) => {
258-
const { multiValueSelect, enumType, enumValues, ...rest } = item;
263+
const { multiValueSelect, enumType, enumValues, cardinality, cardinalityToggle, ...rest } = item;
264+
265+
// Determine cardinality based on multiValueSelect and cardinality toggle
266+
let finalCardinality = "SINGLE";
267+
if (multiValueSelect) {
268+
// If multivalues is enabled, use the cardinalityToggle (SET or LIST)
269+
// Default to SET if not specified
270+
finalCardinality = cardinalityToggle === "LIST" ? "LIST" : (cardinality === "LIST" ? "LIST" : "SET");
271+
}
259272

260273
const baseObj = {
261274
...rest,
275+
cardinality: finalCardinality,
262276
options: {
263277
applicableEntityTypes: JSON.stringify(
264278
rest.options.applicableEntityTypes
@@ -508,6 +522,7 @@ const BusinessMetaDataForm = ({
508522
},
509523
isOptional: true,
510524
cardinality: "SINGLE",
525+
cardinalityToggle: "SET", // Default toggle value when multivalues is enabled
511526
valuesMinCount: 0,
512527
valuesMaxCount: 1,
513528
isUnique: false,

dashboard/src/views/DetailPage/BusinessMetadataDetails/BusinessMetadataAtrribute.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,18 @@ const BusinessMetadataAtrribute = ({ componentProps, row }: any) => {
8484
header: "Enable Multivalues",
8585
enableSorting: false
8686
},
87+
{
88+
accessorKey: "cardinality",
89+
cell: (info: any) =>
90+
!isEmpty(info.getValue()) ? (
91+
<Typography>{info.getValue()}</Typography>
92+
) : (
93+
<span>N/A</span>
94+
),
95+
header: "Cardinality",
96+
enableSorting: true,
97+
show: true
98+
},
8799
{
88100
accessorKey: "maxStrLength",
89101
cell: (info: any) => {
@@ -217,7 +229,9 @@ const BusinessMetadataAtrribute = ({ componentProps, row }: any) => {
217229
...(currentTypeName == "enumeration" && {
218230
enumValues: enumTypeOptions
219231
}),
220-
multiValueSelect: str.indexOf("<") != -1 ? true : false
232+
multiValueSelect: str.indexOf("<") != -1 ? true : false,
233+
// Set cardinalityToggle based on existing cardinality (SET or LIST), default to SET
234+
cardinalityToggle: original?.cardinality === "LIST" ? "LIST" : "SET"
221235
}
222236
];
223237
setForm(true);

dashboard/src/views/DetailPage/BusinessMetadataDetails/BusinessMetadataDetailsLayout.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,10 +179,19 @@ const BusinessMetadataDetailsLayout = () => {
179179
let attributeDefsData = [...formAttributes];
180180

181181
let attributes = attributeDefsData.map((item) => {
182-
const { multiValueSelect, enumValues, enumType, ...rest } = item;
182+
const { multiValueSelect, enumValues, enumType, cardinality, cardinalityToggle, ...rest } = item;
183+
184+
// Determine cardinality based on multiValueSelect and cardinality toggle
185+
let finalCardinality = "SINGLE";
186+
if (multiValueSelect) {
187+
// If multivalues is enabled, use the cardinalityToggle (SET or LIST)
188+
// Default to SET if not specified
189+
finalCardinality = cardinalityToggle === "LIST" ? "LIST" : (cardinality === "LIST" ? "LIST" : "SET");
190+
}
183191

184192
return {
185193
...rest,
194+
cardinality: finalCardinality,
186195
...{
187196
options: {
188197
applicableEntityTypes: JSON.stringify(

dashboardv2/public/css/scss/business-metadata.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,4 +240,12 @@
240240
.business-metadata-detail-attr-key {
241241
width: 30%;
242242
}
243+
}
244+
245+
// Disabled state for cardinality toggle buttons
246+
.cardinality-btn.disabled,
247+
.cardinality-btn[disabled] {
248+
opacity: 0.6;
249+
cursor: not-allowed;
250+
pointer-events: none;
243251
}

dashboardv2/public/js/templates/business_metadata/BusinessMetadataAttributeItemView_tmpl.html

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,17 @@
6868
<div class="form-group" data-id="multiValueSelect">
6969
<label class="control-label col-sm-3" for="multiValSelect">Enable Multivalues</label>
7070
<div class="col-sm-8">
71-
<input type="checkbox" class="form-check-input multi-value-select" data-id="multiValueSelectStatus">
71+
<div class="row">
72+
<div class="col-sm-6">
73+
<input type="checkbox" class="form-check-input multi-value-select" data-id="multiValueSelectStatus">
74+
</div>
75+
<div class="col-sm-6" data-id="cardinalityToggleContainer" style="display: none;">
76+
<div class="btn-group" role="group" data-id="cardinalityToggle">
77+
<button type="button" class="btn btn-sm btn-default cardinality-btn" data-value="SET" data-id="cardinalitySET">SET</button>
78+
<button type="button" class="btn btn-sm btn-default cardinality-btn active" data-value="LIST" data-id="cardinalityLIST">LIST</button>
79+
</div>
80+
</div>
81+
</div>
7282
</div>
7383
</div>
7484
<div class="form-group enumtype-container" data-id="enumTypeSelectorContainer">

dashboardv2/public/js/views/business_metadata/BusinessMetadataAttrTableLayoutView.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,15 @@ define(['require',
108108
attrDetails.typeName = attrObj.typeName.replace("array<", "").replace(">", "");
109109
attrDetails.multiValued = true;
110110
}
111+
// Set cardinalityToggle based on existing cardinality (SET or LIST), default to SET
112+
if (attrObj.cardinality) {
113+
attrDetails.cardinalityToggle = (attrObj.cardinality === "LIST") ? "LIST" : "SET";
114+
} else {
115+
// If cardinality is not set but it's an array type, default to SET
116+
if (attrObj.typeName.includes('array')) {
117+
attrDetails.cardinalityToggle = "SET";
118+
}
119+
}
111120
}
112121
});
113122
this.showDetails = false;
@@ -197,6 +206,27 @@ define(['require',
197206
}
198207
})
199208
},
209+
cardinality: {
210+
label: "Cardinality",
211+
cell: "html",
212+
editable: false,
213+
sortable: true,
214+
formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
215+
fromRaw: function(rawValue, model) {
216+
var cardinality = model.get('cardinality');
217+
if (!cardinality) {
218+
// If cardinality is not set, determine from typeName
219+
if (model.get('typeName').indexOf('array<') > -1) {
220+
// Default to SET for array types if cardinality is not specified
221+
cardinality = "SET";
222+
} else {
223+
cardinality = "SINGLE";
224+
}
225+
}
226+
return _.escape(cardinality);
227+
}
228+
})
229+
},
200230
maxStrLength: {
201231
label: "Max Length",
202232
cell: "html",

0 commit comments

Comments
 (0)