Skip to content

Commit 113c306

Browse files
committed
fix(access-control): trim the name comparison the same way as description
nameChanged compared a trimmed buffer against an untrimmed baseline — the exact asymmetry already fixed for description. A group stored before the name schema gained .trim() opens permanently dirty: Save/Discard visible and the unsaved-changes modal firing on back, until a save rewrites it. Both buffers now seed trimmed and compare trimmed on both sides. Also dims the Info badge along with the row it belongs to when the block is disallowed.
1 parent 86cec38 commit 113c306

1 file changed

Lines changed: 10 additions & 10 deletions

File tree

apps/sim/ee/access-control/components/group-detail.tsx

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,7 @@ function BlockToolRow({
766766
</button>
767767
{/* Outside the button: an Info trigger is itself a button and cannot nest. */}
768768
{block.description && (
769-
<Info side='top' className='flex-shrink-0'>
769+
<Info side='top' className={cn('flex-shrink-0', !isBlockAllowed && 'opacity-60')}>
770770
{block.description}
771771
</Info>
772772
)}
@@ -824,14 +824,14 @@ export function GroupDetail({
824824
*/
825825
const [viewingGroup, setViewingGroup] = useState<PermissionGroup>(group)
826826
const [editingConfig, setEditingConfig] = useState<PermissionGroupConfig>({ ...group.config })
827-
const [editingName, setEditingName] = useState(group.name)
827+
const [editingName, setEditingName] = useState(group.name.trim())
828828
const [editingDescription, setEditingDescription] = useState((group.description ?? '').trim())
829829
const prevGroupIdRef = useRef(group.id)
830830
if (prevGroupIdRef.current !== group.id) {
831831
prevGroupIdRef.current = group.id
832832
setViewingGroup(group)
833833
setEditingConfig({ ...group.config })
834-
setEditingName(group.name)
834+
setEditingName(group.name.trim())
835835
setEditingDescription((group.description ?? '').trim())
836836
}
837837

@@ -954,14 +954,14 @@ export function GroupDetail({
954954
return JSON.stringify(viewingGroup.config) !== JSON.stringify(editingConfig)
955955
}, [viewingGroup.config, editingConfig])
956956

957+
// Both buffers are seeded trimmed and compared against a trimmed baseline. The
958+
// contract trims name and description on write, but a row stored before those
959+
// schemas gained `.trim()` (or written straight to the API) can still carry
960+
// padding — compared raw it would open dirty with no way to clear it, since
961+
// Discard restores the same padded value.
957962
const trimmedName = editingName.trim()
958963
const trimmedDescription = editingDescription.trim()
959-
const nameChanged = trimmedName !== viewingGroup.name
960-
// `name` is trimmed by its contract schema, but a description stored before
961-
// description trimming was added (or written straight to the API) can still
962-
// carry padding. The buffer is
963-
// seeded trimmed and compared against a trimmed baseline, so such a row opens
964-
// clean instead of being dirty with no way to clear it.
964+
const nameChanged = trimmedName !== viewingGroup.name.trim()
965965
const descriptionChanged = trimmedDescription !== (viewingGroup.description ?? '').trim()
966966
const hasChanges = hasConfigChanges || nameChanged || descriptionChanged
967967

@@ -1353,7 +1353,7 @@ export function GroupDetail({
13531353

13541354
const handleDiscardConfig = () => {
13551355
setEditingConfig({ ...viewingGroup.config })
1356-
setEditingName(viewingGroup.name)
1356+
setEditingName(viewingGroup.name.trim())
13571357
setEditingDescription((viewingGroup.description ?? '').trim())
13581358
}
13591359

0 commit comments

Comments
 (0)