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
v-if="folderType === 'collection'"
ref="propertiesAction"
:icon="IconSettings2"
:label="t('action.properties')"

View File

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

View File

@@ -40,6 +40,8 @@
<HttpAuthorization
v-model="editableCollection.auth"
:is-collection-property="true"
:is-root-collection="editingProperties.isRootCollection"
:inherited-properties="editingProperties.inheritedProperties"
/>
<AppBanner
:banner="{
@@ -80,37 +82,46 @@
import { watch, ref } from "vue"
import { useI18n } from "@composables/i18n"
import { HoppCollection, HoppRESTRequest } from "@hoppscotch/data"
import { TeamCollection } from "~/helpers/backend/graphql"
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()
type EditingProperties = {
collection: HoppCollection<HoppRESTRequest> | TeamCollection | null
isRootCollection: boolean
path: string
inheritedProperties: HoppInheritedProperty | null
}
const props = withDefaults(
defineProps<{
show: boolean
loadingState: boolean
collection: HoppCollection<HoppRESTRequest> | TeamCollection
editingProperties: EditingProperties | null
}>(),
{
show: false,
loadingState: false,
editingProperties: null,
}
)
const emit = defineEmits<{
(e: "submit", name: string): void
(e: "set-collection-properties", newCollection: any): void
(e: "hide-modal"): void
}>()
const editableCollection = ref({
...props.collection,
body: {
contentType: null,
body: null,
},
headers: [],
auth: {
authType: "none",
authType: "inherit",
authActive: false,
},
}) as any
@@ -124,23 +135,44 @@ const changeOptionTab = (tab: RESTOptionTabs) => {
watch(
() => props.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 = () => {
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 = () => {
emit("hide-modal")
}

View File

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

View File

@@ -155,7 +155,9 @@
/>
<CollectionsProperties
:show="showModalEditProperties"
:editing-properties="editingProperties"
@hide-modal="displayModalEditProperties(false)"
@set-collection-properties="setCollectionProperties"
/>
</div>
</template>
@@ -226,6 +228,7 @@ import {
getFoldersByPath,
resolveSaveContextOnCollectionReorder,
updateSaveContextForAffectedRequests,
updateInheritedPropertiesForAffectedRequests,
resetTeamRequestsContext,
} from "~/helpers/collection/collection"
import { currentReorderingStatus$ } from "~/newstore/reordering"
@@ -233,6 +236,7 @@ import { defineActionHandler, invokeAction } from "~/helpers/actions"
import { WorkspaceService } from "~/services/workspace.service"
import { useService } from "dioc/vue"
import { RESTTabService } from "~/services/tab/rest"
import { HoppInheritedProperty } from "~/helpers/types/HoppInheritedProperties"
const t = useI18n()
const toast = useToast()
@@ -288,6 +292,17 @@ const editingRequestName = ref("")
const editingRequestIndex = ref<number | 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 filterTexts = ref("")
@@ -597,6 +612,11 @@ const addNewRootCollection = (name: string) => {
name,
folders: [],
requests: [],
headers: [],
auth: {
authType: "inherit",
authActive: false,
},
})
)
@@ -657,6 +677,8 @@ const onAddRequest = (requestName: string) => {
if (!path) return
const insertionIndex = saveRESTRequestAs(path, newRequest)
const { auth, headers, name } = cascaseParentCollectionForHeaderAuth(path)
tabs.createNewTab({
request: newRequest,
isDirty: false,
@@ -665,6 +687,12 @@ const onAddRequest = (requestName: string) => {
folderPath: path,
requestIndex: insertionIndex,
},
inheritedProperties: {
auth,
headers,
parentName: name,
parentId: path,
},
})
platform.analytics?.logEvent({
@@ -1286,6 +1314,63 @@ const selectPicked = (payload: Picked | null) => {
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
* @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
let possibleTab = null
const { auth, headers, name } =
cascaseParentCollectionForHeaderAuth(folderPath)
if (collectionsType.value.type === "team-collections") {
possibleTab = tabs.getTabRefWithSaveContext({
originLocation: "team-collection",
@@ -1336,6 +1424,12 @@ const selectRequest = (selectedRequest: {
folderPath: folderPath!,
requestIndex: parseInt(requestIndex),
},
inheritedProperties: {
parentId: folderPath || "",
parentName: name,
auth: auth,
headers,
},
})
}
}
@@ -1364,14 +1458,14 @@ const dropRequest = (payload: {
if (!requestIndex || !destinationCollectionIndex) return
let possibleTab = null
if (collectionsType.value.type === "my-collections" && folderPath) {
moveRESTRequest(
folderPath,
pathToLastIndex(requestIndex),
const { auth, headers, name } = cascaseParentCollectionForHeaderAuth(
destinationCollectionIndex
)
const possibleTab = tabs.getTabRefWithSaveContext({
possibleTab = tabs.getTabRefWithSaveContext({
originLocation: "user-collection",
folderPath,
requestIndex: pathToLastIndex(requestIndex),
@@ -1387,6 +1481,13 @@ const dropRequest = (payload: {
destinationCollectionIndex
).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
@@ -1396,6 +1497,11 @@ const dropRequest = (payload: {
folderPath,
length: getRequestsByPath(myCollections.value, folderPath).length,
})
moveRESTRequest(
folderPath,
pathToLastIndex(requestIndex),
destinationCollectionIndex
)
toast.success(`${t("request.moved")}`)
draggingToRoot.value = false
@@ -1420,7 +1526,7 @@ const dropRequest = (payload: {
1
)
const possibleTab = tabs.getTabRefWithSaveContext({
possibleTab = tabs.getTabRefWithSaveContext({
originLocation: "team-collection",
requestID: requestIndex,
})
@@ -1550,6 +1656,22 @@ const dropCollection = (payload: {
`${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
toast.success(`${t("collection.moved")}`)
} else if (hasTeamWriteAccess.value) {
@@ -1912,13 +2034,58 @@ const editProperties = (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)
}
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) => {
if (title === `${t("confirm.remove_collection")}`) onRemoveCollection()
else if (title === `${t("confirm.remove_request")}`) onRemoveRequest()