preload data from last version, closes #404

also fixes some smaller stuff
This commit is contained in:
MiniDigger | Martin 2022-06-19 18:27:32 +02:00
parent b07ea82e03
commit 1afe7d9294
5 changed files with 50 additions and 38 deletions

View File

@ -76,7 +76,7 @@ function reset() {
async function onSearch(val: string, name: string) {
if (val) {
const projects = await useApi<PaginatedResult<Project>>(`projects?relevance=true&limit=25&offset=0&q=${val.replace("/", " ")}`);
const projects = await useApi<PaginatedResult<Project>>(`projects?relevance=true&limit=25&offset=0&q=${val ? val.replace("/", " ") : ""}`);
results.value[name] = projects.result
.filter((p) => p.namespace.owner !== route.params.user || p.namespace.slug !== route.params.project)
.map((p) => p.namespace);
@ -96,6 +96,22 @@ const filteredDeps = computed(() => {
return props.version.pluginDependencies[props.platform]?.filter((d) => !deletedDeps.value.includes(d.name)) || [];
});
function toString(namespace: ProjectNamespace | string) {
if (!namespace) return "";
if (typeof namespace === "string") return namespace;
return namespace.owner + "/" + namespace.slug;
}
function fromString(string: string): ProjectNamespace | string | null {
const split = string.split("/");
return split.length !== 2
? string
: {
owner: split[0],
slug: split[1],
};
}
defineExpose({ results, newDepResults, newDeps, deletedDeps, reset: reset });
</script>
@ -129,7 +145,7 @@ defineExpose({ results, newDepResults, newDeps, deletedDeps, reset: reset });
<!-- :rules="!!dep.externalUrl ? [] : [required(t('version.new.form.hangarProject'))]" -->
<InputAutocomplete
:id="dep.name"
v-model="dep.namespace"
:model-value="toString(dep.namespace)"
:placeholder="t('version.new.form.hangarProject')"
:values="results[dep.name]"
:item-text="getNamespace"
@ -137,6 +153,7 @@ defineExpose({ results, newDepResults, newDeps, deletedDeps, reset: reset });
:disabled="!!dep.externalUrl"
@search="onSearch($event, dep.name)"
@change="dep.externalUrl = null"
@update:modelValue="dep.namespace = fromString($event)"
/>
</td>
<td v-if="!noEditing">
@ -172,7 +189,7 @@ defineExpose({ results, newDepResults, newDeps, deletedDeps, reset: reset });
/>
<InputAutocomplete
:id="newDep.name"
v-model="newDep.namespace"
:model-value="toString(newDep.namespace)"
:placeholder="t('version.new.form.hangarProject')"
:values="newDepResults[index]"
:item-text="getNamespace"
@ -181,6 +198,7 @@ defineExpose({ results, newDepResults, newDeps, deletedDeps, reset: reset });
:rules="!!newDep.externalUrl ? [] : [required(t('version.new.form.hangarProject'))]"
@search="onNewDepSearch($event, index)"
@change="newDep.externalUrl = null"
@update:modelValue="newDep.namespace = fromString($event)"
/>
</td>
<td v-if="!noEditing">

View File

@ -43,9 +43,10 @@ const downloadLink = computed(() => {
return externalUrl.value;
}
const versionString = props.platformSelection ? "recommended" : props.version!.name;
const platform = props.platformSelection ? selectedPlatform.value : props.platform!.name;
return `${window.location.protocol}//${window.location.host}/api/v1/projects/${props.project.namespace.owner}/${props.project.namespace.slug}/versions/${versionString}/${platform}/download`;
const versionString = props.platformSelection ? "recommended" : props.version?.name;
const platform = props.platformSelection ? selectedPlatform.value : props.platform?.name;
const path = `/api/v1/projects/${props.project.namespace.owner}/${props.project.namespace.slug}/versions/${versionString}/${platform}/download`;
return import.meta.env.SSR ? path : `${window.location.protocol}//${window.location.host}${path}`;
});
if (props.platformSelection) {

View File

@ -1,5 +1,5 @@
<script setup lang="ts">
import { computed, ref, watch } from "vue";
import { computed, watch } from "vue";
import { useValidation } from "~/composables/useValidationHelpers";
import { ValidationRule } from "@vuelidate/core";
import InputWrapper from "~/components/ui/InputWrapper.vue";
@ -21,8 +21,8 @@ export interface Option {
const props = withDefaults(
defineProps<{
id: string;
modelValue: object | string | boolean | number | null;
values: Option[] | Record<string, any> | string[];
modelValue?: object | string | boolean | number | null;
values?: Option[] | Record<string, any> | string[];
itemValue?: string | ((object: object) => string);
itemText?: string | ((object: object) => string);
disabled?: boolean;

View File

@ -266,7 +266,7 @@ async function restoreVersion() {
</template>
<div class="flex items-center">
<PlatformLogo :platform="platform.enumName" :size="24" class="mr-1" />
<PlatformLogo :platform="platform?.enumName" :size="24" class="mr-1" />
{{ platform?.name }}
{{ platformTag?.data }}
</div>

View File

@ -47,7 +47,14 @@ const steps: Step[] = [
},
disableNext: computed(() => file.value == null && url.value == null),
},
{ value: "basic", header: t("version.new.steps.2.header") },
{
value: "basic",
header: t("version.new.steps.2.header"),
beforeNext: async () => {
await preload();
return true;
},
},
{ value: "dependencies", header: t("version.new.steps.3.header") },
{
value: "changelog",
@ -95,21 +102,19 @@ async function preload() {
for (const platform in pendingVersion.value.platformDependencies) {
// Get last platform and plugin dependency data for the last version of the same channel/any other channel if not found
useInternalApi<LastDependencies>(`versions/version/${props.project.namespace.owner}/${props.project.namespace.slug}/lastdependencies`, true)
.then(v => {
if (!v) {
return
useInternalApi<LastDependencies>(`versions/version/${props.project.namespace.owner}/${props.project.namespace.slug}/lastdependencies`, true, "get", {
channel: pendingVersion.value?.channelName,
platform: platform,
})
.then((v) => {
if (!v || !pendingVersion.value) {
return;
}
for (const platformVersion of v.platformDependencies) {
//TODO list of strings (e.g. "1.18", "1.19")
}
for (const pluginDependency of v.pluginDependencies) {
//TODO
}
}).catch<any>((e) =>
handleRequestError(e, ctx, i18n)
);
pendingVersion.value.platformDependencies[platform as Platform] = v.platformDependencies;
pendingVersion.value.pluginDependencies[platform as Platform] = v.pluginDependencies;
})
.catch<any>((e) => handleRequestError(e, ctx, i18n));
}
}
@ -185,16 +190,6 @@ function togglePlatform(platform: Platform) {
selectedPlatforms.value.push(platform);
}
}
function togglePlatformVersion(version: string, platform: Platform) {
const versions = pendingVersion.value!.platformDependencies[platform];
const index = version.indexOf(version);
if (index !== -1) {
versions.push(version);
} else {
versions.splice(index, 1);
}
}
useHead(
useSeo(
i18n.t("version.new.title") + " | " + props.project.name,
@ -274,7 +269,6 @@ useHead(
<template #dependencies>
<h2 class="text-xl mt-2 mb-2">{{ t("version.new.form.platformVersions") }}</h2>
<!-- todo: preload platforms and dependencies from previous version in same channel -->
<div class="flex flex-wrap gap-y-3 mb-5">
<div v-for="platform in selectedPlatformsData" :key="platform.name" class="basis-full">
<div>{{ platform.name }}</div>
@ -289,11 +283,10 @@ useHead(
<div v-for="platform in selectedPlatformsData" :key="platform.enumName" class="basis-full">
<div>{{ platform.name }}</div>
<DependencyTable
:key="`${platform}-deps-table`"
:key="`${platform.name}-deps-table`"
:platform="platform.enumName"
:version="pendingVersion"
:no-editing="pendingVersion.isFile"
:new-deps-prop="pendingVersion.pluginDependencies[platform.enumName]"
:is-new="!pendingVersion.isFile"
/>
</div>