diff --git a/dashboard/src/views/BusinessMetadata/BusinessMetadataAtrributeForm.tsx b/dashboard/src/views/BusinessMetadata/BusinessMetadataAtrributeForm.tsx index 1f4bc2acf79..88301507872 100644 --- a/dashboard/src/views/BusinessMetadata/BusinessMetadataAtrributeForm.tsx +++ b/dashboard/src/views/BusinessMetadata/BusinessMetadataAtrributeForm.tsx @@ -37,7 +37,9 @@ import { tooltipClasses, TooltipProps, styled, - FilterOptionsState + FilterOptionsState, + ToggleButton, + ToggleButtonGroup } from "@mui/material"; import { customSortBy, isEmpty, serverError } from "@utils/Utils"; import { Controller, useForm } from "react-hook-form"; @@ -463,41 +465,82 @@ const BusinessMetadataAttributeForm = ({ watched?.[index] && watched?.[index]?.multiValueSelect) || isEmpty(editbmAttribute)) && ( - ( - <> - - - Enable Multivalues - - - {" "} - + ( + <> + + + Enable Multivalues + + + + { + onChange(e.target.checked); + // Reset cardinality toggle when multivalues is unchecked + if (!e.target.checked) { + attributeDefsSetValue( + `attributeDefs.${index}.cardinalityToggle`, + "SET" + ); + } + }} + /> + } + label={undefined} /> - } - label={undefined} - /> - {" "} - - - )} - /> + {value && ( + ( + { + if (newValue !== null) { + toggleOnChange(newValue); + } + }} + aria-label="cardinality toggle" + > + + SET + + + LIST + + + )} + /> + )} + + + + + )} + /> + )} {watched?.[index] && watched?.[index]?.typeName == "string" && ( { - const { multiValueSelect, enumType, enumValues, ...rest } = item; + const { multiValueSelect, enumType, enumValues, cardinality, cardinalityToggle, ...rest } = item; + + // Determine cardinality based on multiValueSelect and cardinality toggle + let finalCardinality = "SINGLE"; + if (multiValueSelect) { + // If multivalues is enabled, use the cardinalityToggle (SET or LIST) + // Default to SET if not specified + finalCardinality = cardinalityToggle === "LIST" ? "LIST" : (cardinality === "LIST" ? "LIST" : "SET"); + } const baseObj = { ...rest, + cardinality: finalCardinality, options: { applicableEntityTypes: JSON.stringify( rest.options.applicableEntityTypes @@ -508,6 +522,7 @@ const BusinessMetaDataForm = ({ }, isOptional: true, cardinality: "SINGLE", + cardinalityToggle: "SET", // Default toggle value when multivalues is enabled valuesMinCount: 0, valuesMaxCount: 1, isUnique: false, diff --git a/dashboard/src/views/DetailPage/BusinessMetadataDetails/BusinessMetadataAtrribute.tsx b/dashboard/src/views/DetailPage/BusinessMetadataDetails/BusinessMetadataAtrribute.tsx index 8ed291d906c..af9c1a35549 100644 --- a/dashboard/src/views/DetailPage/BusinessMetadataDetails/BusinessMetadataAtrribute.tsx +++ b/dashboard/src/views/DetailPage/BusinessMetadataDetails/BusinessMetadataAtrribute.tsx @@ -84,6 +84,18 @@ const BusinessMetadataAtrribute = ({ componentProps, row }: any) => { header: "Enable Multivalues", enableSorting: false }, + { + accessorKey: "cardinality", + cell: (info: any) => + !isEmpty(info.getValue()) ? ( + {info.getValue()} + ) : ( + N/A + ), + header: "Cardinality", + enableSorting: true, + show: true + }, { accessorKey: "maxStrLength", cell: (info: any) => { @@ -217,7 +229,9 @@ const BusinessMetadataAtrribute = ({ componentProps, row }: any) => { ...(currentTypeName == "enumeration" && { enumValues: enumTypeOptions }), - multiValueSelect: str.indexOf("<") != -1 ? true : false + multiValueSelect: str.indexOf("<") != -1 ? true : false, + // Set cardinalityToggle based on existing cardinality (SET or LIST), default to SET + cardinalityToggle: original?.cardinality === "LIST" ? "LIST" : "SET" } ]; setForm(true); diff --git a/dashboard/src/views/DetailPage/BusinessMetadataDetails/BusinessMetadataDetailsLayout.tsx b/dashboard/src/views/DetailPage/BusinessMetadataDetails/BusinessMetadataDetailsLayout.tsx index 1638565ff0b..b3d419246af 100644 --- a/dashboard/src/views/DetailPage/BusinessMetadataDetails/BusinessMetadataDetailsLayout.tsx +++ b/dashboard/src/views/DetailPage/BusinessMetadataDetails/BusinessMetadataDetailsLayout.tsx @@ -179,10 +179,19 @@ const BusinessMetadataDetailsLayout = () => { let attributeDefsData = [...formAttributes]; let attributes = attributeDefsData.map((item) => { - const { multiValueSelect, enumValues, enumType, ...rest } = item; + const { multiValueSelect, enumValues, enumType, cardinality, cardinalityToggle, ...rest } = item; + + // Determine cardinality based on multiValueSelect and cardinality toggle + let finalCardinality = "SINGLE"; + if (multiValueSelect) { + // If multivalues is enabled, use the cardinalityToggle (SET or LIST) + // Default to SET if not specified + finalCardinality = cardinalityToggle === "LIST" ? "LIST" : (cardinality === "LIST" ? "LIST" : "SET"); + } return { ...rest, + cardinality: finalCardinality, ...{ options: { applicableEntityTypes: JSON.stringify( diff --git a/dashboardv2/public/css/scss/business-metadata.scss b/dashboardv2/public/css/scss/business-metadata.scss index 5bcbb5df9fc..2cadd14bf7f 100644 --- a/dashboardv2/public/css/scss/business-metadata.scss +++ b/dashboardv2/public/css/scss/business-metadata.scss @@ -240,4 +240,12 @@ .business-metadata-detail-attr-key { width: 30%; } +} + +// Disabled state for cardinality toggle buttons +.cardinality-btn.disabled, +.cardinality-btn[disabled] { + opacity: 0.6; + cursor: not-allowed; + pointer-events: none; } \ No newline at end of file diff --git a/dashboardv2/public/js/templates/business_metadata/BusinessMetadataAttributeItemView_tmpl.html b/dashboardv2/public/js/templates/business_metadata/BusinessMetadataAttributeItemView_tmpl.html index aedb6dabee0..8ffb689b444 100644 --- a/dashboardv2/public/js/templates/business_metadata/BusinessMetadataAttributeItemView_tmpl.html +++ b/dashboardv2/public/js/templates/business_metadata/BusinessMetadataAttributeItemView_tmpl.html @@ -68,7 +68,17 @@
- +
+
+ +
+ +
diff --git a/dashboardv2/public/js/views/business_metadata/BusinessMetadataAttrTableLayoutView.js b/dashboardv2/public/js/views/business_metadata/BusinessMetadataAttrTableLayoutView.js index 37058bbe2e5..37e6e7a834c 100644 --- a/dashboardv2/public/js/views/business_metadata/BusinessMetadataAttrTableLayoutView.js +++ b/dashboardv2/public/js/views/business_metadata/BusinessMetadataAttrTableLayoutView.js @@ -108,6 +108,15 @@ define(['require', attrDetails.typeName = attrObj.typeName.replace("array<", "").replace(">", ""); attrDetails.multiValued = true; } + // Set cardinalityToggle based on existing cardinality (SET or LIST), default to SET + if (attrObj.cardinality) { + attrDetails.cardinalityToggle = (attrObj.cardinality === "LIST") ? "LIST" : "SET"; + } else { + // If cardinality is not set but it's an array type, default to SET + if (attrObj.typeName.includes('array')) { + attrDetails.cardinalityToggle = "SET"; + } + } } }); this.showDetails = false; @@ -197,6 +206,27 @@ define(['require', } }) }, + cardinality: { + label: "Cardinality", + cell: "html", + editable: false, + sortable: true, + formatter: _.extend({}, Backgrid.CellFormatter.prototype, { + fromRaw: function(rawValue, model) { + var cardinality = model.get('cardinality'); + if (!cardinality) { + // If cardinality is not set, determine from typeName + if (model.get('typeName').indexOf('array<') > -1) { + // Default to SET for array types if cardinality is not specified + cardinality = "SET"; + } else { + cardinality = "SINGLE"; + } + } + return _.escape(cardinality); + } + }) + }, maxStrLength: { label: "Max Length", cell: "html", diff --git a/dashboardv2/public/js/views/business_metadata/BusinessMetadataAttributeItemView.js b/dashboardv2/public/js/views/business_metadata/BusinessMetadataAttributeItemView.js index 5190db0319a..6dddb8f6515 100644 --- a/dashboardv2/public/js/views/business_metadata/BusinessMetadataAttributeItemView.js +++ b/dashboardv2/public/js/views/business_metadata/BusinessMetadataAttributeItemView.js @@ -48,6 +48,10 @@ define(['require', enumValueSelector: "[data-id='enumValueSelector']", multiValueSelect: "[data-id='multiValueSelect']", multiValueSelectStatus: "[data-id='multiValueSelectStatus']", + cardinalityToggleContainer: "[data-id='cardinalityToggleContainer']", + cardinalityToggle: "[data-id='cardinalityToggle']", + cardinalitySET: "[data-id='cardinalitySET']", + cardinalityLIST: "[data-id='cardinalityLIST']", stringLengthContainer: "[data-id='stringLengthContainer']", stringLengthValue: "[data-id='stringLength']", createNewEnum: "[data-id='createNewEnum']" @@ -122,15 +126,72 @@ define(['require', this.model.set({ "enumValues": this.ui.enumValueSelector.val() }); }; events["change " + this.ui.multiValueSelectStatus] = function(e) { + var that = this; this.model.set({ "multiValueSelect": e.target.checked }); var typename = this.model.get('typeName'); if (e.target.checked) { typename = "array<" + typename + ">"; + // Show cardinality toggle when multivalues is enabled + that.ui.cardinalityToggleContainer.show(); + // Disable cardinality toggle buttons in edit mode + if (that.isAttrEdit) { + that.ui.cardinalitySET.attr('disabled', 'disabled'); + that.ui.cardinalityLIST.attr('disabled', 'disabled'); + that.ui.cardinalitySET.addClass('disabled'); + that.ui.cardinalityLIST.addClass('disabled'); + } else { + that.ui.cardinalitySET.removeAttr('disabled'); + that.ui.cardinalityLIST.removeAttr('disabled'); + that.ui.cardinalitySET.removeClass('disabled'); + that.ui.cardinalityLIST.removeClass('disabled'); + } + // Set default cardinality to SET if not already set + if (!that.model.get('cardinalityToggle')) { + that.model.set({ "cardinalityToggle": "SET" }); + that.ui.cardinalitySET.addClass('active'); + that.ui.cardinalityLIST.removeClass('active'); + } else { + // Set active button based on current value + var currentCardinality = that.model.get('cardinalityToggle'); + if (currentCardinality === "LIST") { + that.ui.cardinalityLIST.addClass('active'); + that.ui.cardinalitySET.removeClass('active'); + } else { + that.ui.cardinalitySET.addClass('active'); + that.ui.cardinalityLIST.removeClass('active'); + } + } } else { typename = typename.replace('array<', '').replace('>', ''); + // Hide cardinality toggle when multivalues is disabled + that.ui.cardinalityToggleContainer.hide(); + // Reset cardinality toggle + that.model.set({ "cardinalityToggle": "SET" }); } this.model.set({ "typeName": typename }); }; + events["click " + this.ui.cardinalitySET] = function(e) { + e.preventDefault(); + var that = this; + // Disable cardinality toggle in edit mode + if (that.isAttrEdit) { + return; + } + that.model.set({ "cardinalityToggle": "SET" }); + that.ui.cardinalitySET.addClass('active'); + that.ui.cardinalityLIST.removeClass('active'); + }; + events["click " + this.ui.cardinalityLIST] = function(e) { + e.preventDefault(); + var that = this; + // Disable cardinality toggle in edit mode + if (that.isAttrEdit) { + return; + } + that.model.set({ "cardinalityToggle": "LIST" }); + that.ui.cardinalityLIST.addClass('active'); + that.ui.cardinalitySET.removeClass('active'); + }; events["change " + this.ui.entityTypeSelector] = function(e) { var options = this.model.get('options') || {}; options.applicableEntityTypes = JSON.stringify(this.ui.entityTypeSelector.val()); @@ -223,6 +284,24 @@ define(['require', this.ui.multiValueSelect.show(); $(this.ui.multiValueSelectStatus).prop('checked', true).trigger('change'); this.ui.multiValueSelectStatus.attr("disabled", "false"); + // Set cardinality toggle based on existing cardinality (SET or LIST), default to SET + var existingCardinality = this.model.get("cardinality"); + var cardinalityToggle = (existingCardinality === "LIST") ? "LIST" : "SET"; + this.model.set({ "cardinalityToggle": cardinalityToggle }); + if (cardinalityToggle === "LIST") { + this.ui.cardinalityLIST.addClass('active'); + this.ui.cardinalitySET.removeClass('active'); + } else { + this.ui.cardinalitySET.addClass('active'); + this.ui.cardinalityLIST.removeClass('active'); + } + // Disable cardinality toggle buttons in edit mode + if (this.isAttrEdit) { + this.ui.cardinalitySET.attr('disabled', 'disabled'); + this.ui.cardinalityLIST.attr('disabled', 'disabled'); + this.ui.cardinalitySET.addClass('disabled'); + this.ui.cardinalityLIST.addClass('disabled'); + } } } }, diff --git a/dashboardv2/public/js/views/business_metadata/BusinessMetadataTableLayoutView.js b/dashboardv2/public/js/views/business_metadata/BusinessMetadataTableLayoutView.js index c02236843fe..53e14b9c462 100644 --- a/dashboardv2/public/js/views/business_metadata/BusinessMetadataTableLayoutView.js +++ b/dashboardv2/public/js/views/business_metadata/BusinessMetadataTableLayoutView.js @@ -244,11 +244,11 @@ define(['require', accordion: false, alwaysVisible: true, expand: function(el, model) { - el.attr('colspan', '8'); + el.attr('colspan', '9'); var attrValues = '', attrTable = $('table'), attrTableBody = $('tbody'), - attrTableHeading = "AttributeTypeSearch WeightEnable MultivaluesMax LengthApplicable Type(s)Action", + attrTableHeading = "AttributeTypeSearch WeightEnable MultivaluesCardinalityMax LengthApplicable Type(s)Action", attrRow = '', attrTableDetails = ''; if (model.attributes && model.attributes.attributeDefs.length) { @@ -256,7 +256,8 @@ define(['require', var applicableEntityTypes = '', typeName = attrObj.typeName, multiSelect = '', - maxString = 'NA'; + maxString = 'NA', + cardinality = 'SINGLE'; if (attrObj.options && attrObj.options.applicableEntityTypes) { var entityTypes = JSON.parse(attrObj.options.applicableEntityTypes); _.each(entityTypes, function(values) { @@ -266,12 +267,21 @@ define(['require', if (typeName.includes('array')) { typeName = _.escape(typeName); multiSelect = 'checked'; + // Determine cardinality - use existing cardinality value or default to SET + if (attrObj.cardinality) { + cardinality = attrObj.cardinality; + } else { + cardinality = 'SET'; + } + } else { + // For non-array types, cardinality is SINGLE + cardinality = 'SINGLE'; } if (typeName.includes('string') && attrObj.options && attrObj.options.maxStrLength) { maxString = attrObj.options.maxStrLength; } - attrRow += " " + _.escape(attrObj.name) + "" + typeName + "" + _.escape(attrObj.searchWeight) + " " + maxString + "" + applicableEntityTypes + "
Edit
"; + attrRow += " " + _.escape(attrObj.name) + "" + typeName + "" + _.escape(attrObj.searchWeight) + " " + _.escape(cardinality) + "" + maxString + "" + applicableEntityTypes + "
Edit
"; }); var adminText = '
' + attrTableHeading + attrRow + '
'; $(el).append($('
').html(adminText)); diff --git a/dashboardv2/public/js/views/business_metadata/CreateBusinessMetadataLayoutView.js b/dashboardv2/public/js/views/business_metadata/CreateBusinessMetadataLayoutView.js index 165b9950087..200e4ad164a 100644 --- a/dashboardv2/public/js/views/business_metadata/CreateBusinessMetadataLayoutView.js +++ b/dashboardv2/public/js/views/business_metadata/CreateBusinessMetadataLayoutView.js @@ -216,6 +216,27 @@ define(['require', } }, + processAttributes: function(attributes) { + var that = this; + return attributes.map(function(item) { + var multiValueSelect = item.multiValueSelect || false; + var cardinalityToggle = item.cardinalityToggle || "SET"; + + // Determine cardinality based on multiValueSelect and cardinality toggle + var finalCardinality = "SINGLE"; + if (multiValueSelect) { + // If multivalues is enabled, use the cardinalityToggle (SET or LIST) + // Default to SET if not specified + finalCardinality = cardinalityToggle === "LIST" ? "LIST" : (item.cardinality === "LIST" ? "LIST" : "SET"); + } + + // Remove cardinalityToggle from the final object as it's not part of API + var processedItem = _.omit(item, 'cardinalityToggle'); + processedItem.cardinality = finalCardinality; + + return processedItem; + }); + }, onCreateBusinessMetadata: function() { var that = this; if (this.validateValues()) { @@ -227,6 +248,9 @@ define(['require', var attributeObj = this.collection.toJSON(); if (this.collection.length === 1 && this.collection.first().get("name") === "") { attributeObj = []; + } else { + // Process attributes to include cardinality + attributeObj = this.processAttributes(attributeObj); } this.json = { "enumDefs": [], @@ -279,7 +303,9 @@ define(['require', if (selectedBusinessMetadataClone.attributeDefs === undefined) { selectedBusinessMetadataClone.attributeDefs = []; } - selectedBusinessMetadataClone.attributeDefs = selectedBusinessMetadataClone.attributeDefs.concat(this.collection.toJSON()); + // Process new attributes to include cardinality + var newAttributes = this.processAttributes(this.collection.toJSON()); + selectedBusinessMetadataClone.attributeDefs = selectedBusinessMetadataClone.attributeDefs.concat(newAttributes); this.json = { "enumDefs": [], "structDefs": [], diff --git a/dashboardv3/public/css/scss/business-metadata.scss b/dashboardv3/public/css/scss/business-metadata.scss index efed616e1f4..2a593bee82a 100644 --- a/dashboardv3/public/css/scss/business-metadata.scss +++ b/dashboardv3/public/css/scss/business-metadata.scss @@ -240,4 +240,12 @@ .business-metadata-detail-attr-key { width: 30%; } +} + +// Disabled state for cardinality toggle buttons +.cardinality-btn.disabled, +.cardinality-btn[disabled] { + opacity: 0.6; + cursor: not-allowed; + pointer-events: none; } \ No newline at end of file diff --git a/dashboardv3/public/js/templates/business_metadata/BusinessMetadataAttributeItemView_tmpl.html b/dashboardv3/public/js/templates/business_metadata/BusinessMetadataAttributeItemView_tmpl.html index aedb6dabee0..8ffb689b444 100644 --- a/dashboardv3/public/js/templates/business_metadata/BusinessMetadataAttributeItemView_tmpl.html +++ b/dashboardv3/public/js/templates/business_metadata/BusinessMetadataAttributeItemView_tmpl.html @@ -68,7 +68,17 @@
- +
+
+ +
+ +
diff --git a/dashboardv3/public/js/views/business_metadata/BusinessMetadataAttrTableLayoutView.js b/dashboardv3/public/js/views/business_metadata/BusinessMetadataAttrTableLayoutView.js index dd1e470e2f6..4646abbb164 100644 --- a/dashboardv3/public/js/views/business_metadata/BusinessMetadataAttrTableLayoutView.js +++ b/dashboardv3/public/js/views/business_metadata/BusinessMetadataAttrTableLayoutView.js @@ -108,6 +108,15 @@ define(['require', attrDetails.typeName = attrObj.typeName.replace("array<", "").replace(">", ""); attrDetails.multiValued = true; } + // Set cardinalityToggle based on existing cardinality (SET or LIST), default to SET + if (attrObj.cardinality) { + attrDetails.cardinalityToggle = (attrObj.cardinality === "LIST") ? "LIST" : "SET"; + } else { + // If cardinality is not set but it's an array type, default to SET + if (attrObj.typeName.includes('array')) { + attrDetails.cardinalityToggle = "SET"; + } + } } }); this.showDetails = false; @@ -197,6 +206,27 @@ define(['require', } }) }, + cardinality: { + label: "Cardinality", + cell: "html", + editable: false, + sortable: true, + formatter: _.extend({}, Backgrid.CellFormatter.prototype, { + fromRaw: function(rawValue, model) { + var cardinality = model.get('cardinality'); + if (!cardinality) { + // If cardinality is not set, determine from typeName + if (model.get('typeName').indexOf('array<') > -1) { + // Default to SET for array types if cardinality is not specified + cardinality = "SET"; + } else { + cardinality = "SINGLE"; + } + } + return _.escape(cardinality); + } + }) + }, maxStrLength: { label: "Max Length", cell: "html", diff --git a/dashboardv3/public/js/views/business_metadata/BusinessMetadataAttributeItemView.js b/dashboardv3/public/js/views/business_metadata/BusinessMetadataAttributeItemView.js index 5190db0319a..6dddb8f6515 100644 --- a/dashboardv3/public/js/views/business_metadata/BusinessMetadataAttributeItemView.js +++ b/dashboardv3/public/js/views/business_metadata/BusinessMetadataAttributeItemView.js @@ -48,6 +48,10 @@ define(['require', enumValueSelector: "[data-id='enumValueSelector']", multiValueSelect: "[data-id='multiValueSelect']", multiValueSelectStatus: "[data-id='multiValueSelectStatus']", + cardinalityToggleContainer: "[data-id='cardinalityToggleContainer']", + cardinalityToggle: "[data-id='cardinalityToggle']", + cardinalitySET: "[data-id='cardinalitySET']", + cardinalityLIST: "[data-id='cardinalityLIST']", stringLengthContainer: "[data-id='stringLengthContainer']", stringLengthValue: "[data-id='stringLength']", createNewEnum: "[data-id='createNewEnum']" @@ -122,15 +126,72 @@ define(['require', this.model.set({ "enumValues": this.ui.enumValueSelector.val() }); }; events["change " + this.ui.multiValueSelectStatus] = function(e) { + var that = this; this.model.set({ "multiValueSelect": e.target.checked }); var typename = this.model.get('typeName'); if (e.target.checked) { typename = "array<" + typename + ">"; + // Show cardinality toggle when multivalues is enabled + that.ui.cardinalityToggleContainer.show(); + // Disable cardinality toggle buttons in edit mode + if (that.isAttrEdit) { + that.ui.cardinalitySET.attr('disabled', 'disabled'); + that.ui.cardinalityLIST.attr('disabled', 'disabled'); + that.ui.cardinalitySET.addClass('disabled'); + that.ui.cardinalityLIST.addClass('disabled'); + } else { + that.ui.cardinalitySET.removeAttr('disabled'); + that.ui.cardinalityLIST.removeAttr('disabled'); + that.ui.cardinalitySET.removeClass('disabled'); + that.ui.cardinalityLIST.removeClass('disabled'); + } + // Set default cardinality to SET if not already set + if (!that.model.get('cardinalityToggle')) { + that.model.set({ "cardinalityToggle": "SET" }); + that.ui.cardinalitySET.addClass('active'); + that.ui.cardinalityLIST.removeClass('active'); + } else { + // Set active button based on current value + var currentCardinality = that.model.get('cardinalityToggle'); + if (currentCardinality === "LIST") { + that.ui.cardinalityLIST.addClass('active'); + that.ui.cardinalitySET.removeClass('active'); + } else { + that.ui.cardinalitySET.addClass('active'); + that.ui.cardinalityLIST.removeClass('active'); + } + } } else { typename = typename.replace('array<', '').replace('>', ''); + // Hide cardinality toggle when multivalues is disabled + that.ui.cardinalityToggleContainer.hide(); + // Reset cardinality toggle + that.model.set({ "cardinalityToggle": "SET" }); } this.model.set({ "typeName": typename }); }; + events["click " + this.ui.cardinalitySET] = function(e) { + e.preventDefault(); + var that = this; + // Disable cardinality toggle in edit mode + if (that.isAttrEdit) { + return; + } + that.model.set({ "cardinalityToggle": "SET" }); + that.ui.cardinalitySET.addClass('active'); + that.ui.cardinalityLIST.removeClass('active'); + }; + events["click " + this.ui.cardinalityLIST] = function(e) { + e.preventDefault(); + var that = this; + // Disable cardinality toggle in edit mode + if (that.isAttrEdit) { + return; + } + that.model.set({ "cardinalityToggle": "LIST" }); + that.ui.cardinalityLIST.addClass('active'); + that.ui.cardinalitySET.removeClass('active'); + }; events["change " + this.ui.entityTypeSelector] = function(e) { var options = this.model.get('options') || {}; options.applicableEntityTypes = JSON.stringify(this.ui.entityTypeSelector.val()); @@ -223,6 +284,24 @@ define(['require', this.ui.multiValueSelect.show(); $(this.ui.multiValueSelectStatus).prop('checked', true).trigger('change'); this.ui.multiValueSelectStatus.attr("disabled", "false"); + // Set cardinality toggle based on existing cardinality (SET or LIST), default to SET + var existingCardinality = this.model.get("cardinality"); + var cardinalityToggle = (existingCardinality === "LIST") ? "LIST" : "SET"; + this.model.set({ "cardinalityToggle": cardinalityToggle }); + if (cardinalityToggle === "LIST") { + this.ui.cardinalityLIST.addClass('active'); + this.ui.cardinalitySET.removeClass('active'); + } else { + this.ui.cardinalitySET.addClass('active'); + this.ui.cardinalityLIST.removeClass('active'); + } + // Disable cardinality toggle buttons in edit mode + if (this.isAttrEdit) { + this.ui.cardinalitySET.attr('disabled', 'disabled'); + this.ui.cardinalityLIST.attr('disabled', 'disabled'); + this.ui.cardinalitySET.addClass('disabled'); + this.ui.cardinalityLIST.addClass('disabled'); + } } } }, diff --git a/dashboardv3/public/js/views/business_metadata/BusinessMetadataTableLayoutView.js b/dashboardv3/public/js/views/business_metadata/BusinessMetadataTableLayoutView.js index 27463065686..099a220af77 100644 --- a/dashboardv3/public/js/views/business_metadata/BusinessMetadataTableLayoutView.js +++ b/dashboardv3/public/js/views/business_metadata/BusinessMetadataTableLayoutView.js @@ -244,11 +244,11 @@ define(['require', accordion: false, alwaysVisible: true, expand: function(el, model) { - el.attr('colspan', '8'); + el.attr('colspan', '9'); var attrValues = '', attrTable = $('table'), attrTableBody = $('tbody'), - attrTableHeading = "AttributeTypeSearch WeightEnable MultivaluesMax LengthApplicable Type(s)Action", + attrTableHeading = "AttributeTypeSearch WeightEnable MultivaluesCardinalityMax LengthApplicable Type(s)Action", attrRow = '', attrTableDetails = ''; if (model.attributes && model.attributes.attributeDefs.length) { @@ -256,7 +256,8 @@ define(['require', var applicableEntityTypes = '', typeName = attrObj.typeName, multiSelect = '', - maxString = 'NA'; + maxString = 'NA', + cardinality = 'SINGLE'; if (attrObj.options && attrObj.options.applicableEntityTypes) { var entityTypes = JSON.parse(attrObj.options.applicableEntityTypes); _.each(entityTypes, function(values) { @@ -266,12 +267,21 @@ define(['require', if (typeName.includes('array')) { typeName = _.escape(typeName); multiSelect = 'checked'; + // Determine cardinality - use existing cardinality value or default to SET + if (attrObj.cardinality) { + cardinality = attrObj.cardinality; + } else { + cardinality = 'SET'; + } + } else { + // For non-array types, cardinality is SINGLE + cardinality = 'SINGLE'; } if (typeName.includes('string') && attrObj.options && attrObj.options.maxStrLength) { maxString = attrObj.options.maxStrLength; } - attrRow += " " + _.escape(attrObj.name) + "" + typeName + "" + _.escape(attrObj.searchWeight) + " " + maxString + "" + applicableEntityTypes + "
Edit
"; + attrRow += " " + _.escape(attrObj.name) + "" + typeName + "" + _.escape(attrObj.searchWeight) + " " + _.escape(cardinality) + "" + maxString + "" + applicableEntityTypes + "
Edit
"; }); var adminText = '
' + attrTableHeading + attrRow + '
'; $(el).append($('
').html(adminText)); diff --git a/dashboardv3/public/js/views/business_metadata/CreateBusinessMetadataLayoutView.js b/dashboardv3/public/js/views/business_metadata/CreateBusinessMetadataLayoutView.js index 165b9950087..200e4ad164a 100644 --- a/dashboardv3/public/js/views/business_metadata/CreateBusinessMetadataLayoutView.js +++ b/dashboardv3/public/js/views/business_metadata/CreateBusinessMetadataLayoutView.js @@ -216,6 +216,27 @@ define(['require', } }, + processAttributes: function(attributes) { + var that = this; + return attributes.map(function(item) { + var multiValueSelect = item.multiValueSelect || false; + var cardinalityToggle = item.cardinalityToggle || "SET"; + + // Determine cardinality based on multiValueSelect and cardinality toggle + var finalCardinality = "SINGLE"; + if (multiValueSelect) { + // If multivalues is enabled, use the cardinalityToggle (SET or LIST) + // Default to SET if not specified + finalCardinality = cardinalityToggle === "LIST" ? "LIST" : (item.cardinality === "LIST" ? "LIST" : "SET"); + } + + // Remove cardinalityToggle from the final object as it's not part of API + var processedItem = _.omit(item, 'cardinalityToggle'); + processedItem.cardinality = finalCardinality; + + return processedItem; + }); + }, onCreateBusinessMetadata: function() { var that = this; if (this.validateValues()) { @@ -227,6 +248,9 @@ define(['require', var attributeObj = this.collection.toJSON(); if (this.collection.length === 1 && this.collection.first().get("name") === "") { attributeObj = []; + } else { + // Process attributes to include cardinality + attributeObj = this.processAttributes(attributeObj); } this.json = { "enumDefs": [], @@ -279,7 +303,9 @@ define(['require', if (selectedBusinessMetadataClone.attributeDefs === undefined) { selectedBusinessMetadataClone.attributeDefs = []; } - selectedBusinessMetadataClone.attributeDefs = selectedBusinessMetadataClone.attributeDefs.concat(this.collection.toJSON()); + // Process new attributes to include cardinality + var newAttributes = this.processAttributes(this.collection.toJSON()); + selectedBusinessMetadataClone.attributeDefs = selectedBusinessMetadataClone.attributeDefs.concat(newAttributes); this.json = { "enumDefs": [], "structDefs": [],