Loading components/marketplace/service-spec-management-add-char.tsx +24 −15 Changes for components/marketplace/service-spec-management-add-char.tsx: 24 added lines, 15 removed lines. Original line number Diff line number Diff line Loading @@ -18,12 +18,15 @@ export default function ServiceSpecManagementAddChar({ handleSpecChars, char, isReadOnly = false, // Add this prop with default value false onlyDefaultEditable = false, }: { onClose: () => void; handleSpecChars: (value: CharacteristicSpecification) => void; char?: CharacteristicSpecification; isReadOnly?: boolean; // New prop to control read-only mode onlyDefaultEditable?: boolean; }) { const lockFields = isReadOnly || onlyDefaultEditable; const [name, setName] = useState(char?.name || ''); const [description, setDescription] = useState(char?.description || ''); // Value Type selection Loading Loading @@ -62,7 +65,9 @@ export default function ServiceSpecManagementAddChar({ const [specificValue, setSpecificValue] = useState<CharacteristicValueSpecification | undefined>( undefined, ); const [inheritedValueCount] = useState( onlyDefaultEditable ? (char?.characteristicValueSpecification?.length ?? 0) : 0, ); const schema = z.object({ name: z.string().min(1, 'Name is required'), description: z.string(), Loading Loading @@ -162,10 +167,7 @@ export default function ServiceSpecManagementAddChar({ description, ...(charValues.length ? { characteristicValueSpecification: charValues.map((charValue) => ({ value: charValue.value, isDefault: charValue.isDefault, })), characteristicValueSpecification: charValues.map((charValue) => ({ ...charValue })), } : {}), configurable, Loading Loading @@ -228,6 +230,8 @@ export default function ServiceSpecManagementAddChar({ <div className="text-xl text-maestro-blue-80"> {isReadOnly ? 'View Parent Characteristic' : onlyDefaultEditable ? 'Edit Inherited Default' : char ? 'Edit Characteristic' : 'New Characteristic'} Loading @@ -254,7 +258,7 @@ export default function ServiceSpecManagementAddChar({ handleInputChange('name', value); }} aria-label="name" isDisabled={isReadOnly} isDisabled={lockFields} /> )} /> Loading @@ -277,7 +281,7 @@ export default function ServiceSpecManagementAddChar({ handleInputChange('description', value); }} aria-label="description" isDisabled={isReadOnly} isDisabled={lockFields} /> )} /> Loading @@ -298,7 +302,7 @@ export default function ServiceSpecManagementAddChar({ ? [valueTypes[0]] : [] } isDisabled={isReadOnly} isDisabled={lockFields} onSelectionChange={(keys) => { const selected = Array.from(keys)[0] as string; setValueType(selected); Loading Loading @@ -345,7 +349,7 @@ export default function ServiceSpecManagementAddChar({ field.onChange(e.target.checked); handleInputChange('configurable', e.target.checked); }} isDisabled={isReadOnly} isDisabled={lockFields} /> </div> )} Loading @@ -364,7 +368,7 @@ export default function ServiceSpecManagementAddChar({ {charValue?.value?.value} </div> {!isReadOnly && ( {!isReadOnly && !(onlyDefaultEditable && index < inheritedValueCount) && ( <Button onPress={() => setCharValues((prev) => prev.filter((_, i) => i !== index)) Loading @@ -384,6 +388,11 @@ export default function ServiceSpecManagementAddChar({ charValue={specificValue} charValues={charValues} isReadOnly={isReadOnly} // Pass the isReadOnly prop to ServiceSpecManagementAddCharValue // onlyDefaultEditable={ // onlyDefaultEditable && // valueIndex !== '' && // Number(valueIndex) < inheritedValueCount // } /> )} </div> Loading Loading @@ -411,7 +420,7 @@ export default function ServiceSpecManagementAddChar({ handleInputChange('minCardinality', value); }} aria-label="minCardinality" isDisabled={isReadOnly} isDisabled={lockFields} /> )} /> Loading @@ -434,7 +443,7 @@ export default function ServiceSpecManagementAddChar({ handleInputChange('maxCardinality', value); }} aria-label="maxCardinality" isDisabled={isReadOnly} isDisabled={lockFields} /> )} /> Loading @@ -460,7 +469,7 @@ export default function ServiceSpecManagementAddChar({ field.onChange(e.target.checked); handleInputChange('isUnique', e.target.checked); }} isDisabled={isReadOnly} isDisabled={lockFields} /> </div> )} Loading @@ -480,7 +489,7 @@ export default function ServiceSpecManagementAddChar({ field.onChange(e.target.checked); handleInputChange('extensible', e.target.checked); }} isDisabled={isReadOnly} isDisabled={lockFields} /> </div> )} Loading @@ -494,7 +503,7 @@ export default function ServiceSpecManagementAddChar({ currentServiceSpecCharacteristic={char} onChange={handleInputChange} mode={'create'} isReadOnly={isReadOnly} // Pass the isReadOnly prop isReadOnly={lockFields} // Pass the isReadOnly prop /> </div> </form> Loading components/marketplace/service-spec-managment-modal.tsx +28 −48 Changes for components/marketplace/service-spec-managment-modal.tsx: 28 added lines, 48 removed lines. Original line number Diff line number Diff line Loading @@ -123,6 +123,7 @@ export default function ServiceSpecManagementModal({ const [currentParentSpecId, setCurrentParentSpecId] = useState<string | undefined>(undefined); const [originalParentId, setOriginalParentId] = useState<string | undefined>(undefined); const [relationshipTypes, setRelationshipTypes] = useState<string[]>([]); const [isInheritedChar, setIsInheritedChar] = useState(false); useEffect(() => { const fetchTypes = async () => { Loading Loading @@ -264,41 +265,31 @@ export default function ServiceSpecManagementModal({ const handleSpecChars = (value: CharacteristicSpecification) => { try { // Case 1: Adding a new characteristic if (!charIndex) { setCharSpecs((prev) => [...prev, value]); } // Case 2: Editing an existing characteristic else { } else { const indexNum = !isNaN(Number(charIndex)) ? Number(charIndex) : -1; setCharSpecs((prev) => { if (indexNum >= 0 && indexNum < prev.length) { const updated = [...prev]; const originalId = prev[indexNum].id; if (isInheritedChar) { // Only the default/value specification may be overridden updated[indexNum] = { ...value, id: originalId || value.id, ...prev[indexNum], characteristicValueSpecification: value.characteristicValueSpecification, }; return updated; } else if (charIndex === 'parent') { return prev; } else { updated[indexNum] = { ...value, id: prev[indexNum].id || value.id }; } return updated; } return prev.map((char) => { const matchById = value.id && char.id === value.id; const matchByName = !matchById && value.name && char.name === value.name; if (matchById || matchByName) { return { ...value, id: char.id || value.id, }; } return char; return matchById || matchByName ? { ...value, id: char.id || value.id } : char; }); } }); } } catch (error) { Loading @@ -306,6 +297,7 @@ export default function ServiceSpecManagementModal({ } finally { setCharIndex(''); setSpecificChar(undefined); setIsInheritedChar(false); } }; Loading Loading @@ -521,15 +513,23 @@ export default function ServiceSpecManagementModal({ setReturnedError('An unexpected error occurred'); } }; const openInheritedChar = (char: CharacteristicSpecification) => { const realIndex = charSpecs.findIndex((c) => c === char); setCharIndex(realIndex.toString()); setIsInheritedChar(true); setSpecificChar(char); setModalAddChar(true); }; const openModalAddChar = (char?: CharacteristicSpecification, index?: number) => { setCharIndex(index !== undefined ? index.toString() : ''); setIsInheritedChar(false); setModalAddChar(true); setSpecificChar(char); }; const closeModalAddChar = () => { setModalAddChar(false); setIsInheritedChar(false); }; const setParent = (spec: ServiceSpecification | undefined) => { Loading Loading @@ -940,7 +940,7 @@ export default function ServiceSpecManagementModal({ validFor: char.validFor ? { ...char.validFor } : undefined, characteristicValueSpecification: char.characteristicValueSpecification ? [...char.characteristicValueSpecification] ? structuredClone(char.characteristicValueSpecification) : undefined, }; }, Loading Loading @@ -994,14 +994,7 @@ export default function ServiceSpecManagementModal({ > <div className="w-full cursor-pointer" onClick={() => { setCharIndex('parent'); setModalAddChar(true); setSpecificChar({ ...char, isReadOnly: true, } as CharacteristicSpecification & { isReadOnly: boolean }); }} onClick={() => openInheritedChar(char)} > <span>{displayName}</span> </div> Loading Loading @@ -1204,17 +1197,10 @@ export default function ServiceSpecManagementModal({ <div className="flex w-full justify-end gap-2"> <Button onClick={() => { setModalAddChar(true); setCharIndex('parent'); setSpecificChar({ ...char, isReadOnly: true, } as CharacteristicSpecification & { isReadOnly: boolean }); }} onClick={() => openInheritedChar(char)} className="rounded-md bg-maestro-turquoise text-maestro-white" > VIEW EDIT DEFAULT </Button> </div> </div> Loading Loading @@ -1375,14 +1361,7 @@ export default function ServiceSpecManagementModal({ DELETE </Button> <Button onClick={() => { setModalAddChar(true); setCharIndex(realIndex.toString()); setSpecificChar({ ...char, isReadOnly: true, } as CharacteristicSpecification & { isReadOnly: boolean }); }} onClick={() => openModalAddChar(char, realIndex)} className="rounded-md bg-maestro-turquoise text-maestro-white" > EDIT Loading @@ -1401,7 +1380,8 @@ export default function ServiceSpecManagementModal({ onClose={closeModalAddChar} handleSpecChars={handleSpecChars} char={specificChar} isReadOnly={charIndex === 'parent'} isReadOnly={false} onlyDefaultEditable={isInheritedChar} /> )} </div> Loading Loading
components/marketplace/service-spec-management-add-char.tsx +24 −15 Changes for components/marketplace/service-spec-management-add-char.tsx: 24 added lines, 15 removed lines. Original line number Diff line number Diff line Loading @@ -18,12 +18,15 @@ export default function ServiceSpecManagementAddChar({ handleSpecChars, char, isReadOnly = false, // Add this prop with default value false onlyDefaultEditable = false, }: { onClose: () => void; handleSpecChars: (value: CharacteristicSpecification) => void; char?: CharacteristicSpecification; isReadOnly?: boolean; // New prop to control read-only mode onlyDefaultEditable?: boolean; }) { const lockFields = isReadOnly || onlyDefaultEditable; const [name, setName] = useState(char?.name || ''); const [description, setDescription] = useState(char?.description || ''); // Value Type selection Loading Loading @@ -62,7 +65,9 @@ export default function ServiceSpecManagementAddChar({ const [specificValue, setSpecificValue] = useState<CharacteristicValueSpecification | undefined>( undefined, ); const [inheritedValueCount] = useState( onlyDefaultEditable ? (char?.characteristicValueSpecification?.length ?? 0) : 0, ); const schema = z.object({ name: z.string().min(1, 'Name is required'), description: z.string(), Loading Loading @@ -162,10 +167,7 @@ export default function ServiceSpecManagementAddChar({ description, ...(charValues.length ? { characteristicValueSpecification: charValues.map((charValue) => ({ value: charValue.value, isDefault: charValue.isDefault, })), characteristicValueSpecification: charValues.map((charValue) => ({ ...charValue })), } : {}), configurable, Loading Loading @@ -228,6 +230,8 @@ export default function ServiceSpecManagementAddChar({ <div className="text-xl text-maestro-blue-80"> {isReadOnly ? 'View Parent Characteristic' : onlyDefaultEditable ? 'Edit Inherited Default' : char ? 'Edit Characteristic' : 'New Characteristic'} Loading @@ -254,7 +258,7 @@ export default function ServiceSpecManagementAddChar({ handleInputChange('name', value); }} aria-label="name" isDisabled={isReadOnly} isDisabled={lockFields} /> )} /> Loading @@ -277,7 +281,7 @@ export default function ServiceSpecManagementAddChar({ handleInputChange('description', value); }} aria-label="description" isDisabled={isReadOnly} isDisabled={lockFields} /> )} /> Loading @@ -298,7 +302,7 @@ export default function ServiceSpecManagementAddChar({ ? [valueTypes[0]] : [] } isDisabled={isReadOnly} isDisabled={lockFields} onSelectionChange={(keys) => { const selected = Array.from(keys)[0] as string; setValueType(selected); Loading Loading @@ -345,7 +349,7 @@ export default function ServiceSpecManagementAddChar({ field.onChange(e.target.checked); handleInputChange('configurable', e.target.checked); }} isDisabled={isReadOnly} isDisabled={lockFields} /> </div> )} Loading @@ -364,7 +368,7 @@ export default function ServiceSpecManagementAddChar({ {charValue?.value?.value} </div> {!isReadOnly && ( {!isReadOnly && !(onlyDefaultEditable && index < inheritedValueCount) && ( <Button onPress={() => setCharValues((prev) => prev.filter((_, i) => i !== index)) Loading @@ -384,6 +388,11 @@ export default function ServiceSpecManagementAddChar({ charValue={specificValue} charValues={charValues} isReadOnly={isReadOnly} // Pass the isReadOnly prop to ServiceSpecManagementAddCharValue // onlyDefaultEditable={ // onlyDefaultEditable && // valueIndex !== '' && // Number(valueIndex) < inheritedValueCount // } /> )} </div> Loading Loading @@ -411,7 +420,7 @@ export default function ServiceSpecManagementAddChar({ handleInputChange('minCardinality', value); }} aria-label="minCardinality" isDisabled={isReadOnly} isDisabled={lockFields} /> )} /> Loading @@ -434,7 +443,7 @@ export default function ServiceSpecManagementAddChar({ handleInputChange('maxCardinality', value); }} aria-label="maxCardinality" isDisabled={isReadOnly} isDisabled={lockFields} /> )} /> Loading @@ -460,7 +469,7 @@ export default function ServiceSpecManagementAddChar({ field.onChange(e.target.checked); handleInputChange('isUnique', e.target.checked); }} isDisabled={isReadOnly} isDisabled={lockFields} /> </div> )} Loading @@ -480,7 +489,7 @@ export default function ServiceSpecManagementAddChar({ field.onChange(e.target.checked); handleInputChange('extensible', e.target.checked); }} isDisabled={isReadOnly} isDisabled={lockFields} /> </div> )} Loading @@ -494,7 +503,7 @@ export default function ServiceSpecManagementAddChar({ currentServiceSpecCharacteristic={char} onChange={handleInputChange} mode={'create'} isReadOnly={isReadOnly} // Pass the isReadOnly prop isReadOnly={lockFields} // Pass the isReadOnly prop /> </div> </form> Loading
components/marketplace/service-spec-managment-modal.tsx +28 −48 Changes for components/marketplace/service-spec-managment-modal.tsx: 28 added lines, 48 removed lines. Original line number Diff line number Diff line Loading @@ -123,6 +123,7 @@ export default function ServiceSpecManagementModal({ const [currentParentSpecId, setCurrentParentSpecId] = useState<string | undefined>(undefined); const [originalParentId, setOriginalParentId] = useState<string | undefined>(undefined); const [relationshipTypes, setRelationshipTypes] = useState<string[]>([]); const [isInheritedChar, setIsInheritedChar] = useState(false); useEffect(() => { const fetchTypes = async () => { Loading Loading @@ -264,41 +265,31 @@ export default function ServiceSpecManagementModal({ const handleSpecChars = (value: CharacteristicSpecification) => { try { // Case 1: Adding a new characteristic if (!charIndex) { setCharSpecs((prev) => [...prev, value]); } // Case 2: Editing an existing characteristic else { } else { const indexNum = !isNaN(Number(charIndex)) ? Number(charIndex) : -1; setCharSpecs((prev) => { if (indexNum >= 0 && indexNum < prev.length) { const updated = [...prev]; const originalId = prev[indexNum].id; if (isInheritedChar) { // Only the default/value specification may be overridden updated[indexNum] = { ...value, id: originalId || value.id, ...prev[indexNum], characteristicValueSpecification: value.characteristicValueSpecification, }; return updated; } else if (charIndex === 'parent') { return prev; } else { updated[indexNum] = { ...value, id: prev[indexNum].id || value.id }; } return updated; } return prev.map((char) => { const matchById = value.id && char.id === value.id; const matchByName = !matchById && value.name && char.name === value.name; if (matchById || matchByName) { return { ...value, id: char.id || value.id, }; } return char; return matchById || matchByName ? { ...value, id: char.id || value.id } : char; }); } }); } } catch (error) { Loading @@ -306,6 +297,7 @@ export default function ServiceSpecManagementModal({ } finally { setCharIndex(''); setSpecificChar(undefined); setIsInheritedChar(false); } }; Loading Loading @@ -521,15 +513,23 @@ export default function ServiceSpecManagementModal({ setReturnedError('An unexpected error occurred'); } }; const openInheritedChar = (char: CharacteristicSpecification) => { const realIndex = charSpecs.findIndex((c) => c === char); setCharIndex(realIndex.toString()); setIsInheritedChar(true); setSpecificChar(char); setModalAddChar(true); }; const openModalAddChar = (char?: CharacteristicSpecification, index?: number) => { setCharIndex(index !== undefined ? index.toString() : ''); setIsInheritedChar(false); setModalAddChar(true); setSpecificChar(char); }; const closeModalAddChar = () => { setModalAddChar(false); setIsInheritedChar(false); }; const setParent = (spec: ServiceSpecification | undefined) => { Loading Loading @@ -940,7 +940,7 @@ export default function ServiceSpecManagementModal({ validFor: char.validFor ? { ...char.validFor } : undefined, characteristicValueSpecification: char.characteristicValueSpecification ? [...char.characteristicValueSpecification] ? structuredClone(char.characteristicValueSpecification) : undefined, }; }, Loading Loading @@ -994,14 +994,7 @@ export default function ServiceSpecManagementModal({ > <div className="w-full cursor-pointer" onClick={() => { setCharIndex('parent'); setModalAddChar(true); setSpecificChar({ ...char, isReadOnly: true, } as CharacteristicSpecification & { isReadOnly: boolean }); }} onClick={() => openInheritedChar(char)} > <span>{displayName}</span> </div> Loading Loading @@ -1204,17 +1197,10 @@ export default function ServiceSpecManagementModal({ <div className="flex w-full justify-end gap-2"> <Button onClick={() => { setModalAddChar(true); setCharIndex('parent'); setSpecificChar({ ...char, isReadOnly: true, } as CharacteristicSpecification & { isReadOnly: boolean }); }} onClick={() => openInheritedChar(char)} className="rounded-md bg-maestro-turquoise text-maestro-white" > VIEW EDIT DEFAULT </Button> </div> </div> Loading Loading @@ -1375,14 +1361,7 @@ export default function ServiceSpecManagementModal({ DELETE </Button> <Button onClick={() => { setModalAddChar(true); setCharIndex(realIndex.toString()); setSpecificChar({ ...char, isReadOnly: true, } as CharacteristicSpecification & { isReadOnly: boolean }); }} onClick={() => openModalAddChar(char, realIndex)} className="rounded-md bg-maestro-turquoise text-maestro-white" > EDIT Loading @@ -1401,7 +1380,8 @@ export default function ServiceSpecManagementModal({ onClose={closeModalAddChar} handleSpecChars={handleSpecChars} char={specificChar} isReadOnly={charIndex === 'parent'} isReadOnly={false} onlyDefaultEditable={isInheritedChar} /> )} </div> Loading