Skip to content

Commit

Permalink
feat: track draft transaction changes, fix: transaction modal, fix: S…
Browse files Browse the repository at this point in the history
…aveDraftButton, fix: transaction specific changes (#1527)

Signed-off-by: Hristiyan <[email protected]>
  • Loading branch information
icoxxx authored Feb 11, 2025
1 parent 5926528 commit 9050df9
Show file tree
Hide file tree
Showing 7 changed files with 428 additions and 209 deletions.
97 changes: 0 additions & 97 deletions front-end/src/renderer/components/GroupActionModal.vue

This file was deleted.

123 changes: 20 additions & 103 deletions front-end/src/renderer/components/SaveDraftButton.vue
Original file line number Diff line number Diff line change
@@ -1,28 +1,21 @@
<script setup lang="ts">
import type { RouteLocationNormalized } from 'vue-router';
import type { Transaction } from '@hashgraph/sdk';
import { ref } from 'vue';
import { onBeforeRouteLeave } from 'vue-router';
import { FileAppendTransaction, FileUpdateTransaction } from '@hashgraph/sdk';
import useUserStore from '@renderer/stores/storeUser';
import { useToast } from 'vue-toast-notification';
import { useRoute, useRouter } from 'vue-router';
import {
addDraft,
draftExists,
getDraft,
updateDraft,
} from '@renderer/services/transactionDraftsService';
import { addDraft, getDraft, updateDraft } from '@renderer/services/transactionDraftsService';
import { getTransactionFromBytes, isUserLoggedIn } from '@renderer/utils';
import AppButton from '@renderer/components/ui/AppButton.vue';
import AppModal from '@renderer/components/ui/AppModal.vue';
import AppCustomIcon from '@renderer/components/ui/AppCustomIcon.vue';
const emit = defineEmits<{
(event: 'draft-saved'): void;
}>();
/* Props */
const props = defineProps<{
Expand All @@ -42,50 +35,41 @@ const toast = useToast();
const route = useRoute();
const router = useRouter();
/* State */
const routeTo = ref<RouteLocationNormalized | null>(null);
const isSaveDraftModalShown = ref(false);
/* Handlers */
const saveDraft = async () => {
const handleDraft = async () => {
if (!isUserLoggedIn(user.personal)) {
throw new Error('User is not logged in');
}
const transactionBytes = getTransactionBytes();
if (!transactionBytes) return;
if (route.query.draftId) {
try {
try {
if (route.query.draftId) {
const loadedDraft = await getDraft(route.query.draftId.toString());
if (getTransactionFromBytes(loadedDraft.transactionBytes).toBytes() != transactionBytes) {
if (getTransactionFromBytes(loadedDraft.transactionBytes).toBytes() !== transactionBytes) {
await updateDraft(loadedDraft.id, {
transactionBytes: transactionBytes.toString(),
description: props.description,
});
emit('draft-saved');
toast.success('Draft updated');
props.handleDraftUpdated && props.handleDraftUpdated(loadedDraft.id);
} else {
await sendAddDraft(user.personal.id, transactionBytes);
router.push('/transactions?tab=Drafts');
}
} catch (error) {
console.log(error);
} else {
await sendAddDraft(user.personal.id, transactionBytes);
emit('draft-saved');
}
} else {
await sendAddDraft(user.personal.id, transactionBytes);
} catch (error) {
console.log(error);
}
};
const handleModalSaveDraftSubmit = () => {
props.handleSaveDraft ? props.handleSaveDraft() : saveDraft();
routeTo.value && router.push(routeTo.value);
};
/* Functions */
async function sendAddDraft(userId: string, transactionBytes: Uint8Array) {
const { id } = await addDraft(userId, transactionBytes, props.description);
props.handleDraftAdded && props.handleDraftAdded(id);
router.push('/transactions?tab=Drafts');
toast.success('Draft saved');
}
Expand All @@ -101,84 +85,17 @@ function getTransactionBytes() {
}
return transaction.toBytes();
}
/* Hooks */
onBeforeRouteLeave(async to => {
if (to.name?.toString().toLocaleLowerCase().includes('login')) return true;
const transactionBytes = getTransactionBytes();
if (!transactionBytes) return true;
if (route.query.draftId) {
try {
const loadedDraft = await getDraft(route.query.draftId.toString());
if (getTransactionFromBytes(loadedDraft.transactionBytes).toBytes() != transactionBytes) {
await updateDraft(loadedDraft.id, {
transactionBytes: transactionBytes.toString(),
description: props.description,
});
props.handleDraftUpdated && props.handleDraftUpdated(loadedDraft.id);
}
} catch (error) {
console.log(error);
}
return true;
}
if (!(await draftExists(transactionBytes)) && !isSaveDraftModalShown.value && !props.isExecuted) {
isSaveDraftModalShown.value = true;
routeTo.value = to;
return false;
} else {
return true;
}
});
</script>
<template>
<div>
<AppButton
color="secondary"
type="button"
data-testid="button-save-draft"
@click="() => (handleSaveDraft ? handleSaveDraft() : saveDraft())"
@click="() => (handleSaveDraft ? handleSaveDraft() : handleDraft())"
v-bind="$attrs"
><i class="bi bi-save"></i> Save Draft</AppButton
><i class="bi bi-save"></i>
{{ Boolean(route.query.draftId) ? 'Update Draft' : 'Save Draft' }}</AppButton
>
<AppModal
:show="isSaveDraftModalShown"
:close-on-click-outside="false"
:close-on-escape="false"
class="small-modal"
>
<form class="text-center p-4" @submit.prevent="handleModalSaveDraftSubmit">
<div class="text-start">
<i class="bi bi-x-lg cursor-pointer" @click="isSaveDraftModalShown = false"></i>
</div>
<div>
<AppCustomIcon :name="'lock'" style="height: 160px" />
</div>
<h2 class="text-title text-semi-bold mt-3">Save draft?</h2>
<p class="text-small text-secondary mt-3">
Pick up exactly where you left off, without compromising your flow or losing valuable
time.
</p>

<hr class="separator my-5" />

<div class="flex-between-centered gap-4">
<AppButton
color="borderless"
data-testid="button-discard-draft-modal"
type="button"
@click="routeTo && $router.push(routeTo)"
>Discard</AppButton
>
<AppButton color="primary" data-testid="button-save-draft-modal" type="submit"
>Save</AppButton
>
</div>
</form>
</AppModal>
</div>
</template>
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
<script setup lang="ts">
import { onMounted } from 'vue';
import type { Transaction } from '@hashgraph/sdk';
import {
FileAppendTransaction,
FileCreateTransaction,
FileUpdateTransaction,
type Transaction,
} from '@hashgraph/sdk';
import useTransactionGroupStore from '@renderer/stores/storeTransactionGroup';
Expand Down Expand Up @@ -42,6 +47,14 @@ const handleLoadFromDraft = async () => {
if (transactionBytes) {
const transaction = getTransactionFromBytes(transactionBytes);
if (
transaction instanceof FileCreateTransaction ||
transaction instanceof FileUpdateTransaction ||
(transaction instanceof FileAppendTransaction && transaction.contents?.length === 0)
) {
//@ts-expect-error - contents should be null
transaction.setContents(null);
}
emit('draft-loaded', transaction);
}
};
Expand Down
Loading

0 comments on commit 9050df9

Please sign in to comment.