Skip to content

Commit

Permalink
set state upstream even if invalid, better input logic
Browse files Browse the repository at this point in the history
  • Loading branch information
gsteenkamp89 committed Feb 7, 2024
1 parent dee32dc commit 70cf32a
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 21 deletions.
4 changes: 2 additions & 2 deletions src/components/Ui/UiInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ const props = defineProps<{
const emit = defineEmits(['update:modelValue', 'blur']);
function handleInput(e) {
const input = e.target.value;
function handleInput(e: Event) {
const input = (e.target as HTMLInputElement).value;
if (props.number) {
return emit('update:modelValue', !input ? undefined : parseFloat(input));
}
Expand Down
2 changes: 2 additions & 0 deletions src/composables/useFormSpaceProposal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useStorage } from '@vueuse/core';
import { clone } from '@snapshot-labs/snapshot.js/src/utils';
import schemas from '@snapshot-labs/snapshot.js/src/schemas';
import { validateForm } from '@/helpers/validation';
import { OsnapPluginData } from '@/plugins/oSnap/types';

interface ProposalForm {
name: string;
Expand All @@ -15,6 +16,7 @@ interface ProposalForm {
metadata: {
plugins: {
safeSnap?: { valid: boolean };
oSnap?: OsnapPluginData;
};
};
}
Expand Down
40 changes: 34 additions & 6 deletions src/plugins/oSnap/Create.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ import {
getGnosisSafeBalances,
getGnosisSafeCollectibles,
getIsOsnapEnabled,
getModuleAddressForTreasury
getModuleAddressForTreasury,
validateTransaction
} from './utils';
import OsnapMarketingWidget from './components/OsnapMarketingWidget.vue';
Expand All @@ -43,22 +44,30 @@ const safes = ref<GnosisSafe[]>([]);
const tokens = ref<Token[]>([]);
const collectables = ref<NFT[]>([]);
const transactionsValid = ref(false);
function addTransaction(transaction: Transaction) {
if (newPluginData.value.safe === null) return;
newPluginData.value.safe.transactions.push(transaction);
newPluginData.value.safe.transactions.push({
...transaction,
isValid: validateTransaction(transaction)
});
update(newPluginData.value);
}
function removeTransaction(transactionIndex: number) {
if (!newPluginData.value.safe) return;
newPluginData.value.safe.transactions.splice(transactionIndex, 1);
update(newPluginData.value);
}
function updateTransaction(transaction: Transaction, transactionIndex: number) {
if (!newPluginData.value.safe) return;
newPluginData.value.safe.transactions[transactionIndex] = transaction;
newPluginData.value.safe.transactions[transactionIndex] = {
...transaction,
isValid: validateTransaction(transaction)
};
update(newPluginData.value);
}
Expand All @@ -76,7 +85,6 @@ async function fetchBalances(network: Network, safeAddress: string) {
if (!safeAddress) {
return [];
}
try {
const balances = await getGnosisSafeBalances(network, safeAddress);
Expand Down Expand Up @@ -226,14 +234,34 @@ onMounted(async () => {
update(newPluginData.value);
isLoading.value = false;
});
watch(newPluginData, () => {
// validate form here, set isValid accordingly upstream
if (!newPluginData.value.safe) {
return;
}
// can't publish without transactions
if (newPluginData.value.safe.transactions.length === 0) {
transactionsValid.value = false;
return;
}
// check ALL transactions
if (newPluginData.value.safe.transactions.every(validateTransaction)) {
transactionsValid.value = false;
return;
}
// default to invalid
transactionsValid.value = false;
});
</script>

<template>
<template v-if="hasLegacyPluginInstalled">
<div class="rounded-2xl border p-4 text-md">
<h2 class="mb-2">Warning: Multiple oSnap enabled plugins detected</h2>
<p class="mb-2">
For best experience using oSnap, please remove the SafeSnap plugin from your space.
For best experience using oSnap, please remove the SafeSnap plugin from
your space.
</p>
</div>
</template>
Expand Down
15 changes: 11 additions & 4 deletions src/plugins/oSnap/components/Input/Amount.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,31 @@ const dirty = ref(false);
const format = (amount: string) => {
try {
return parseUnits(amount, props.decimals).toString();
// empty string throws
const parsed = parseUnits(amount, props.decimals).toString();
return parsed;
} catch (error) {
return undefined;
return parseUnits('0', props.decimals).toString();
}
};
const handleInput = () => {
dirty.value = true;
const value = format(input.value);
isValid.value = !!value;
emit('update:modelValue', value ?? '');
// empty string value will throw error being converted to BigNumber
emit('update:modelValue', value ?? '0');
};
onMounted(() => {
if (props.modelValue) {
input.value = formatUnits(props.modelValue, props.decimals);
}
});
watch(input, () => {
const value = format(input.value);
isValid.value = !!value && parseInt(value) > 0;
});
</script>

<template>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const nativeAsset = getNativeAsset(props.network);
const amount = ref(props.transaction.amount ?? '');
const recipient = ref(props.transaction.recipient ?? '');
const tokens = ref<Token[]>([nativeAsset, ...props.tokens]);
const selectedTokenAddress = ref<Token['address']>(
props.transaction?.token?.address ?? 'main'
);
Expand All @@ -42,8 +43,6 @@ const selectedTokenIsNative = computed(
const isTokenModalOpen = ref(false);
function updateTransaction() {
if (!isBigNumberish(amount.value) || !isAddress(recipient.value)) return;
try {
const data = selectedTokenIsNative.value
? '0x'
Expand All @@ -55,10 +54,10 @@ function updateTransaction() {
recipient: recipient.value,
token: selectedToken.value
});
emit('updateTransaction', transaction);
const isTransactionValid = validateTransaction(transaction);
if (isTransactionValid) {
emit('updateTransaction', transaction);
return;
if (!isTransactionValid) {
console.warn('invalid transaction');
}
} catch (error) {
console.warn('invalid transaction', error);
Expand Down
1 change: 1 addition & 0 deletions src/plugins/oSnap/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export type BaseTransaction = {
value: string;
data: string;
formatted: OptimisticGovernorTransaction;
isValid?: boolean;
};

/**
Expand Down
10 changes: 6 additions & 4 deletions src/plugins/oSnap/utils/validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ export const mustBeEthereumContractAddress = memoize(
* Validates a transaction.
*/
export function validateTransaction(transaction: BaseTransaction) {
const addressEmptyOrValidate =
transaction.to === '' || isAddress(transaction.to);
const addressNotEmptyOrInvalid =
transaction.to !== '' && isAddress(transaction.to);
const valueIsPositive =
isBigNumberish(transaction.value) && parseInt(transaction.value) > 0;
return (
isBigNumberish(transaction.value) &&
addressEmptyOrValidate &&
valueIsPositive &&
addressNotEmptyOrInvalid &&
(!transaction.data || isHexString(transaction.data))
);
}
Expand Down

0 comments on commit 70cf32a

Please sign in to comment.