Skip to content

Commit

Permalink
Improve upload dialog to drawer
Browse files Browse the repository at this point in the history
  • Loading branch information
yunusefendi52 committed Dec 3, 2024
1 parent 6a62a29 commit 73a5dbf
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 70 deletions.
13 changes: 13 additions & 0 deletions assets/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,17 @@ body {

.appdark .bg-color {
background: rgb(25, 25, 25);
}

.p-multiselect {
min-width: 17rem;
}

.p-multiselect-label {
display: flex;
flex-wrap: wrap;
}

.p-multiselect-token {
margin: 0.1rem;
}
83 changes: 48 additions & 35 deletions components/AppFileUpload.vue
Original file line number Diff line number Diff line change
@@ -1,37 +1,48 @@
<template>
<div class="flex flex-col gap-3" v-if="mimeTypeFromOsType">
<input class="p-2 border rounded-lg" ref="fileRef" type="file" :accept="mimeTypeFromOsType">
<div class="flex flex-col gap-2">
<label for="releasenotes">Release Notes</label>
<InputText id="releasenotes" v-model="releaseNotes" aria-describedby="releasenotes-help" />
<Drawer class="!w-[30rem]" position="right" header="Upload" v-model:visible="showUpload">
<div class="flex flex-col gap-3" v-if="mimeTypeFromOsType">
<div>
<InputFileUpload v-model="fileList" type="file" :accept="mimeTypeFromOsType" @change="checkFile" />
</div>
<div class="flex flex-col gap-2">
<label for="releasenotes">Release Notes</label>
<Textarea rows="4" id="releasenotes" v-model="releaseNotes" aria-describedby="releasenotes-help" />
</div>
<div class="flex flex-col gap-2">
<label for="releasenotes">Groups</label>
<MultiSelect v-model="selectedGroup" display="chip" :options="groups" optionLabel="name"
placeholder="Select Groups" filter />
</div>
<Button class="self-end mt-4" :label="isPending ? 'Uploading...' : 'Upload'" @click="submit"
:loading="isPending" />
</div>
<div class="flex flex-col gap-2">
<label for="releasenotes">Groups</label>
<MultiSelect v-model="selectedGroup" display="chip" :options="groups" optionLabel="name"
placeholder="Select Groups" filter />
</div>
<Button :label="isPending ? 'Uploading...' : 'Upload'" @click="submit" :loading="isPending" />
</div>
</Drawer>
</template>

<script setup lang="ts">
import { UpdateGroupsRequest } from '~/server/api/update-artifact-groups.put';
import { UpdateGroupsRequest } from '~/server/api/update-artifact-groups.put'
const releaseNotes = ref<string | null>(null)
const dialogRef = inject<any>('dialogRef');
const osType = ref<OsType | null>(null)
const prop = ref<any>(null)
const orgName = ref<string>('')
const appName = ref<string>('')
prop.value = dialogRef.value.data.props
osType.value = dialogRef.value.data.props.osType
orgName.value = dialogRef.value.data.props.orgName
appName.value = dialogRef.value.data.props.appName
const showUpload = defineModel<boolean>()
const props = defineProps<{
dataProps: any,
}>()
const emit = defineEmits(['onSuccess'])
const groupName = computed(() => dialogRef.value.data.groupName)
const releaseNotes = ref<string | null>(null)
const osType = computed<OsType | null>(() => props.dataProps!.osType)
const orgName = computed(() => props.dataProps!.orgName)
const appName = computed(() => props.dataProps!.appName)
const groupName = computed(() => props.dataProps.groupName)
const mimeTypeFromOsType = computed(() => osType.value ? getMimeTypeFromosType(osType.value) : undefined)
const fileRef = ref<HTMLInputElement | null>(null)
const fileList = ref<FileList | undefined>()
// const fileApkRef = ref<HTMLInputElement | null>(null)
const showUploadFileApk = ref(false)
const isFileAab = ref(false)
function checkFile(event: Event) {
const input = event.target as HTMLInputElement
isFileAab.value = input.files?.item(0)?.name?.endsWith('.aab') || false
}
const { data: appGroups } = useFetch('/api/groups/list-groups', {
query: {
Expand All @@ -52,8 +63,8 @@ watchEffect(() => {
})
const { mutateAsync, isPending } = useMutation({
mutationFn: async (file: File) => {
const { artifactId } = await onUpload(file, undefined)
mutationFn: async (param: { file: File, apkFile: File | undefined }) => {
const { artifactId } = await onUpload(param.file, param.apkFile)
const groupIds = selectedGroup.value?.map(e => e.id) ?? []
if (artifactId && groupIds && groupIds.length) {
await $fetch('/api/update-artifact-groups', {
Expand All @@ -66,22 +77,24 @@ const { mutateAsync, isPending } = useMutation({
}
},
onSuccess: () => {
if (fileRef.value) {
fileRef.value.value = ''
dialogRef.value.close({
success: true,
});
if (fileList.value) {
fileList.value = undefined
emit('onSuccess')
}
},
})
const submit = async () => {
const inputFile = fileRef.value as HTMLInputElement | null
const realFile = inputFile?.files && inputFile?.files.length ? inputFile.files[0] : undefined
const realFile = fileList.value?.length ? fileList.value[0] : undefined
if (!realFile) {
return
}
mutateAsync(realFile)
// const inputApkFile = fileApkRef.value as HTMLInputElement | null
// const apkActualFile = inputApkFile?.files && inputApkFile?.files.length ? inputApkFile.files[0] : undefined
mutateAsync({
file: realFile,
apkFile: undefined,
})
}
const onUpload = async (file: File, apkFile: File | undefined) => {
Expand Down
53 changes: 53 additions & 0 deletions components/InputFileUpload.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<template>
<AppCard @click="clickUpload" class="cursor-pointer !py-3">
<div class="flex flex-row items-center">
<div class="flex-1 flex flex-col">
<template v-if="modelFile">
<span>{{ modelFile.name }}</span>
<span class="text-sm">{{ formatBytes(modelFile.size) }}</span>
</template>
<span v-else>Click to upload here</span>
</div>
<Button v-if="modelFile" icon="pi pi-times" text @click="(e) => {
e.stopPropagation()
model = undefined
}" />
<Button v-else icon=" pi pi-upload" text />
</div>
</AppCard>
<input ref="fileRef" :modelValue="model" class="hidden" type="file" :accept="prop.accept" @change="(e) => {
onChange(e)
}">
</template>

<script setup lang="ts">
import { formatBytes } from '#imports'
defineOptions({
inheritAttrs: false,
})
const fileRef = ref<HTMLInputElement>()
const model = defineModel<FileList | undefined>()
watchEffect(() => {
if (!model.value && fileRef.value) {
fileRef.value.value = ''
}
})
const modelFile = computed(() => model.value && model.value.length ? model.value.item(0) : undefined)
const prop = defineProps<{
accept?: string,
}>()
function onChange(event: Event) {
const inputEl = event.target as HTMLInputElement
model.value = inputEl?.files || undefined
emit('change', event)
}
const emit = defineEmits<{
(e: 'change', event: Event): void
}>()
function clickUpload() {
fileRef.value?.click()
}
</script>
26 changes: 7 additions & 19 deletions components/Releases.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,16 @@
</template>
</DataTable>
</div>
<AppFileUpload v-model="showUpload" :dataProps="props" @on-success="() => {
showUpload = false
refresh()
}" />
</template>

<script setup lang="ts">
import AppFileUpload from './AppFileUpload.vue';
import { DataTableRowClickEvent } from 'primevue/datatable';
import { formatDate } from '#imports';
const props = defineProps<{
orgName: string,
Expand Down Expand Up @@ -69,29 +74,12 @@ const { data, refresh } = useFetch('/api/artifacts/list-artifacts', {
})
const list = computed(() => data.value)
const dialog = useDialog();
const showUpload = ref(false)
const upload = () => {
if (!props.osType) {
return
}
dialog.open(AppFileUpload, {
props: {
modal: true,
header: 'Upload',
closeOnEscape: false,
},
data: {
props,
groupName: props.groupName,
},
onClose: (o) => {
if (o?.data?.success) {
refresh()
}
}
})
showUpload.value = true
}
const selectRow = async (row: DataTableRowClickEvent) => {
Expand Down
15 changes: 0 additions & 15 deletions pages/orgs/[orgName]/apps/[appId]/releases/[detailArtifact].vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,21 +54,6 @@
</div>
</template>

<style>
.p-multiselect {
min-width: 17rem;
}
.p-multiselect-label {
display: flex;
flex-wrap: wrap;
}
.p-multiselect-token {
margin: 0.1rem;
}
</style>

<script setup lang="ts">
import { formatDate, formatBytes } from '#imports'
import { UpdateGroupsRequest } from '~/server/api/update-artifact-groups.put';
Expand Down
4 changes: 3 additions & 1 deletion server/api/artifacts/upload-artifact-url.post.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { findApiKey } from "./upload-artifact.post"

export default defineEventHandler(async (event) => {
const { fileKey, appName, orgName, releaseNotes, packageMetadata, } = await readValidatedBody(event, z.object({
const { fileKey, apkFileKey, appName, orgName, releaseNotes, packageMetadata, } = await readValidatedBody(event, z.object({
fileKey: z.string().max(128),
apkFileKey: z.string().max(128).nullish(),
appName: z.string().trim().min(1).max(128),
orgName: z.string().trim().min(1).max(128),
releaseNotes: z.string().nullish(),
Expand Down Expand Up @@ -64,6 +65,7 @@ export default defineEventHandler(async (event) => {
createdAt: now,
updatedAt: now,
fileObjectKey: fileKey,
fileObjectApkKey: apkFileKey,
versionCode2: packageData?.versionCode?.toString()!,
versionName2: packageData?.versionName!,
appsId: appId,
Expand Down

0 comments on commit 73a5dbf

Please sign in to comment.