feat: unsaved change popup (#2239)

Co-authored-by: Andrew Bastin <andrewbastin.k@gmail.com>
Co-authored-by: liyasthomas <liyascthomas@gmail.com>
This commit is contained in:
Nivedin
2022-04-13 20:52:44 +05:30
committed by liyasthomas
parent 9232aad184
commit 99148a0a0e
7 changed files with 771 additions and 242 deletions

View File

@@ -97,16 +97,29 @@
@hide-modal="confirmRemove = false"
@resolve="clearHistory"
/>
<HttpReqChangeConfirmModal
:show="confirmChange"
@hide-modal="confirmChange = false"
@save-change="saveRequestChange"
@discard-change="discardRequestChange"
/>
<CollectionsSaveRequest
mode="rest"
:show="showSaveRequestModal"
@hide-modal="showSaveRequestModal = false"
/>
</div>
</template>
<script setup lang="ts">
import { computed, ref, Ref } from "@nuxtjs/composition-api"
import { safelyExtractRESTRequest } from "@hoppscotch/data"
import { HoppRESTRequest, safelyExtractRESTRequest } from "@hoppscotch/data"
import groupBy from "lodash/groupBy"
import { useTimeAgo } from "@vueuse/core"
import { pipe } from "fp-ts/function"
import * as A from "fp-ts/Array"
import * as E from "fp-ts/Either"
import isEqual from "lodash/isEqual"
import {
useI18n,
useReadonlyStream,
@@ -124,17 +137,17 @@ import {
RESTHistoryEntry,
GQLHistoryEntry,
} from "~/newstore/history"
import { getDefaultRESTRequest, setRESTRequest } from "~/newstore/RESTSession"
const props = defineProps<{
page: "rest" | "graphql"
}>()
const filterText = ref("")
const showMore = ref(false)
const confirmRemove = ref(false)
const toast = useToast()
const t = useI18n()
import {
getDefaultRESTRequest,
getRESTRequest,
getRESTSaveContext,
setRESTRequest,
setRESTSaveContext,
} from "~/newstore/RESTSession"
import { editRESTRequest } from "~/newstore/collections"
import { runMutation } from "~/helpers/backend/GQLClient"
import { UpdateRequestDocument } from "~/helpers/backend/graphql"
import { HoppRequestSaveContext } from "~/helpers/types/HoppRequestSaveContext"
type HistoryEntry = GQLHistoryEntry | RESTHistoryEntry
@@ -143,6 +156,21 @@ type TimedHistoryEntry = {
timeAgo: Ref<string>
}
const props = defineProps<{
page: "rest" | "graphql"
}>()
const toast = useToast()
const t = useI18n()
const filterText = ref("")
const showMore = ref(false)
const confirmRemove = ref(false)
const clickedHistory = ref<HistoryEntry | null>(null)
const confirmChange = ref(false)
const showSaveRequestModal = ref(false)
const history = useReadonlyStream<RESTHistoryEntry[] | GQLHistoryEntry[]>(
props.page === "rest" ? restHistory$ : graphqlHistory$,
[]
@@ -199,11 +227,93 @@ const clearHistory = () => {
toast.success(`${t("state.history_deleted")}`)
}
const useHistory = (entry: any) => {
if (props.page === "rest")
setRESTRequest(
safelyExtractRESTRequest(entry.request, getDefaultRESTRequest())
)
const setRestReq = (request: HoppRESTRequest | null | undefined) => {
setRESTRequest(safelyExtractRESTRequest(request, getDefaultRESTRequest()))
}
const useHistory = (entry: HistoryEntry) => {
const currentFullReq = getRESTRequest()
// Initial state trigers a popup
if (!clickedHistory.value) {
clickedHistory.value = entry
confirmChange.value = true
return
}
// Checks if there are any change done in current request and the history request
if (!isEqual(currentFullReq, clickedHistory.value.request)) {
clickedHistory.value = entry
confirmChange.value = true
} else {
props.page === "rest" && setRestReq(entry.request as HoppRESTRequest)
clickedHistory.value = entry
}
}
/** Save current request to the collection */
const saveRequestChange = () => {
const saveCtx = getRESTSaveContext()
saveCurrentRequest(saveCtx)
confirmChange.value = false
}
/** Discard changes and change the current request and remove the collection context */
const discardRequestChange = () => {
const saveCtx = getRESTSaveContext()
if (saveCtx) {
setRESTSaveContext(null)
}
clickedHistory.value &&
setRestReq(clickedHistory.value.request as HoppRESTRequest)
confirmChange.value = false
}
const saveCurrentRequest = (saveCtx: HoppRequestSaveContext | null) => {
if (!saveCtx) {
showSaveRequestModal.value = true
return
}
if (saveCtx.originLocation === "user-collection") {
try {
editRESTRequest(
saveCtx.folderPath,
saveCtx.requestIndex,
getRESTRequest()
)
clickedHistory.value &&
setRestReq(clickedHistory.value.request as HoppRESTRequest)
setRESTSaveContext(null)
toast.success(`${t("request.saved")}`)
} catch (e) {
console.error(e)
setRESTSaveContext(null)
saveCurrentRequest(null)
}
} else if (saveCtx.originLocation === "team-collection") {
const req = getRESTRequest()
try {
runMutation(UpdateRequestDocument, {
requestID: saveCtx.requestID,
data: {
title: req.name,
request: JSON.stringify(req),
},
})().then((result) => {
if (E.isLeft(result)) {
toast.error(`${t("profile.no_permission")}`)
} else {
toast.success(`${t("request.saved")}`)
}
})
clickedHistory.value &&
setRestReq(clickedHistory.value.request as HoppRESTRequest)
setRESTSaveContext(null)
} catch (error) {
showSaveRequestModal.value = true
toast.error(`${t("error.something_went_wrong")}`)
console.error(error)
setRESTSaveContext(null)
}
}
}
const isRESTHistoryEntry = (
@@ -225,14 +335,16 @@ const deleteBatchHistoryEntry = (entries: TimedHistoryEntry[]) => {
toast.success(`${t("state.deleted")}`)
}
const deleteHistory = (entry: any) => {
if (props.page === "rest") deleteRESTHistoryEntry(entry)
else deleteGraphqlHistoryEntry(entry)
const deleteHistory = (entry: HistoryEntry) => {
if (props.page === "rest") deleteRESTHistoryEntry(entry as RESTHistoryEntry)
else deleteGraphqlHistoryEntry(entry as GQLHistoryEntry)
toast.success(`${t("state.deleted")}`)
}
const toggleStar = (entry: any) => {
if (props.page === "rest") toggleRESTHistoryEntryStar(entry)
else toggleGraphqlHistoryEntryStar(entry)
const toggleStar = (entry: HistoryEntry) => {
//History entry type specified because function does not know the type
if (props.page === "rest")
toggleRESTHistoryEntryStar(entry as RESTHistoryEntry)
else toggleGraphqlHistoryEntryStar(entry as GQLHistoryEntry)
}
</script>