chore: update properties UI flow

This commit is contained in:
nivedin
2023-11-28 22:34:10 +05:30
committed by Andrew Bastin
parent f8aeb42da5
commit ae531f5882
5 changed files with 235 additions and 23 deletions

View File

@@ -161,7 +161,6 @@
" "
/> />
<HoppSmartItem <HoppSmartItem
v-if="folderType === 'collection'"
ref="propertiesAction" ref="propertiesAction"
:icon="IconSettings2" :icon="IconSettings2"
:label="t('action.properties')" :label="t('action.properties')"

View File

@@ -146,6 +146,13 @@
folder: node.data.data.data, folder: node.data.data.data,
}) })
" "
@edit-properties="
node.data.type === 'folders' &&
emit('edit-properties', {
collectionIndex: node.id,
collection: node.data.data.data,
})
"
@export-data=" @export-data="
node.data.type === 'folders' && node.data.type === 'folders' &&
emit('export-data', node.data.data.data) emit('export-data', node.data.data.data)

View File

@@ -40,6 +40,8 @@
<HttpAuthorization <HttpAuthorization
v-model="editableCollection.auth" v-model="editableCollection.auth"
:is-collection-property="true" :is-collection-property="true"
:is-root-collection="editingProperties.isRootCollection"
:inherited-properties="editingProperties.inheritedProperties"
/> />
<AppBanner <AppBanner
:banner="{ :banner="{
@@ -80,37 +82,46 @@
import { watch, ref } from "vue" import { watch, ref } from "vue"
import { useI18n } from "@composables/i18n" import { useI18n } from "@composables/i18n"
import { HoppCollection, HoppRESTRequest } from "@hoppscotch/data" import { HoppCollection, HoppRESTRequest } from "@hoppscotch/data"
import { TeamCollection } from "~/helpers/backend/graphql"
import { RESTOptionTabs } from "../http/RequestOptions.vue" import { RESTOptionTabs } from "../http/RequestOptions.vue"
import { TeamCollection } from "~/helpers/teams/TeamCollection"
import { clone } from "lodash-es"
import { HoppInheritedProperty } from "~/helpers/types/HoppInheritedProperties"
const t = useI18n() const t = useI18n()
type EditingProperties = {
collection: HoppCollection<HoppRESTRequest> | TeamCollection | null
isRootCollection: boolean
path: string
inheritedProperties: HoppInheritedProperty | null
}
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{
show: boolean show: boolean
loadingState: boolean loadingState: boolean
collection: HoppCollection<HoppRESTRequest> | TeamCollection editingProperties: EditingProperties | null
}>(), }>(),
{ {
show: false, show: false,
loadingState: false, loadingState: false,
editingProperties: null,
} }
) )
const emit = defineEmits<{ const emit = defineEmits<{
(e: "submit", name: string): void (e: "set-collection-properties", newCollection: any): void
(e: "hide-modal"): void (e: "hide-modal"): void
}>() }>()
const editableCollection = ref({ const editableCollection = ref({
...props.collection,
body: { body: {
contentType: null, contentType: null,
body: null, body: null,
}, },
headers: [], headers: [],
auth: { auth: {
authType: "none", authType: "inherit",
authActive: false, authActive: false,
}, },
}) as any }) as any
@@ -124,23 +135,44 @@ const changeOptionTab = (tab: RESTOptionTabs) => {
watch( watch(
() => props.show, () => props.show,
(show) => { (show) => {
if (!show) { if (show && props.editingProperties?.collection) {
editableCollection.value.auth = clone(
props.editingProperties.collection.auth
)
editableCollection.value.headers = clone(
props.editingProperties.collection.headers
)
} else {
editableCollection.value = {
body: {
contentType: null,
body: null,
},
headers: [],
auth: {
authType: "inherit",
authActive: false,
},
}
} }
} }
) )
const saveEditedCollection = () => { const saveEditedCollection = () => {
console.log("new-coll", editableCollection.value) if (!props.editingProperties) return
const finalCollection = clone(editableCollection.value)
delete finalCollection.body
const collection = {
path: props.editingProperties.path,
collection: {
...props.editingProperties.collection,
...finalCollection,
},
isRootCollection: props.editingProperties.isRootCollection,
}
emit("set-collection-properties", collection)
} }
// const addNewCollection = () => {
// if (!editingName.value) {
// toast.error(t("collection.invalid_name"))
// return
// }
// }
const hideModal = () => { const hideModal = () => {
emit("hide-modal") emit("hide-modal")
} }

View File

@@ -166,6 +166,13 @@
folder: node.data.data.data, folder: node.data.data.data,
}) })
" "
@edit-properties="
node.data.type === 'folders' &&
emit('edit-properties', {
collectionIndex: node.id,
collection: node.data.data.data,
})
"
@export-data=" @export-data="
node.data.type === 'folders' && node.data.type === 'folders' &&
emit('export-data', node.data.data.data) emit('export-data', node.data.data.data)

View File

@@ -155,7 +155,9 @@
/> />
<CollectionsProperties <CollectionsProperties
:show="showModalEditProperties" :show="showModalEditProperties"
:editing-properties="editingProperties"
@hide-modal="displayModalEditProperties(false)" @hide-modal="displayModalEditProperties(false)"
@set-collection-properties="setCollectionProperties"
/> />
</div> </div>
</template> </template>
@@ -226,6 +228,7 @@ import {
getFoldersByPath, getFoldersByPath,
resolveSaveContextOnCollectionReorder, resolveSaveContextOnCollectionReorder,
updateSaveContextForAffectedRequests, updateSaveContextForAffectedRequests,
updateInheritedPropertiesForAffectedRequests,
resetTeamRequestsContext, resetTeamRequestsContext,
} from "~/helpers/collection/collection" } from "~/helpers/collection/collection"
import { currentReorderingStatus$ } from "~/newstore/reordering" import { currentReorderingStatus$ } from "~/newstore/reordering"
@@ -233,6 +236,7 @@ import { defineActionHandler, invokeAction } from "~/helpers/actions"
import { WorkspaceService } from "~/services/workspace.service" import { WorkspaceService } from "~/services/workspace.service"
import { useService } from "dioc/vue" import { useService } from "dioc/vue"
import { RESTTabService } from "~/services/tab/rest" import { RESTTabService } from "~/services/tab/rest"
import { HoppInheritedProperty } from "~/helpers/types/HoppInheritedProperties"
const t = useI18n() const t = useI18n()
const toast = useToast() const toast = useToast()
@@ -288,6 +292,17 @@ const editingRequestName = ref("")
const editingRequestIndex = ref<number | null>(null) const editingRequestIndex = ref<number | null>(null)
const editingRequestID = ref<string | null>(null) const editingRequestID = ref<string | null>(null)
const editingProperties = ref<{
collection: HoppCollection<HoppRESTRequest> | TeamCollection | null
isRootCollection: boolean
path: string
inheritedProperties?: HoppInheritedProperty
}>({
collection: null,
isRootCollection: false,
path: "",
})
const confirmModalTitle = ref<string | null>(null) const confirmModalTitle = ref<string | null>(null)
const filterTexts = ref("") const filterTexts = ref("")
@@ -597,6 +612,11 @@ const addNewRootCollection = (name: string) => {
name, name,
folders: [], folders: [],
requests: [], requests: [],
headers: [],
auth: {
authType: "inherit",
authActive: false,
},
}) })
) )
@@ -657,6 +677,8 @@ const onAddRequest = (requestName: string) => {
if (!path) return if (!path) return
const insertionIndex = saveRESTRequestAs(path, newRequest) const insertionIndex = saveRESTRequestAs(path, newRequest)
const { auth, headers, name } = cascaseParentCollectionForHeaderAuth(path)
tabs.createNewTab({ tabs.createNewTab({
request: newRequest, request: newRequest,
isDirty: false, isDirty: false,
@@ -665,6 +687,12 @@ const onAddRequest = (requestName: string) => {
folderPath: path, folderPath: path,
requestIndex: insertionIndex, requestIndex: insertionIndex,
}, },
inheritedProperties: {
auth,
headers,
parentName: name,
parentId: path,
},
}) })
platform.analytics?.logEvent({ platform.analytics?.logEvent({
@@ -1286,6 +1314,63 @@ const selectPicked = (payload: Picked | null) => {
emit("select", payload) emit("select", payload)
} }
const cascaseParentCollectionForHeaderAuth = (
folderPath: string | undefined
) => {
let auth: HoppRESTRequest["auth"] = {
authType: "none",
authActive: false,
}
const headers: HoppRESTRequest["headers"] = []
let name = ""
if (!folderPath) return { auth, headers, name: "" }
const path = folderPath.split("/").map((i) => parseInt(i))
// Check if the path is empty or invalid
if (!path || path.length === 0) {
console.error("Invalid path:", folderPath)
return { auth, headers, name: "" }
}
// Loop through the path and get the last parent folder with authType other than 'inherit'
for (let i = 0; i < path.length; i++) {
const parentFolder = navigateToFolderWithIndexPath(
restCollectionStore.value.state,
[...path.slice(0, i + 1)] // Create a copy of the path array
)
// Check if parentFolder is undefined or null
if (!parentFolder) {
console.error("Parent folder not found for path:", path)
return { auth, headers, name: "" }
}
const parentFolderAuth = parentFolder.auth
const parentFolderHeaders = parentFolder.headers
// Check if authType is not 'inherit'
if (parentFolderAuth?.authType !== "inherit") {
auth = parentFolderAuth || auth
name = parentFolder.name
}
// Update headers, overwriting duplicates by key
if (parentFolderHeaders) {
const activeHeaders = parentFolderHeaders.filter((h) => h.active)
activeHeaders.forEach((header) => {
const index = headers.findIndex((h) => h.key === header.key)
if (index !== -1) {
// Replace the existing header with the same key
headers[index] = header
} else {
headers.push(header)
}
})
}
}
return { auth, headers, name }
}
/** /**
* This function is called when the user clicks on a request * This function is called when the user clicks on a request
* @param selectedRequest The request that the user clicked on emited from the collection tree * @param selectedRequest The request that the user clicked on emited from the collection tree
@@ -1301,6 +1386,9 @@ const selectRequest = (selectedRequest: {
// If there is a request with this save context, switch into it // If there is a request with this save context, switch into it
let possibleTab = null let possibleTab = null
const { auth, headers, name } =
cascaseParentCollectionForHeaderAuth(folderPath)
if (collectionsType.value.type === "team-collections") { if (collectionsType.value.type === "team-collections") {
possibleTab = tabs.getTabRefWithSaveContext({ possibleTab = tabs.getTabRefWithSaveContext({
originLocation: "team-collection", originLocation: "team-collection",
@@ -1336,6 +1424,12 @@ const selectRequest = (selectedRequest: {
folderPath: folderPath!, folderPath: folderPath!,
requestIndex: parseInt(requestIndex), requestIndex: parseInt(requestIndex),
}, },
inheritedProperties: {
parentId: folderPath || "",
parentName: name,
auth: auth,
headers,
},
}) })
} }
} }
@@ -1364,14 +1458,14 @@ const dropRequest = (payload: {
if (!requestIndex || !destinationCollectionIndex) return if (!requestIndex || !destinationCollectionIndex) return
let possibleTab = null
if (collectionsType.value.type === "my-collections" && folderPath) { if (collectionsType.value.type === "my-collections" && folderPath) {
moveRESTRequest( const { auth, headers, name } = cascaseParentCollectionForHeaderAuth(
folderPath,
pathToLastIndex(requestIndex),
destinationCollectionIndex destinationCollectionIndex
) )
const possibleTab = tabs.getTabRefWithSaveContext({ possibleTab = tabs.getTabRefWithSaveContext({
originLocation: "user-collection", originLocation: "user-collection",
folderPath, folderPath,
requestIndex: pathToLastIndex(requestIndex), requestIndex: pathToLastIndex(requestIndex),
@@ -1387,6 +1481,13 @@ const dropRequest = (payload: {
destinationCollectionIndex destinationCollectionIndex
).length, ).length,
} }
possibleTab.value.document.inheritedProperties = {
parentId: destinationCollectionIndex,
parentName: name,
auth,
headers,
}
} }
// When it's drop it's basically getting deleted from last folder. reordering last folder accordingly // When it's drop it's basically getting deleted from last folder. reordering last folder accordingly
@@ -1396,6 +1497,11 @@ const dropRequest = (payload: {
folderPath, folderPath,
length: getRequestsByPath(myCollections.value, folderPath).length, length: getRequestsByPath(myCollections.value, folderPath).length,
}) })
moveRESTRequest(
folderPath,
pathToLastIndex(requestIndex),
destinationCollectionIndex
)
toast.success(`${t("request.moved")}`) toast.success(`${t("request.moved")}`)
draggingToRoot.value = false draggingToRoot.value = false
@@ -1420,7 +1526,7 @@ const dropRequest = (payload: {
1 1
) )
const possibleTab = tabs.getTabRefWithSaveContext({ possibleTab = tabs.getTabRefWithSaveContext({
originLocation: "team-collection", originLocation: "team-collection",
requestID: requestIndex, requestID: requestIndex,
}) })
@@ -1550,6 +1656,22 @@ const dropCollection = (payload: {
`${destinationCollectionIndex}/${totalFoldersOfDestinationCollection}` `${destinationCollectionIndex}/${totalFoldersOfDestinationCollection}`
) )
const { auth, headers, name } = cascaseParentCollectionForHeaderAuth(
`${destinationCollectionIndex}/${totalFoldersOfDestinationCollection}`
)
const inheritedProperty = {
parentId: `${destinationCollectionIndex}/${totalFoldersOfDestinationCollection}`,
parentName: name,
auth,
headers,
}
updateInheritedPropertiesForAffectedRequests(
`${destinationCollectionIndex}/${totalFoldersOfDestinationCollection}`,
inheritedProperty
)
draggingToRoot.value = false draggingToRoot.value = false
toast.success(`${t("collection.moved")}`) toast.success(`${t("collection.moved")}`)
} else if (hasTeamWriteAccess.value) { } else if (hasTeamWriteAccess.value) {
@@ -1912,13 +2034,58 @@ const editProperties = (payload: {
}) => { }) => {
const { collection, collectionIndex } = payload const { collection, collectionIndex } = payload
console.log(collectionIndex, collection) const parentIndex = collectionIndex.split("/").slice(0, -1).join("/") // remove last folder to get parent folder
editingCollection.value = collection let inheritedProperties = {}
if (parentIndex) {
const { auth, headers, name } =
cascaseParentCollectionForHeaderAuth(parentIndex)
inheritedProperties = {
parentId: parentIndex ?? "",
parentName: name,
auth,
headers,
} as HoppInheritedProperty
}
editingProperties.value = {
collection,
isRootCollection: isAlreadyInRoot(collectionIndex),
path: collectionIndex,
inheritedProperties,
}
displayModalEditProperties(true) displayModalEditProperties(true)
} }
const setCollectionProperties = (newCollection: {
collection: HoppCollection<HoppRESTRequest>
path: string
isRootCollection: boolean
}) => {
const { collection, path, isRootCollection } = newCollection
if (isRootCollection) {
editRESTCollection(parseInt(path), collection)
} else {
editRESTFolder(path, collection)
}
const { auth, headers, name } = cascaseParentCollectionForHeaderAuth(path)
nextTick(() => {
updateInheritedPropertiesForAffectedRequests(path, {
parentId: path,
parentName: name,
auth,
headers,
})
})
displayModalEditProperties(false)
}
const resolveConfirmModal = (title: string | null) => { const resolveConfirmModal = (title: string | null) => {
if (title === `${t("confirm.remove_collection")}`) onRemoveCollection() if (title === `${t("confirm.remove_collection")}`) onRemoveCollection()
else if (title === `${t("confirm.remove_request")}`) onRemoveRequest() else if (title === `${t("confirm.remove_request")}`) onRemoveRequest()