Skip to content

Commit 240ea4c

Browse files
committed
feat:Initialized CustomToast component
1 parent e5ec12f commit 240ea4c

File tree

5 files changed

+115
-17
lines changed

5 files changed

+115
-17
lines changed

src/App.vue

+10-8
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
<template>
22
<RouterView />
3-
<VToasts/>
3+
<VToasts />
4+
<CustomToast />
45
</template>
56

67
<script>
7-
// Components
8-
import VToasts from '@/components/VToasts.vue';
8+
// Components
9+
import VToasts from '@/components/VToasts.vue';
10+
import CustomToast from './components/comments/CustomToast.vue';
911
10-
export default {
11-
name: 'App',
12+
export default {
13+
name: 'App',
1214
13-
components: { VToasts }
14-
};
15-
</script>
15+
components: { VToasts, CustomToast }
16+
};
17+
</script>

src/components/VToasts.vue

-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
3030
export default {
3131
name: 'VToasts',
32-
3332
setup() {
3433
let items = installToast();
3534
+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<template>
2+
<div class="toast-container bottom-0 end-0">
3+
<div v-for="item of items" :key="item.id"
4+
:class="`toast show align-items-center border-1 m-2 fw-medium text-bg-${item.theme}`" role="alert"
5+
aria-live="assertive" aria-atomic="true">
6+
<div class="toast-header" v-html="item.title" v-if="!!item.title"></div>
7+
<div class="d-flex justify-content-between align-items-center">
8+
<div class="toast-body">
9+
<button @click="handleCallbackCall(item.id,item.callback)" class="btn btn-secondary">
10+
Undo
11+
</button>
12+
</div>
13+
<button v-if="item.clearable" type="button" class="btn-close p-3" aria-label="Close"
14+
@click="hideToast(item.id)"></button>
15+
</div>
16+
</div>
17+
</div>
18+
</template>
19+
20+
<script>
21+
import { installCustomToast, useCustomToast } from '@/composables/customToast.composable';
22+
23+
export default {
24+
name: 'CustomToast',
25+
setup() {
26+
let items = installCustomToast();
27+
28+
const { hideToast } = useCustomToast();
29+
const handleCallbackCall = (id,callback) => {
30+
callback?.()
31+
hideToast(id)
32+
}
33+
34+
return {
35+
items,
36+
hideToast,
37+
handleCallbackCall
38+
};
39+
},
40+
}
41+
</script>
+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { ref, getCurrentInstance } from 'vue';
2+
3+
// Utils
4+
import { getUniqueId } from '@/utils';
5+
6+
const items = ref([]);
7+
8+
export function installCustomToast() {
9+
const instance = getCurrentInstance();
10+
if (instance.type.name !== 'CustomToast') {
11+
throw new Error('installToast should only be called in the Custom toast component');
12+
}
13+
14+
return items;
15+
}
16+
17+
export function useCustomToast() {
18+
function showToast({ theme, duration = 5000, clearable = true , title, callback}) {
19+
const id = getUniqueId();
20+
21+
const _timeOutId = setTimeout(function () {
22+
hideToast(id);
23+
}, duration);
24+
25+
items.value.push({
26+
id,
27+
duration,
28+
theme,
29+
clearable,
30+
title,
31+
callback,
32+
_time_out_id: _timeOutId
33+
});
34+
35+
return id;
36+
}
37+
38+
function hideToast(id) {
39+
const index = items.value.findIndex(function (item) {
40+
return item.id === id;
41+
});
42+
43+
clearTimeout(items.value[index]._time_out_id);
44+
45+
items.value.splice(index, 1);
46+
}
47+
48+
return {
49+
showToast,
50+
hideToast
51+
};
52+
}

src/views/CommentsView.vue

+12-8
Original file line numberDiff line numberDiff line change
@@ -109,16 +109,15 @@ import VModal from "@/components/VModal.vue";
109109
import { useFetchComments } from "@/composables/comments.composable";
110110
import { useApplyFilters } from "@/composables/filter.composable";
111111
import useFetchPost from "@/composables/posts.composable";
112-
import { useToast } from "@/composables/toast.composable";
112+
import { useCustomToast } from "@/composables/customToast.composable";
113113
import ThemeColor from "@/enums/ThemeColor";
114114
import StorageService from "@/services/storage.service";
115115
import { computed, reactive, ref, watch } from "vue";
116116
117117
export default {
118118
name: "CommentsView",
119119
setup() {
120-
const { showToast } = useToast();
121-
120+
const { showToast } = useCustomToast();
122121
const { comments, commentsIsLoading, fetchComments, changeStatus: changeCommentStatus } = useFetchComments();
123122
fetchComments({});
124123
@@ -194,22 +193,27 @@ export default {
194193
const regex = new RegExp(`(${query})`, "gi");
195194
return String(text).replace(regex, "<mark>$1</mark>");
196195
};
196+
const handleUndoRejection = () => {
197+
console.log("Undo rejection callback executed");
198+
};
199+
197200
const handleConfirmRejection = () => {
198-
changeCommentStatus(rejectComment.comment.id, "REJECTED");
199-
showToast({ body: "Undo", theme: ThemeColor.WARNING, duration: 3000 });
200-
rejectComment.comment = null;
201+
showToast({
202+
theme: ThemeColor.WARNING,
203+
duration: 3000,
204+
callback: handleUndoRejection,
205+
});
201206
rejectComment.modalIsOpen = false;
207+
rejectComment.comment = null;
202208
};
203209
204210
const selectedRows = ref([]);
205-
206211
const handleStatusChangeAll = (status) => {
207212
selectedRows.value.forEach((commentId) => {
208213
changeCommentStatus(commentId, status);
209214
selectedRows.value = [];
210215
});
211216
};
212-
213217
return {
214218
comments: filteredComments,
215219
commentsIsLoading,

0 commit comments

Comments
 (0)