Fix table multiple pending changes

This commit is contained in:
Carlos Monastyrski
2025-11-19 12:43:54 -03:00
parent 1b34699142
commit 5cd6bf8213
3 changed files with 45 additions and 28 deletions
@@ -483,8 +483,8 @@ export const secretV2BridgeServiceFactory = ({
}); });
if (!sharedSecretToModify) if (!sharedSecretToModify)
throw new NotFoundError({ message: `Secret with name ${inputSecret.secretName} not found` }); throw new NotFoundError({ message: `Secret with name ${inputSecret.secretName} not found` });
if (sharedSecretToModify.isRotatedSecret && (inputSecret.newSecretName || inputSecret.secretValue)) if (sharedSecretToModify.isRotatedSecret && inputSecret.newSecretName)
throw new BadRequestError({ message: "Cannot update rotated secret name or value" }); throw new BadRequestError({ message: "Cannot update rotated secret name" });
secretId = sharedSecretToModify.id; secretId = sharedSecretToModify.id;
secret = sharedSecretToModify; secret = sharedSecretToModify;
} }
@@ -1934,8 +1934,14 @@ export const secretV2BridgeServiceFactory = ({
if (el.isRotatedSecret) { if (el.isRotatedSecret) {
const input = secretsToUpdateGroupByPath[secretPath].find((i) => i.secretKey === el.key); const input = secretsToUpdateGroupByPath[secretPath].find((i) => i.secretKey === el.key);
if (input && (input.newSecretName || input.secretValue)) if (input) {
throw new BadRequestError({ message: `Cannot update rotated secret name or value: ${el.key}` }); if (input.newSecretName) {
delete input.newSecretName;
}
if (input.secretValue !== undefined) {
delete input.secretValue;
}
}
} }
}); });
@@ -2061,8 +2067,11 @@ export const secretV2BridgeServiceFactory = ({
commitChanges, commitChanges,
inputSecrets: secretsToUpdate.map((el) => { inputSecrets: secretsToUpdate.map((el) => {
const originalSecret = secretsToUpdateInDBGroupedByKey[el.secretKey][0]; const originalSecret = secretsToUpdateInDBGroupedByKey[el.secretKey][0];
const shouldUpdateValue = !originalSecret.isRotatedSecret && typeof el.secretValue !== "undefined";
const shouldUpdateName = !originalSecret.isRotatedSecret && el.newSecretName;
const encryptedValue = const encryptedValue =
typeof el.secretValue !== "undefined" shouldUpdateValue && el.secretValue !== undefined
? { ? {
encryptedValue: secretManagerEncryptor({ plainText: Buffer.from(el.secretValue) }).cipherTextBlob, encryptedValue: secretManagerEncryptor({ plainText: Buffer.from(el.secretValue) }).cipherTextBlob,
references: secretReferencesGroupByInputSecretKey[el.secretKey]?.nestedReferences references: secretReferencesGroupByInputSecretKey[el.secretKey]?.nestedReferences
@@ -2077,7 +2086,7 @@ export const secretV2BridgeServiceFactory = ({
(value) => secretManagerEncryptor({ plainText: Buffer.from(value) }).cipherTextBlob (value) => secretManagerEncryptor({ plainText: Buffer.from(value) }).cipherTextBlob
), ),
skipMultilineEncoding: el.skipMultilineEncoding, skipMultilineEncoding: el.skipMultilineEncoding,
key: el.newSecretName || el.secretKey, key: shouldUpdateName ? el.newSecretName : el.secretKey,
tags: el.tagIds, tags: el.tagIds,
secretMetadata: el.secretMetadata, secretMetadata: el.secretMetadata,
...encryptedValue ...encryptedValue
@@ -52,6 +52,7 @@ type Props = {
}[]; }[];
}[]; }[];
colWidth: number; colWidth: number;
excludePendingCreates?: boolean;
}; };
export const SecretListView = ({ export const SecretListView = ({
@@ -64,7 +65,8 @@ export const SecretListView = ({
isProtectedBranch = false, isProtectedBranch = false,
usedBySecretSyncs, usedBySecretSyncs,
importedBy, importedBy,
colWidth colWidth,
excludePendingCreates = false
}: Props) => { }: Props) => {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const { popUp, handlePopUpToggle, handlePopUpOpen, handlePopUpClose } = usePopUp([ const { popUp, handlePopUpToggle, handlePopUpOpen, handlePopUpClose } = usePopUp([
@@ -580,27 +582,32 @@ export const SecretListView = ({
{FontAwesomeSpriteSymbols.map(({ icon, symbol }) => ( {FontAwesomeSpriteSymbols.map(({ icon, symbol }) => (
<FontAwesomeIcon icon={icon} symbol={symbol} key={`font-awesome-svg-spritie-${symbol}`} /> <FontAwesomeIcon icon={icon} symbol={symbol} key={`font-awesome-svg-spritie-${symbol}`} />
))} ))}
{secrets.map((secret) => ( {secrets
<SecretItem .filter((secret) => {
colWidth={colWidth} if (!excludePendingCreates) return true;
environment={environment} return !secret.isPending || secret.pendingAction !== PendingAction.Create;
secretPath={secretPath} })
tags={wsTags} .map((secret) => (
isSelected={Boolean(selectedSecrets?.[secret.id])} <SecretItem
onToggleSecretSelect={toggleSelectedSecret} colWidth={colWidth}
isVisible={isVisible} environment={environment}
secret={secret} secretPath={secretPath}
key={secret.id} tags={wsTags}
onSaveSecret={handleSaveSecret} isSelected={Boolean(selectedSecrets?.[secret.id])}
onDeleteSecret={onDeleteSecret} onToggleSecretSelect={toggleSelectedSecret}
onDetailViewSecret={onDetailViewSecret} isVisible={isVisible}
importedBy={importedBy} secret={secret}
onCreateTag={onCreateTag} key={secret.id}
onShareSecret={onShareSecret} onSaveSecret={handleSaveSecret}
isPending={secret.isPending} onDeleteSecret={onDeleteSecret}
pendingAction={secret.pendingAction} onDetailViewSecret={onDetailViewSecret}
/> importedBy={importedBy}
))} onCreateTag={onCreateTag}
onShareSecret={onShareSecret}
isPending={secret.isPending}
pendingAction={secret.pendingAction}
/>
))}
<DeleteActionModal <DeleteActionModal
isOpen={popUp.deleteSecret.isOpen} isOpen={popUp.deleteSecret.isOpen}
deleteKey={(popUp.deleteSecret?.data as SecretV3RawSanitized)?.key} deleteKey={(popUp.deleteSecret?.data as SecretV3RawSanitized)?.key}
@@ -253,6 +253,7 @@ export const SecretRotationItem = ({
isProtectedBranch={isProtectedBranch} isProtectedBranch={isProtectedBranch}
importedBy={importedBy} importedBy={importedBy}
usedBySecretSyncs={usedBySecretSyncs} usedBySecretSyncs={usedBySecretSyncs}
excludePendingCreates
/> />
)} )}
<Modal onOpenChange={setShowSecrets} isOpen={showSecrets}> <Modal onOpenChange={setShowSecrets} isOpen={showSecrets}>