Always support drag and drop in the Models panel (#5259)
* Always support drag and drop in the Models tab * Remove some unneeded code * Change drag and drop styling
This commit is contained in:
committed by
GitHub
parent
878231e865
commit
d8d9502ed5
@@ -10,16 +10,57 @@
|
||||
:disabled="loading"
|
||||
class="z-[1] relative"
|
||||
/>
|
||||
<ProjectPageModelsResults
|
||||
v-model:grid-or-list="gridOrList"
|
||||
v-model:search="search"
|
||||
v-model:loading="loading"
|
||||
:source-apps="selectedApps"
|
||||
:contributors="selectedMembers"
|
||||
:project="project"
|
||||
<FormFileUploadZone
|
||||
v-if="hasModels"
|
||||
v-slot="{ isDraggingFiles }"
|
||||
:disabled="!canCreateModel"
|
||||
:size-limit="maxSizeInBytes"
|
||||
:accept="accept"
|
||||
class="relative"
|
||||
@files-selected="onFilesSelected"
|
||||
>
|
||||
<div
|
||||
class="relative mt-8 min-h-[360px]"
|
||||
:class="[isDraggingFiles && canCreateModel ? 'pointer-events-none' : '']"
|
||||
>
|
||||
<ProjectPageModelsResults
|
||||
v-model:grid-or-list="gridOrList"
|
||||
v-model:search="search"
|
||||
v-model:loading="loading"
|
||||
:source-apps="selectedApps"
|
||||
:contributors="selectedMembers"
|
||||
:project="project"
|
||||
:project-id="projectId"
|
||||
@clear-search="clearSearch"
|
||||
/>
|
||||
|
||||
<div
|
||||
v-if="isDraggingFiles && canCreateModel"
|
||||
class="absolute inset-0 bg-primary/10 border border-dashed border-primary rounded-lg flex items-center justify-center z-10 bg-white/50 dark:bg-black/50 text-center text-heading text-primary"
|
||||
>
|
||||
Drop file to upload
|
||||
</div>
|
||||
</div>
|
||||
</FormFileUploadZone>
|
||||
|
||||
<div v-else class="mt-8">
|
||||
<ProjectPageModelsResults
|
||||
v-model:grid-or-list="gridOrList"
|
||||
v-model:search="search"
|
||||
v-model:loading="loading"
|
||||
:source-apps="selectedApps"
|
||||
:contributors="selectedMembers"
|
||||
:project="project"
|
||||
:project-id="projectId"
|
||||
@clear-search="clearSearch"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<ProjectPageModelsNewDialog
|
||||
v-model:open="showNewModelDialog"
|
||||
:project-id="projectId"
|
||||
class="z-[0] relative mt-8"
|
||||
@clear-search="clearSearch"
|
||||
:model-name="fileUpload?.file.name"
|
||||
@submit="onModelCreate"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -29,6 +70,11 @@ import type { SourceAppDefinition } from '@speckle/shared'
|
||||
import type { FormUsersSelectItemFragment } from '~~/lib/common/generated/gql/graphql'
|
||||
import { projectModelsPageQuery } from '~~/lib/projects/graphql/queries'
|
||||
import { useProjectPageItemViewType } from '~~/lib/projects/composables/projectPages'
|
||||
import {
|
||||
useFileImport,
|
||||
useGlobalFileImportManager
|
||||
} from '~~/lib/core/composables/fileImport'
|
||||
import type { ProjectPageLatestItemsModelItemFragment } from '~/lib/common/generated/gql/graphql'
|
||||
|
||||
const route = useRoute()
|
||||
const projectId = computed(() => route.params.id as string)
|
||||
@@ -45,9 +91,69 @@ const { result } = useQuery(projectModelsPageQuery, () => ({
|
||||
|
||||
const project = computed(() => result.value?.project)
|
||||
|
||||
// File upload logic
|
||||
const { addFailedJob } = useGlobalFileImportManager()
|
||||
const showNewModelDialog = ref(false)
|
||||
|
||||
const {
|
||||
maxSizeInBytes,
|
||||
onFilesSelected,
|
||||
accept,
|
||||
upload: fileUpload,
|
||||
isUploading,
|
||||
uploadSelected,
|
||||
resetSelected,
|
||||
isUploadable: isFileUploadUploadable
|
||||
} = useFileImport({
|
||||
project: computed(() => project.value || { id: '' }),
|
||||
manuallyTriggerUpload: true,
|
||||
fileSelectedCallback: () => {
|
||||
if (!fileUpload.value?.error) {
|
||||
// Only if upload is valid, trigger model creation dialog
|
||||
showNewModelDialog.value = true
|
||||
}
|
||||
},
|
||||
errorCallback: ({ failedJob }) => {
|
||||
// Register global file upload error and reset upload
|
||||
addFailedJob(failedJob)
|
||||
resetSelected()
|
||||
}
|
||||
})
|
||||
|
||||
const canCreateModel = computed(
|
||||
() => project.value?.permissions?.canCreateModel?.authorized ?? false
|
||||
)
|
||||
|
||||
const hasModels = computed(() => (project.value?.models?.totalCount ?? 0) > 0)
|
||||
|
||||
const onModelCreate = (params: { model: ProjectPageLatestItemsModelItemFragment }) => {
|
||||
if (!isFileUploadUploadable.value) return
|
||||
|
||||
uploadSelected({
|
||||
model: params.model
|
||||
})
|
||||
}
|
||||
|
||||
const clearSearch = () => {
|
||||
search.value = ''
|
||||
selectedMembers.value = []
|
||||
selectedApps.value = []
|
||||
}
|
||||
|
||||
// Watch for upload completion to reset state
|
||||
watch(isUploading, (newVal, oldVal) => {
|
||||
if (!newVal && oldVal) {
|
||||
// Reset file upload state when upload finishes
|
||||
resetSelected()
|
||||
}
|
||||
})
|
||||
|
||||
watch(showNewModelDialog, (newVal, oldVal) => {
|
||||
if (oldVal && !newVal) {
|
||||
// Unselect file if model was not created
|
||||
if (!isUploading.value) {
|
||||
resetSelected()
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user