mirror of
https://github.com/HangarMC/Hangar.git
synced 2025-02-23 15:12:52 +08:00
version creating dependency configuration
This commit is contained in:
parent
c4570a7dbc
commit
ff8899272c
@ -1,3 +1,13 @@
|
||||
@import '~vuetify/src/styles/styles.sass';
|
||||
|
||||
.text-transform-unset {
|
||||
text-transform: unset;
|
||||
}
|
||||
}
|
||||
|
||||
.platform-logo {
|
||||
fill: map-deep-get($material-dark, 'tabs');
|
||||
}
|
||||
|
||||
.v-tab--active .platform-logo {
|
||||
fill: map-get($blue, 'base')
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="markdown-editor">
|
||||
<div v-show="isEditing && !preview" class="ml-4">
|
||||
<v-textarea v-model="rawEdited" outlined :rows="rawEdited.split(/\r\n|\r|\n/g).length + 3" />
|
||||
<v-textarea v-model="rawEdited" outlined :rows="rawEdited.split(/\r\n|\r|\n/g).length + 3" :rules="rules" />
|
||||
</div>
|
||||
<Markdown v-show="!isEditing" :raw="raw" class="ml-4" />
|
||||
<Markdown v-if="preview" :raw="rawEdited" class="ml-4" inner-class="pl-5" />
|
||||
@ -54,6 +54,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Prop, PropSync, Vue, Watch } from 'nuxt-property-decorator';
|
||||
import { PropType } from 'vue';
|
||||
import Markdown from '~/components/Markdown.vue';
|
||||
import DeletePageModal from '~/components/modals/pages/DeletePageModal.vue';
|
||||
|
||||
@ -86,6 +87,9 @@ export default class MarkdownEditor extends Vue {
|
||||
@Prop({ default: true, type: Boolean })
|
||||
saveable!: boolean;
|
||||
|
||||
@Prop({ default: () => [], type: Array as PropType<Function[]> })
|
||||
rules!: Function[];
|
||||
|
||||
created() {
|
||||
this.rawEdited = this.raw || '';
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1" width="72" height="72" viewBox="0 0 2000 2000">
|
||||
<title>Paper</title>
|
||||
<path
|
||||
fill="#FFF"
|
||||
class="platform-logo"
|
||||
d="M1625.4 316.8c16.8 12 24.8 31.2 21.6 51.1l-204.5 1227.2c-2.4 15.2-12 28-25.6 36-7.2 4-16 6.4-24.8 6.4-6.4 0-12.8-1.6-19.2-4L1011 1485.6l-193.3 235.7c-9.6 12-24 18.4-39.2 18.4-5.6 0-12-.8-17.6-3.2-20-7.2-33.6-26.4-33.6-47.9v-278.8l690.3-846.1-854.1 739L248 1173.2c-18.4-7.2-30.4-24-32-43.9-.8-19.2 8.8-37.6 25.6-47.1l1329.4-767c8-4.8 16.8-7.2 25.6-7.2 10.4 0 20.8 3.2 28.8 8.8z"
|
||||
/>
|
||||
</svg>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<svg viewBox="0 0 500 500" xmlns="http://www.w3.org/2000/svg">
|
||||
<title>Velocity</title>
|
||||
<g fill="#fff">
|
||||
<g class="platform-logo">
|
||||
<path
|
||||
d="M236.25 232.55l-54.08-73.79a11.86 11.86 0 00-11.91-4.62L84 171.57a11.88 11.88 0 00-8 5.88l-42.64 77.07a11.84 11.84 0 00.81 12.75l54.21 74a11.86 11.86 0 0011.91 4.62l86-17.37a11.85 11.85 0 008-5.89l42.78-77.3a11.86 11.86 0 00-.82-12.78zm-59.45 74.21a9.57 9.57 0 01-13.39-2.06l-31-42.24a16 16 0 00-16-6.21l-52.58 10.63a9.58 9.58 0 01-11.29-7.49A9.58 9.58 0 0160 248.1l57-11.52a16 16 0 0010.81-7.92L156.42 177a9.58 9.58 0 0113-3.75 9.58 9.58 0 013.75 13L146.81 234a16 16 0 001.09 17.16l31 42.23a9.58 9.58 0 01-2.1 13.37z"
|
||||
/>
|
||||
|
@ -2,18 +2,15 @@
|
||||
<template>
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve">
|
||||
<title>Waterfall</title>
|
||||
<g>
|
||||
<g class="platform-logo">
|
||||
<g transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)">
|
||||
<path
|
||||
fill="#FFF"
|
||||
d="M3180.5,5009.8c-162.9-72.8-182-272.1-34.5-350.7c28.7-15.3,205-28.7,484.8-38.3c427.3-13.4,701.3-46,938.9-105.4c206.9-53.6,469.5-143.7,469.5-161c0-9.6-55.6-80.5-122.6-157.1c-900.6-1023.2-1456.3-2103.9-1783.9-3474c-61.3-251-174.4-833.5-185.9-956.2c-5.7-53.7-9.6-55.6-293.2-128.4c-866.1-218.4-1559.8-557.6-2017.7-984.9C101.2-1844.3-40.6-2447.9,243-3013.1c151.4-298.9,471.4-618.9,869.9-866.1c1030.9-643.8,2780.4-988.7,4487.7-887.2c1716.9,103.5,3146.3,599.8,3847.6,1333.6c216.5,229.9,316.2,387.1,404.3,651.5c86.2,258.7,49.8,651.5-84.3,917.9C9381.2-1102.7,8227.7-483.8,6715.8-225.1c-136,23-260.6,46-274,49.8c-24.9,7.7-26.8-7.6,26.8,505.9c145.6,1435.2,515.4,2812.9,963.8,3590.9c176.3,306.6,212.7,344.9,412,419.6c515.4,197.4,831.6,258.7,1458.2,279.8c243.4,9.6,465.6,26.8,494.4,38.3c65.2,24.9,116.9,136,99.6,212.7c-5.8,28.7-32.6,72.8-59.4,97.7c-47.9,46-53.7,46-425.4,44.1c-720.5-5.7-1124.8-78.6-1732.2-316.2c-274-109.2-298.9-128.4-500.1-438.8c-576.8-891-1000.2-2521.7-1155.4-4451.2c-30.7-400.5-59.4-1906.6-38.3-2050.3c21.1-132.2,82.4-195.5,191.6-195.5c69,0,97.7,11.5,139.9,53.7l53.6,53.7v314.3c0,174.4,5.8,316.2,13.4,316.2c44.1,0,492.5-161,615.1-220.4c249.1-120.7,383.2-270.2,341.1-377.5c-42.1-115-293.2-279.8-594-392.8c-251-93.9-768.4-216.5-1121-264.4c-51.7-7.7-231.8-23-400.5-36.4l-306.6-24.9l-57.5-63.2c-47.9-53.6-55.6-72.8-46-141.8c7.7-51.7,28.7-93.9,61.3-120.7c46-40.2,69-44.1,256.8-44.1c224.2,0,666.8,53.7,973.4,115c869.9,180.1,1406.5,444.6,1580.8,785.6c34.5,69,44.1,116.9,44.1,239.5c0,134.1-7.7,166.7-57.5,254.8c-153.3,279.8-576.8,513.5-1211,674.5l-82.4,21.1v151.4c0,84.3,5.8,153.3,15.3,153.3c7.7,0,130.3-28.8,272.1-65.2c643.8-164.8,1117.1-396.6,1410.3-689.8c184-185.8,247.2-316.2,245.3-509.7c0-118.8-9.6-162.9-57.5-258.7c-67.1-138-272.1-352.6-448.4-467.6c-492.5-321.9-1295.3-557.6-2165.3-636.1c-308.5-26.8-994.5-26.8-1303,0c-869.9,78.6-1672.8,314.2-2165.3,636.1c-176.3,115-381.3,329.6-448.4,467.6c-80.5,162.9-82.4,354.5-5.8,511.6c115,233.8,379.4,456,766.5,645.7c128.4,63.2,258.7,120.7,289.3,128.4c55.6,13.4,55.6,13.4,44.1-61.3c-7.7-40.3-13.4-101.6-13.4-136.1c0-55.6-11.5-67.1-147.5-141.8c-394.7-216.5-567.2-423.5-569.1-687.9c-3.8-389,415.8-718.6,965.7-760.7c216.5-15.3,306.6,40.3,306.6,193.5c0,111.1-61.3,162.9-220.4,185.8c-329.6,49.8-530.8,134.1-617,264.4c-70.9,105.4-59.4,166.7,49.8,272.1c51.7,49.8,120.7,105.4,153.3,120.7l57.5,30.6l-1.9-93.9c0-160.9,101.6-249.1,243.4-210.8c115,32.6,138,93.9,151.4,406.2c76.6,1632.6,346.8,2908.7,845,4000.9c279.8,615.1,707.1,1257,1237.8,1856.8c298.9,337.2,304.7,344.9,304.7,425.4c0,116.9-67.1,168.6-358.3,281.7c-291.3,111.1-607.4,199.3-868,239.5C4002.5,5011.7,3259.1,5044.3,3180.5,5009.8z M6700.5-617.9c1312.6-243.3,2322.4-753,2673-1352.8c105.4-178.2,136-298.9,126.5-509.7c-5.7-159-15.3-189.7-88.1-337.2c-321.9-649.6-1385.4-1195.7-2801.4-1439c-605.5-105.4-1293.4-147.5-1989-122.6c-1950.7,67.1-3610.1,710.9-4033.5,1563.6L507.5-2651v220.4v222.3l86.2,172.5c70.9,143.7,116.9,203.1,268.3,354.5c99.6,101.6,247.2,228,327.7,281.7c369.8,252.9,952.3,503.9,1477.4,638.1c80.5,21.1,161,44.1,178.2,49.8c24.9,9.6,30.7,3.8,24.9-30.6c-3.8-34.5-38.3-53.7-183.9-105.4c-701.3-251-1230.2-684.1-1366.2-1119C1180-2421,1390.8-2894.3,1889-3250.8c1469.7-1046.2,4754-1046.2,6223.7,0c823.9,588.3,812.4,1418-30.7,2015.8c-346.8,245.3-938.9,482.9-1490.8,597.8c-90.1,19.2-170.5,42.2-180.1,49.8C6382.4-562.4,6407.3-564.3,6700.5-617.9z"
|
||||
/>
|
||||
<path
|
||||
fill="#FFF"
|
||||
d="M6666,4578.7c-53.7-46-182-220.4-333.4-454.1c-908.3-1406.5-1303-2989.2-1446.7-5806c-9.6-205-19.2-473.3-19.2-595.9c0-195.4,5.7-228,38.3-272.1c86.2-109.2,283.6-76.6,323.8,51.7c11.5,32.6,28.7,279.8,40.3,548c126.5,3021.8,549.9,4685,1561.7,6108.7c124.6,174.4,143.7,212.7,143.7,283.6c0,67.1-9.6,90.1-59.4,130.3C6840.4,4636.2,6735,4640,6666,4578.7z"
|
||||
/>
|
||||
<path
|
||||
fill="#FFF"
|
||||
d="M5958.9,4534.6c-26.8-17.2-105.4-101.6-176.3-187.8C4933.8,3308.3,4381.9,2053.2,4073.4,455.1c-138-718.6-256.8-1820.3-266.3-2494.8c-3.8-281.7-1.9-291.3,42.2-339.2c67.1-70.9,157.1-82.4,237.6-32.6c93.9,57.5,88.1,30.7,128.4,749.2c76.6,1356.6,310.4,2623.2,661.1,3594.7c289.3,793.3,687.9,1521.4,1140.1,2077.1c214.6,262.5,229.9,287.4,229.9,367.9C6246.4,4526.9,6085.4,4613.2,5958.9,4534.6z"
|
||||
/>
|
||||
</g>
|
||||
|
@ -235,6 +235,7 @@ const msgs: LocaleMessageObject = {
|
||||
fileName: 'File name',
|
||||
fileSize: 'File size',
|
||||
externalUrl: 'External URL',
|
||||
hangarProject: 'Hangar Project',
|
||||
channel: 'Channel',
|
||||
addChannel: 'Add Channel',
|
||||
unstable: 'Unstable',
|
||||
@ -244,6 +245,8 @@ const msgs: LocaleMessageObject = {
|
||||
bulletin: 'Release Bulletin',
|
||||
desc: "What's new in this release?",
|
||||
},
|
||||
platforms: 'Platforms',
|
||||
dependencies: 'Plugin Dependencies',
|
||||
},
|
||||
error: {
|
||||
metaNotFound: 'Could not load metadata from uploaded file',
|
||||
@ -262,6 +265,7 @@ const msgs: LocaleMessageObject = {
|
||||
unknown: 'An unknown error has occurred',
|
||||
incomplete: 'Plugin file missing {0}',
|
||||
noDescription: 'Must have a description',
|
||||
invalidPluginDependencyNamespace: 'Declared plugin dependency has an invalid project namespace',
|
||||
channel: {
|
||||
noName: 'Must have a channel name specified',
|
||||
noColor: 'Must have a channel color specified',
|
||||
|
@ -1,7 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-tabs>
|
||||
<v-tab v-for="version in versionPlatforms" :key="`platform-${version}`" nuxt :to="version.toLowerCase()">
|
||||
<v-tab
|
||||
v-for="version in versionPlatforms"
|
||||
:key="`platform-${version}`"
|
||||
nuxt
|
||||
:to="{ name: `author-slug-versions-version-platform`, params: { ...$route.params, platform: version.toLowerCase() } }"
|
||||
>
|
||||
<v-icon left v-text="`$vuetify.icons.${version.toLowerCase()}`"></v-icon>
|
||||
{{ version }}
|
||||
</v-tab>
|
||||
</v-tabs>
|
||||
|
@ -4,8 +4,8 @@
|
||||
<v-col>{{ $t('reviews.headline', [version.author, $util.prettyDate(version.createdAt)]) }}</v-col>
|
||||
<v-col>
|
||||
<v-btn color="secondary" @click="removeFromQueue">{{ $t('reviews.removeFromQueue') }}</v-btn>
|
||||
<v-btn color="secondary" :to="'/' + $route.params.author + '/' + $route.params.slug">{{ $t('reviews.projectPage') }}</v-btn>
|
||||
<v-btn color="secondary" :to="'/' + $route.params.author + '/' + $route.params.slug + '/versions/' + $route.params.version + '/jar'">
|
||||
<v-btn color="secondary" :to="{ name: 'author-slug', params: $route.params }" nuxt exact>{{ $t('reviews.projectPage') }}</v-btn>
|
||||
<v-btn color="secondary" :to="'/' + $route.params.author + '/' + $route.params.slug + '/versions/' + $route.params.version + '/jar'" nuxt>
|
||||
{{ $t('reviews.downloadFile') }}
|
||||
</v-btn>
|
||||
<v-btn v-if="!hasReviewStarted" color="primary" @click="startReview">{{ $t('reviews.startReview') }}</v-btn>
|
||||
@ -22,8 +22,8 @@
|
||||
v-model="message"
|
||||
:label="$t('reviews.reviewMessage')"
|
||||
append-outer-icon="mdi-clipboard"
|
||||
@click:append-outer="sendMessage"
|
||||
></v-text-field>
|
||||
@click="sendMessage"
|
||||
/>
|
||||
|
||||
<h2>{{ $t('reviews.title') }}</h2>
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
<v-card-text v-else>
|
||||
<v-form v-model="validForm">
|
||||
<v-form ref="newVersionForm" v-model="validForm">
|
||||
<v-row justify="space-around">
|
||||
<v-col cols="12">
|
||||
<v-btn color="warning" block @click="reset">{{ $t('general.reset') }}</v-btn>
|
||||
@ -26,6 +26,7 @@
|
||||
:hide-details="isFile"
|
||||
:label="$t('version.new.form.versionString')"
|
||||
:disabled="isFile"
|
||||
:autofocus="!isFile"
|
||||
filled
|
||||
:rules="[$util.$vc.require('Version string')]"
|
||||
/>
|
||||
@ -79,7 +80,7 @@
|
||||
</NewChannelModal>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-sheet color="accent" elevation="1" rounded class="mt-2">
|
||||
<v-sheet color="accent darken-1" elevation="1" rounded class="mt-2">
|
||||
<v-row justify="space-around">
|
||||
<v-col md="3" sm="4" cols="12">
|
||||
<v-checkbox v-model="pendingVersion.unstable" :label="$t('version.new.form.unstable')" />
|
||||
@ -92,13 +93,105 @@
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-sheet>
|
||||
<v-card color="accent darken-1" elevation="1" class="mt-6">
|
||||
<v-card-title class="pb-0">{{ $t('version.new.form.platforms') }}</v-card-title>
|
||||
<v-card-text>
|
||||
<v-row justify="space-around">
|
||||
<v-select
|
||||
v-model="selectedPlatforms"
|
||||
style="display: none"
|
||||
multiple
|
||||
:items="Array.from($store.state.platforms.keys())"
|
||||
:rules="[(v) => !!v.length || 'Error']"
|
||||
/>
|
||||
<v-col v-for="platform in platforms" :key="platform.name" class="flex-grow-0">
|
||||
<div :class="{ platformError: !selectedPlatforms.length }" class="platform-version-label text-center">
|
||||
{{ platform.name }}
|
||||
</div>
|
||||
<v-checkbox
|
||||
v-for="version in platform.possibleVersions"
|
||||
:key="`${platform.name}-${version}`"
|
||||
v-model="pendingVersion.platformDependencies[platform.name.toUpperCase()]"
|
||||
:rules="platformVersionRules"
|
||||
class="platform-version-checkbox"
|
||||
dense
|
||||
hide-details
|
||||
:label="version"
|
||||
:value="version"
|
||||
@change="togglePlatformVersion($event, platform.name.toUpperCase())"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
<v-card v-if="platformsForPluginDeps.length" color="accent darken-1" elevation="1" class="mt-2 pb-1">
|
||||
<v-card-title class="pb-0">{{ $t('version.new.form.dependencies') }}</v-card-title>
|
||||
<template v-for="platform in platformsForPluginDeps">
|
||||
<v-card-subtitle :key="`${platform}-deps`" class="mt-3 pb-0">{{ $store.state.platforms.get(platform).name }}</v-card-subtitle>
|
||||
<v-simple-table :key="`${platform}-deps-table`" class="ma-2">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Required?</th>
|
||||
<th>Link</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="dep in pendingVersion.pluginDependencies[platform]" :key="`${platform}-${dep.name}`">
|
||||
<td>{{ dep.name }}</td>
|
||||
<!--TODO having ripple here produces console errors?-->
|
||||
<td><v-simple-checkbox v-model="dep.required" :ripple="false" /></td>
|
||||
<td>
|
||||
<v-text-field
|
||||
v-model="dep.externalUrl"
|
||||
dense
|
||||
hide-details
|
||||
placeholder="External Link"
|
||||
:disabled="dep.namespace !== null && Object.keys(dep.namespace).length !== 0"
|
||||
:rules="
|
||||
dep.namespace !== null && Object.keys(dep.namespace).length !== 0
|
||||
? []
|
||||
: [$util.$vc.require('version.new.form.externalUrl')]
|
||||
"
|
||||
clearable
|
||||
/>
|
||||
<v-autocomplete
|
||||
v-model="dep.namespace"
|
||||
dense
|
||||
hide-details
|
||||
hide-no-data
|
||||
placeholder="Hangar Project"
|
||||
class="mb-2"
|
||||
:items="hangarProjectSearchResults"
|
||||
:item-text="getNamespace"
|
||||
return-object
|
||||
clearable
|
||||
auto-select-first
|
||||
:disabled="!!dep.externalUrl"
|
||||
:rules="!!dep.externalUrl ? [] : [$util.$vc.require('version.new.form.hangarProject')]"
|
||||
@update:search-input="onSearch"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</v-simple-table>
|
||||
</template>
|
||||
</v-card>
|
||||
<v-row class="mt-3">
|
||||
<v-col cols="12" class="pb-0 ml-6">
|
||||
<h2>{{ $t('version.new.form.release.bulletin') }}</h2>
|
||||
{{ $t('version.new.form.release.desc') }}
|
||||
</v-col>
|
||||
<v-col cols="12">
|
||||
<MarkdownEditor ref="editor" :deletable="false" :cancellable="false" :saveable="false" editing :raw="pendingVersion.description" />
|
||||
<MarkdownEditor
|
||||
ref="editor"
|
||||
:deletable="false"
|
||||
:cancellable="false"
|
||||
:saveable="false"
|
||||
editing
|
||||
:raw="pendingVersion.description"
|
||||
:rules="[$util.$vc.require($t('version.new.form.release.bulletin'))]"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-form>
|
||||
@ -115,12 +208,14 @@
|
||||
<script lang="ts">
|
||||
import { Component } from 'nuxt-property-decorator';
|
||||
import remove from 'lodash-es/remove';
|
||||
import { PendingVersion, ProjectChannel } from 'hangar-internal';
|
||||
import { IPlatform, PendingVersion, ProjectChannel } from 'hangar-internal';
|
||||
import { PaginatedResult, Project, ProjectNamespace } from 'hangar-api';
|
||||
import { HangarProjectMixin } from '~/components/mixins';
|
||||
import { ProjectPermission } from '~/utils/perms';
|
||||
import { NamedPermission, Platform } from '~/types/enums';
|
||||
import MarkdownEditor from '~/components/MarkdownEditor.vue';
|
||||
import NewChannelModal from '~/components/modals/NewChannelModal.vue';
|
||||
import { RootState } from '~/store';
|
||||
|
||||
// TODO implement setting up dependencies
|
||||
@Component({
|
||||
@ -133,6 +228,9 @@ export default class ProjectVersionsNewPage extends HangarProjectMixin {
|
||||
pendingVersion: PendingVersion | null = null;
|
||||
validForm: boolean = false;
|
||||
channels: ProjectChannel[] = [];
|
||||
selectedPlatforms: string[] = [];
|
||||
hangarProjectSearchResults: ProjectNamespace[] = [];
|
||||
|
||||
loading = {
|
||||
create: false,
|
||||
submit: false,
|
||||
@ -144,6 +242,19 @@ export default class ProjectVersionsNewPage extends HangarProjectMixin {
|
||||
};
|
||||
}
|
||||
|
||||
onSearch(val: string) {
|
||||
if (val) {
|
||||
console.log(val);
|
||||
this.$api
|
||||
.request<PaginatedResult<Project>>(`projects?relevance=true&limit=25&offset=0&q=${val}`)
|
||||
.then((projects) => {
|
||||
// console.log(projects.result);
|
||||
this.hangarProjectSearchResults = projects.result.map((p) => p.namespace);
|
||||
})
|
||||
.catch(console.error);
|
||||
}
|
||||
}
|
||||
|
||||
get canCreate(): boolean {
|
||||
return (!!this.file || !!this.url) && !(!!this.file && !!this.url);
|
||||
}
|
||||
@ -152,6 +263,35 @@ export default class ProjectVersionsNewPage extends HangarProjectMixin {
|
||||
return this.channels.find((c) => c.name === this.pendingVersion?.channelName);
|
||||
}
|
||||
|
||||
get platforms(): IPlatform[] {
|
||||
if (this.pendingVersion?.isFile) {
|
||||
const platforms: IPlatform[] = [];
|
||||
for (const platformDependenciesKey in this.pendingVersion.platformDependencies) {
|
||||
platforms.push((this.$store.state as RootState).platforms.get(platformDependenciesKey as Platform)!);
|
||||
}
|
||||
return platforms;
|
||||
}
|
||||
return Array.from((this.$store.state as RootState).platforms.values());
|
||||
}
|
||||
|
||||
get platformsForPluginDeps(): Platform[] {
|
||||
const platforms: Platform[] = [];
|
||||
for (const key of Object.keys(this.pendingVersion!.pluginDependencies)) {
|
||||
if (this.pendingVersion?.pluginDependencies[key as Platform].length) {
|
||||
platforms.push(key as Platform);
|
||||
}
|
||||
}
|
||||
return platforms;
|
||||
}
|
||||
|
||||
get platformVersionRules(): Function[] {
|
||||
if (!this.pendingVersion?.isFile) {
|
||||
return [];
|
||||
} else {
|
||||
return [(v: string[]) => !!v.length || 'Error'];
|
||||
}
|
||||
}
|
||||
|
||||
addChannel(channel: ProjectChannel) {
|
||||
if (this.pendingVersion) {
|
||||
remove(this.channels, (c) => c.temp);
|
||||
@ -162,17 +302,21 @@ export default class ProjectVersionsNewPage extends HangarProjectMixin {
|
||||
|
||||
$refs!: {
|
||||
editor: MarkdownEditor;
|
||||
newVersionForm: any;
|
||||
};
|
||||
|
||||
getNamespace(namespace: ProjectNamespace) {
|
||||
return `${namespace.owner}/${namespace.slug}`;
|
||||
}
|
||||
|
||||
createVersion() {
|
||||
if (this.pendingVersion) {
|
||||
if (!this.$refs.newVersionForm.validate()) {
|
||||
return;
|
||||
}
|
||||
this.pendingVersion.description = this.$refs.editor.rawEdited;
|
||||
this.pendingVersion.channelColor = this.currentChannel!.color;
|
||||
this.pendingVersion.channelNonReviewed = this.currentChannel!.nonReviewed;
|
||||
// TODO remove debug values
|
||||
this.pendingVersion.platformDependencies.PAPER = ['1.13', '1.14', '1.15'];
|
||||
this.pendingVersion.platformDependencies.VELOCITY = ['1.0'];
|
||||
this.pendingVersion.platformDependencies.WATERFALL = ['1.13', '1.14', '1.15'];
|
||||
// played around trying to get this to happen in jackson's deserialization, but couldn't figure it out.
|
||||
for (const platform in this.pendingVersion.platformDependencies) {
|
||||
if (this.pendingVersion.platformDependencies[platform as Platform].length < 1) {
|
||||
@ -188,12 +332,20 @@ export default class ProjectVersionsNewPage extends HangarProjectMixin {
|
||||
this.$api
|
||||
.requestInternal(`versions/version/${this.project.id}/create`, true, 'post', this.pendingVersion)
|
||||
.then(() => {
|
||||
this.$router.push(`/${this.$route.params.author}/${this.$route.params.slug}/versions`);
|
||||
// this.$router.push(`/${this.$route.params.author}/${this.$route.params.slug}/versions`);
|
||||
})
|
||||
.catch(this.$util.handleRequestError);
|
||||
}
|
||||
}
|
||||
|
||||
togglePlatformVersion(value: string[], platform: string) {
|
||||
if (value.length === 0 && this.selectedPlatforms.includes(platform)) {
|
||||
this.$delete(this.selectedPlatforms, this.selectedPlatforms.indexOf(platform));
|
||||
} else if (!this.selectedPlatforms.includes(platform)) {
|
||||
this.selectedPlatforms.push(platform);
|
||||
}
|
||||
}
|
||||
|
||||
// todo handle errors better, for example "version.new.error.duplicateNameAndPlatform"
|
||||
// TODO should have a set of validate name endpoints to provide this check while the user is changing the name (Project name, Version name, page name, channel name, etc)
|
||||
async createPendingVersion() {
|
||||
@ -213,7 +365,11 @@ export default class ProjectVersionsNewPage extends HangarProjectMixin {
|
||||
this.pendingVersion = await this.$api
|
||||
.requestInternal<PendingVersion>(`versions/version/${this.project.id}/upload`, true, 'post', data)
|
||||
.catch<any>(this.$util.handlePageRequestError);
|
||||
|
||||
for (const platformDependenciesKey in this.pendingVersion?.platformDependencies) {
|
||||
if (this.pendingVersion?.platformDependencies[platformDependenciesKey as Platform].length) {
|
||||
this.selectedPlatforms.push(platformDependenciesKey);
|
||||
}
|
||||
}
|
||||
this.loading.create = false;
|
||||
}
|
||||
|
||||
@ -228,3 +384,19 @@ export default class ProjectVersionsNewPage extends HangarProjectMixin {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import '~vuetify/src/styles/styles.sass';
|
||||
|
||||
.platform-version-checkbox.v-input--selection-controls {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.platform-version-label {
|
||||
color: map-deep-get($material-dark, 'text', 'secondary');
|
||||
|
||||
&.platformError {
|
||||
color: var(--v-error-base);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -23,7 +23,9 @@ export default {
|
||||
default: 'dark',
|
||||
dark: true,
|
||||
disable: false,
|
||||
options: {},
|
||||
options: {
|
||||
customProperties: true,
|
||||
},
|
||||
themes: {
|
||||
dark: {
|
||||
anchor: colors.blue.lighten3,
|
||||
|
4
frontend/types/internal/versions.d.ts
vendored
4
frontend/types/internal/versions.d.ts
vendored
@ -1,11 +1,11 @@
|
||||
declare module 'hangar-internal' {
|
||||
import { FileInfo, Named, Version } from 'hangar-api';
|
||||
import { FileInfo, Named, ProjectNamespace, Version } from 'hangar-api';
|
||||
import { Platform } from '~/types/enums';
|
||||
|
||||
interface PlatformDependency {
|
||||
name: string;
|
||||
required: boolean;
|
||||
projectId: number | null;
|
||||
namespace: ProjectNamespace | null;
|
||||
externalUrl: string | null;
|
||||
}
|
||||
|
||||
|
@ -10189,9 +10189,9 @@ vuetify-loader@^1.6.0:
|
||||
loader-utils "^1.2.0"
|
||||
|
||||
vuetify@^2.4.2:
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/vuetify/-/vuetify-2.4.2.tgz#d37d160c1fc6b241fc166a32980b34590a017d6e"
|
||||
integrity sha512-8W1928Fv6GKwLiOThutYf2wtD5C9+vcCavlI8NT0YxNOVvluoL8xrep8mGGwDsCkay+4LzaAX92owKeNi3kpWg==
|
||||
version "2.4.6"
|
||||
resolved "https://registry.yarnpkg.com/vuetify/-/vuetify-2.4.6.tgz#127b37bd36c7a63f61615e0cd6f97e8b203e7a07"
|
||||
integrity sha512-oqAWKAin07ip/QuT/p4bL1LegE3MYPbfojrOcj80RATZDSnJyco2PZD8QuIzd0RhYfdAuSTkY8elvHsLu90RuQ==
|
||||
|
||||
vuex-class@^0.3.2:
|
||||
version "0.3.2"
|
||||
|
@ -1,135 +1,83 @@
|
||||
package io.papermc.hangar.db.dao.internal;
|
||||
|
||||
import io.papermc.hangar.db.dao.v1.VersionsApiDAO.VersionReducer;
|
||||
import io.papermc.hangar.model.api.project.version.PluginDependency;
|
||||
import io.papermc.hangar.model.common.Platform;
|
||||
import io.papermc.hangar.model.internal.versions.HangarVersion;
|
||||
import org.jdbi.v3.core.enums.EnumByOrdinal;
|
||||
import org.jdbi.v3.core.enums.EnumStrategy;
|
||||
import org.jdbi.v3.core.result.LinkedHashMapRowReducer;
|
||||
import org.jdbi.v3.core.result.RowView;
|
||||
import org.jdbi.v3.sqlobject.config.RegisterConstructorMapper;
|
||||
import org.jdbi.v3.sqlobject.config.UseEnumStrategy;
|
||||
import org.jdbi.v3.sqlobject.customizer.Define;
|
||||
import org.jdbi.v3.sqlobject.statement.SqlQuery;
|
||||
import org.jdbi.v3.sqlobject.statement.UseRowReducer;
|
||||
import org.jdbi.v3.stringtemplate4.UseStringTemplateEngine;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
@UseStringTemplateEngine
|
||||
@UseEnumStrategy(EnumStrategy.BY_ORDINAL)
|
||||
@RegisterConstructorMapper(HangarVersion.class)
|
||||
public interface HangarVersionsDAO {
|
||||
|
||||
@UseEnumStrategy(EnumStrategy.BY_ORDINAL)
|
||||
@UseRowReducer(HangarVersionReducer.class)
|
||||
@RegisterConstructorMapper(value = PluginDependency.class, prefix = "pd_")
|
||||
@UseStringTemplateEngine
|
||||
@SqlQuery("SELECT pv.id," +
|
||||
" pv.created_at," +
|
||||
" pv.version_string," +
|
||||
" pv.visibility," +
|
||||
" pv.description," +
|
||||
" coalesce((SELECT sum(pvd.downloads) FROM project_versions_downloads pvd WHERE p.id = pvd.project_id AND pv.id = pvd.version_id), 0) vs_downloads," +
|
||||
" pv.file_name fi_name," +
|
||||
" pv.file_size fi_size_bytes," +
|
||||
" pv.hash fi_md5_hash," +
|
||||
" pv.external_url," +
|
||||
" u.name author," +
|
||||
" pv.review_state," +
|
||||
" pvt.name AS tag_name," +
|
||||
" pvt.data AS tag_data," +
|
||||
" pvt.color AS tag_color," +
|
||||
" 'Channel' AS ch_tag_name," +
|
||||
" pc.name AS ch_tag_data," +
|
||||
" pc.color AS ch_tag_color," +
|
||||
" d.platform pd_platform," +
|
||||
" d.name pd_name," +
|
||||
" d.required pd_required," +
|
||||
" d.project_id pd_project_id," +
|
||||
" d.external_url pd_external_url," +
|
||||
" plv.platform p_platform," +
|
||||
" plv.version p_version," +
|
||||
" exists(SELECT 1 FROM recommended_project_versions rpv WHERE rpv.version_id = pv.id) as recommended," +
|
||||
" ru.name approved_by" +
|
||||
" pv.created_at," +
|
||||
" pv.version_string," +
|
||||
" pv.visibility," +
|
||||
" pv.description," +
|
||||
" coalesce((SELECT sum(pvd.downloads) FROM project_versions_downloads pvd WHERE p.id = pvd.project_id AND pv.id = pvd.version_id), 0) vs_downloads," +
|
||||
" pv.file_name fi_name," +
|
||||
" pv.file_size fi_size_bytes," +
|
||||
" pv.hash fi_md5_hash," +
|
||||
" pv.external_url," +
|
||||
" u.name author," +
|
||||
" pv.review_state," +
|
||||
" exists(SELECT 1 FROM recommended_project_versions rpv WHERE rpv.version_id = pv.id) as recommended," +
|
||||
" ru.name approved_by" +
|
||||
" FROM project_versions pv" +
|
||||
" JOIN projects p ON pv.project_id = p.id" +
|
||||
" LEFT JOIN users u ON pv.author_id = u.id" +
|
||||
" LEFT JOIN project_version_tags pvt ON pv.id = pvt.version_id" +
|
||||
" LEFT JOIN project_channels pc ON pv.channel_id = pc.id " +
|
||||
" JOIN project_version_platform_dependencies pvpd ON pv.id = pvpd.version_id" +
|
||||
" JOIN platform_versions plv ON pvpd.platform_version_id = plv.id" +
|
||||
" LEFT JOIN project_version_dependencies d ON pv.id = d.version_id" +
|
||||
" LEFT JOIN users ru ON pv.reviewer_id = ru.id" +
|
||||
" WHERE <if(!canSeeHidden)>(pv.visibility = 0 " +
|
||||
" <if(userId)>OR (<userId> IN (SELECT pm.user_id FROM project_members_all pm WHERE pm.id = p.id) AND pv.visibility != 4) <endif>) AND <endif> " +
|
||||
" plv.platform = :platform AND" +
|
||||
" pvt.name IS NOT NULL AND" +
|
||||
" lower(p.owner_name) = lower(:author) AND" +
|
||||
" lower(p.slug) = lower(:slug) AND" +
|
||||
" lower(pv.version_string) = lower(:versionString)" +
|
||||
" GROUP BY p.id, pv.id, u.id, pc.id, d.id, plv.id, pvt.id, ru.id " +
|
||||
" ORDER BY pv.created_at DESC")
|
||||
Optional<HangarVersion> getVersion(String author, String slug, String versionString, @EnumByOrdinal Platform platform, @Define boolean canSeeHidden, @Define Long userId);
|
||||
" WHERE " +
|
||||
" <if(!canSeeHidden)>" +
|
||||
" (pv.visibility = 0 " +
|
||||
" <if(userId)>" +
|
||||
" OR (<userId> IN (SELECT pm.user_id FROM project_members_all pm WHERE pm.id = p.id) AND pv.visibility != 4) " +
|
||||
" <endif>)" +
|
||||
" AND" +
|
||||
" <endif>" +
|
||||
" pv.id = :versionId" +
|
||||
" ORDERED BY pv.created_at DESC"
|
||||
)
|
||||
HangarVersion getVersion(long versionId, @Define boolean canSeeHidden, @Define Long userId);
|
||||
|
||||
@UseEnumStrategy(EnumStrategy.BY_ORDINAL)
|
||||
@UseRowReducer(HangarVersionReducer.class)
|
||||
@RegisterConstructorMapper(value = PluginDependency.class, prefix = "pd_")
|
||||
@UseStringTemplateEngine
|
||||
@SqlQuery("SELECT pv.id," +
|
||||
" pv.created_at," +
|
||||
" pv.version_string," +
|
||||
" pv.visibility," +
|
||||
" pv.description," +
|
||||
" coalesce((SELECT sum(pvd.downloads) FROM project_versions_downloads pvd WHERE p.id = pvd.project_id AND pv.id = pvd.version_id), 0) vs_downloads," +
|
||||
" pv.file_name fi_name," +
|
||||
" pv.file_size fi_size_bytes," +
|
||||
" pv.hash fi_md5_hash," +
|
||||
" pv.external_url," +
|
||||
" u.name author," +
|
||||
" pv.review_state," +
|
||||
" pvt.name AS tag_name," +
|
||||
" pvt.data AS tag_data," +
|
||||
" pvt.color AS tag_color," +
|
||||
" 'Channel' AS ch_tag_name," +
|
||||
" pc.name AS ch_tag_data," +
|
||||
" pc.color AS ch_tag_color," +
|
||||
" d.platform pd_platform," +
|
||||
" d.name pd_name," +
|
||||
" d.required pd_required," +
|
||||
" d.project_id pd_project_id," +
|
||||
" d.external_url pd_external_url," +
|
||||
" plv.platform p_platform," +
|
||||
" plv.version p_version," +
|
||||
" exists(SELECT 1 FROM recommended_project_versions rpv WHERE rpv.version_id = pv.id) as recommended," +
|
||||
" ru.name approved_by" +
|
||||
" pv.created_at," +
|
||||
" pv.version_string," +
|
||||
" pv.visibility," +
|
||||
" pv.description," +
|
||||
" coalesce((SELECT sum(pvd.downloads) FROM project_versions_downloads pvd WHERE p.id = pvd.project_id AND pv.id = pvd.version_id), 0) vs_downloads," +
|
||||
" pv.file_name fi_name," +
|
||||
" pv.file_size fi_size_bytes," +
|
||||
" pv.hash fi_md5_hash," +
|
||||
" pv.external_url," +
|
||||
" u.name author," +
|
||||
" pv.review_state," +
|
||||
" exists(SELECT 1 FROM recommended_project_versions rpv WHERE rpv.version_id = pv.id) as recommended," +
|
||||
" ru.name approved_by" +
|
||||
" FROM project_versions pv" +
|
||||
" JOIN projects p ON pv.project_id = p.id" +
|
||||
" JOIN projects p ON pv.project_id = p.id" +
|
||||
" LEFT JOIN users u ON pv.author_id = u.id" +
|
||||
" LEFT JOIN project_version_tags pvt ON pv.id = pvt.version_id" +
|
||||
" LEFT JOIN project_channels pc ON pv.channel_id = pc.id " +
|
||||
" JOIN project_version_platform_dependencies pvpd ON pv.id = pvpd.version_id" +
|
||||
" JOIN platform_versions plv ON pvpd.platform_version_id = plv.id" +
|
||||
" LEFT JOIN project_version_dependencies d ON pv.id = d.version_id" +
|
||||
" LEFT JOIN users ru ON pv.reviewer_id = ru.id" +
|
||||
" WHERE <if(!canSeeHidden)>(pv.visibility = 0 " +
|
||||
" <if(userId)>OR (<userId> IN (SELECT pm.user_id FROM project_members_all pm WHERE pm.id = p.id) AND pv.visibility != 4) <endif>) AND <endif> " +
|
||||
" pvt.name IS NOT NULL AND" +
|
||||
" WHERE " +
|
||||
" <if(!canSeeHidden)>" +
|
||||
" (pv.visibility = 0 " +
|
||||
" <if(userId)>" +
|
||||
" OR (<userId> IN (SELECT pm.user_id FROM project_members_all pm WHERE pm.id = p.id) AND pv.visibility != 4) " +
|
||||
" <endif>)" +
|
||||
" AND" +
|
||||
" <endif>" +
|
||||
" lower(p.owner_name) = lower(:author) AND" +
|
||||
" lower(p.slug) = lower(:slug) AND" +
|
||||
" lower(pv.version_string) = lower(:versionString)" +
|
||||
" GROUP BY p.id, pv.id, u.id, pc.id, d.id, plv.id, pvt.id, ru.id" +
|
||||
" ORDER BY pv.created_at DESC")
|
||||
List<HangarVersion> getVersions(String author, String slug, String versionString, @Define boolean canSeeHidden, @Define Long userId);
|
||||
|
||||
class HangarVersionReducer implements LinkedHashMapRowReducer<Long, HangarVersion> {
|
||||
@Override
|
||||
public void accumulate(Map<Long, HangarVersion> container, RowView rowView) {
|
||||
final HangarVersion version = container.computeIfAbsent(rowView.getColumn("id", Long.class), id -> rowView.getRow(HangarVersion.class));
|
||||
VersionReducer._accumulateVersion(rowView, version.getPluginDependencies(), version.getPlatformDependencies(), version.getTags(), version);
|
||||
}
|
||||
}
|
||||
" pv.version_string = :versionString" +
|
||||
" ORDER BY pv.created_at DESC"
|
||||
)
|
||||
List<HangarVersion> getVersionsWithVersionString(String author, String slug, String versionString, @Define boolean canSeeHidden, @Define Long userId);
|
||||
}
|
||||
|
@ -28,6 +28,9 @@ public interface ProjectChannelsDAO {
|
||||
@SqlQuery("SELECT * FROM project_channels WHERE project_id = :projectId AND name = :name AND color = :color")
|
||||
ProjectChannelTable getProjectChannel(long projectId, String name, @EnumByOrdinal Color color);
|
||||
|
||||
@SqlQuery("SELECT pc.* FROM project_channels pc JOIN project_versions pv ON pc.id = pv.channel_id WHERE pv.id = :versionId")
|
||||
ProjectChannelTable getProjectChannelForVersion(long versionId);
|
||||
|
||||
@SqlQuery("SELECT * FROM project_channels WHERE project_id = :projectId ORDER BY created_at LIMIT 1")
|
||||
ProjectChannelTable getFirstChannel(long projectId);
|
||||
}
|
||||
|
@ -1,44 +1,171 @@
|
||||
package io.papermc.hangar.db.dao.v1;
|
||||
|
||||
import io.papermc.hangar.model.api.color.TagColor;
|
||||
import io.papermc.hangar.db.mappers.TagMapper;
|
||||
import io.papermc.hangar.model.api.project.version.PluginDependency;
|
||||
import io.papermc.hangar.model.api.project.version.Tag;
|
||||
import io.papermc.hangar.model.api.project.version.Version;
|
||||
import io.papermc.hangar.model.api.project.version.VersionStats;
|
||||
import io.papermc.hangar.model.common.Color;
|
||||
import io.papermc.hangar.model.common.Platform;
|
||||
import io.papermc.hangar.util.StringUtils;
|
||||
import org.jdbi.v3.core.enums.EnumByOrdinal;
|
||||
import org.jdbi.v3.core.enums.EnumStrategy;
|
||||
import org.jdbi.v3.core.result.LinkedHashMapRowReducer;
|
||||
import org.jdbi.v3.core.result.RowView;
|
||||
import org.jdbi.v3.sqlobject.config.KeyColumn;
|
||||
import org.jdbi.v3.sqlobject.config.RegisterConstructorMapper;
|
||||
import org.jdbi.v3.sqlobject.config.RegisterRowMapper;
|
||||
import org.jdbi.v3.sqlobject.config.UseEnumStrategy;
|
||||
import org.jdbi.v3.sqlobject.config.ValueColumn;
|
||||
import org.jdbi.v3.sqlobject.customizer.BindList;
|
||||
import org.jdbi.v3.sqlobject.customizer.Define;
|
||||
import org.jdbi.v3.sqlobject.statement.SqlQuery;
|
||||
import org.jdbi.v3.sqlobject.statement.UseRowReducer;
|
||||
import org.jdbi.v3.stringtemplate4.UseStringTemplateEngine;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.SortedMap;
|
||||
import java.util.SortedSet;
|
||||
|
||||
@Repository
|
||||
@UseStringTemplateEngine
|
||||
@UseEnumStrategy(EnumStrategy.BY_ORDINAL)
|
||||
@RegisterConstructorMapper(Version.class)
|
||||
public interface VersionsApiDAO {
|
||||
|
||||
@UseEnumStrategy(EnumStrategy.BY_ORDINAL)
|
||||
@UseRowReducer(VersionReducer.class)
|
||||
@RegisterConstructorMapper(value = PluginDependency.class, prefix = "pd_")
|
||||
@KeyColumn("id")
|
||||
@SqlQuery("SELECT pv.id," +
|
||||
" pv.created_at," +
|
||||
" pv.created_at," +
|
||||
" pv.version_string," +
|
||||
" pv.visibility," +
|
||||
" pv.description," +
|
||||
" coalesce((SELECT sum(pvd.downloads) FROM project_versions_downloads pvd WHERE p.id = pvd.project_id AND pv.id = pvd.version_id), 0) vs_downloads," +
|
||||
" pv.file_name fi_name," +
|
||||
" pv.file_size fi_size_bytes," +
|
||||
" pv.hash fi_md5_hash," +
|
||||
" pv.external_url," +
|
||||
" u.name author," +
|
||||
" pv.review_state," +
|
||||
" exists(SELECT 1 FROM recommended_project_versions rpv WHERE rpv.version_id = pv.id) as recommended" +
|
||||
" FROM project_versions pv" +
|
||||
" JOIN projects p ON pv.project_id = p.id" +
|
||||
" LEFT JOIN users u ON pv.author_id = u.id" +
|
||||
" WHERE " +
|
||||
" <if(!canSeeHidden)>" +
|
||||
" (pv.visibility = 0 " +
|
||||
" <if(userId)>" +
|
||||
" OR (<userId> IN (SELECT pm.user_id FROM project_members_all pm WHERE pm.id = p.id) AND pv.visibility != 4) " +
|
||||
" <endif>)" +
|
||||
" AND" +
|
||||
" <endif>" +
|
||||
" pv.id = :versionId" +
|
||||
" ORDERED BY pv.created_at DESC"
|
||||
)
|
||||
Entry<Long, Version> getVersion(long versionId, @Define boolean canSeeHidden, @Define Long userId);
|
||||
|
||||
@KeyColumn("id")
|
||||
@SqlQuery("SELECT pv.id," +
|
||||
" pv.created_at," +
|
||||
" pv.version_string," +
|
||||
" pv.visibility," +
|
||||
" pv.description," +
|
||||
" coalesce((SELECT sum(pvd.downloads) FROM project_versions_downloads pvd WHERE p.id = pvd.project_id AND pv.id = pvd.version_id), 0) vs_downloads," +
|
||||
" pv.file_name fi_name," +
|
||||
" pv.file_size fi_size_bytes," +
|
||||
" pv.hash fi_md5_hash," +
|
||||
" pv.external_url," +
|
||||
" u.name author," +
|
||||
" pv.review_state," +
|
||||
" exists(SELECT 1 FROM recommended_project_versions rpv WHERE rpv.version_id = pv.id) as recommended" +
|
||||
" FROM project_versions pv" +
|
||||
" JOIN projects p ON pv.project_id = p.id" +
|
||||
" LEFT JOIN users u ON pv.author_id = u.id" +
|
||||
" WHERE " +
|
||||
" <if(!canSeeHidden)>" +
|
||||
" (pv.visibility = 0 " +
|
||||
" <if(userId)>" +
|
||||
" OR (<userId> IN (SELECT pm.user_id FROM project_members_all pm WHERE pm.id = p.id) AND pv.visibility != 4) " +
|
||||
" <endif>)" +
|
||||
" AND" +
|
||||
" <endif>" +
|
||||
" lower(p.owner_name) = lower(:author) AND" +
|
||||
" lower(p.slug) = lower(:slug) AND" +
|
||||
" pv.version_string = :versionString" +
|
||||
" ORDER BY pv.created_at DESC"
|
||||
)
|
||||
SortedMap<Long, Version> getVersionsWithVersionString(String author, String slug, String versionString, @Define boolean canSeeHidden, @Define Long userId);
|
||||
|
||||
@KeyColumn("id")
|
||||
@SqlQuery("SELECT pv.id," +
|
||||
" pv.created_at," +
|
||||
" pv.version_string," +
|
||||
" pv.visibility," +
|
||||
" pv.description," +
|
||||
" coalesce((SELECT sum(pvd.downloads) FROM project_versions_downloads pvd WHERE p.id = pvd.project_id AND pv.id = pvd.version_id), 0) vs_downloads," +
|
||||
" pv.file_name fi_name," +
|
||||
" pv.file_size fi_size_bytes," +
|
||||
" pv.hash fi_md5_hash," +
|
||||
" pv.external_url," +
|
||||
" u.name author," +
|
||||
" pv.review_state," +
|
||||
" exists(SELECT 1 FROM recommended_project_versions rpv WHERE rpv.version_id = pv.id) as recommended" +
|
||||
" FROM project_versions pv" +
|
||||
" JOIN projects p ON pv.project_id = p.id" +
|
||||
" LEFT JOIN users u ON pv.author_id = u.id" +
|
||||
" WHERE " +
|
||||
" <if(!canSeeHidden)>" +
|
||||
" (pv.visibility = 0 " +
|
||||
" <if(userId)>" +
|
||||
" OR (<userId> IN (SELECT pm.user_id FROM project_members_all pm WHERE pm.id = p.id) AND pv.visibility != 4) " +
|
||||
" <endif>)" +
|
||||
" AND" +
|
||||
" <endif>" +
|
||||
" lower(p.owner_name) = lower(:author) AND" +
|
||||
" lower(p.slug) = lower(:slug) " +
|
||||
// TODO tags
|
||||
/*" <if(tags)> AND (" +
|
||||
" pvt.name || ':' || pvt.data IN (<tags>) OR " +
|
||||
" pvt.name IN (<tags>) OR " +
|
||||
" 'Channel:' || pc.name IN (<tags>) OR " +
|
||||
" 'Channel' IN (<tags>)" +
|
||||
" )" +
|
||||
" <endif> " +*/
|
||||
" ORDER BY pv.created_at DESC LIMIT :limit OFFSET :offset"
|
||||
)
|
||||
SortedMap<Long, Version> getVersions(String author, String slug, @BindList(onEmpty = BindList.EmptyHandling.NULL_VALUE) List<String> tags, @Define boolean canSeeHidden, @Define Long userId, long limit, long offset);
|
||||
|
||||
@KeyColumn("platform")
|
||||
@SqlQuery("SELECT " +
|
||||
" pvd.name," +
|
||||
" pvd.required," +
|
||||
" pvd.external_url," +
|
||||
" p.owner_name pn_owner," +
|
||||
" p.slug pn_slug" +
|
||||
" FROM project_version_dependencies pvd" +
|
||||
" LEFT JOIN projects p ON pvd.project_id = p.id" +
|
||||
" WHERE pvd.version_id = :versionId AND pvd.platform = :platform")
|
||||
@RegisterConstructorMapper(PluginDependency.class)
|
||||
Set<PluginDependency> getPluginDependencies(long versionId, @EnumByOrdinal Platform platform);
|
||||
|
||||
@KeyColumn("platform")
|
||||
@ValueColumn("versions")
|
||||
@SqlQuery("SELECT" +
|
||||
" pv.platform," +
|
||||
" array_agg(pv.version ORDER BY pv.created_at) versions" +
|
||||
" FROM project_version_platform_dependencies pvpd " +
|
||||
" JOIN platform_versions pv ON pvpd.platform_version_id = pv.id" +
|
||||
" WHERE pvpd.version_id = :versionId" +
|
||||
" GROUP BY pv.platform")
|
||||
Map<Platform, SortedSet<String>> getPlatformDependencies(long versionId);
|
||||
|
||||
@SqlQuery("SELECT pvt.name, pvt.data, pvt.color FROM project_version_tags pvt WHERE pvt.version_id = :versionId")
|
||||
@RegisterRowMapper(TagMapper.class)
|
||||
Set<Tag> getVersionTags(long versionId);
|
||||
|
||||
/*@UseRowReducer(VersionReducer.class)
|
||||
@RegisterConstructorMapper(value = PluginDependency.class, prefix = "pd_")
|
||||
@UseStringTemplateEngine
|
||||
@SqlQuery("SELECT pv.created_at," +
|
||||
" pv.version_string," +
|
||||
" pv.visibility," +
|
||||
" pv.description," +
|
||||
@ -58,7 +185,8 @@ public interface VersionsApiDAO {
|
||||
" d.platform pd_platform," +
|
||||
" d.name pd_name," +
|
||||
" d.required pd_required," +
|
||||
" d.project_id pd_project_id," +
|
||||
" pdp.owner_name pd_owner," +
|
||||
" pdp.slug pd_slug," +
|
||||
" d.external_url pd_external_url," +
|
||||
" plv.platform p_platform," +
|
||||
" plv.version p_version," +
|
||||
@ -71,6 +199,7 @@ public interface VersionsApiDAO {
|
||||
" JOIN project_version_platform_dependencies pvpd ON pv.id = pvpd.version_id" +
|
||||
" JOIN platform_versions plv ON pvpd.platform_version_id = plv.id" +
|
||||
" LEFT JOIN project_version_dependencies d ON pv.id = d.version_id" +
|
||||
" LEFT JOIN projects pdp ON d.project_id = pdp.id" +
|
||||
" WHERE <if(!canSeeHidden)>(pv.visibility = 0 " +
|
||||
" <if(userId)>OR (<userId> IN (SELECT pm.user_id FROM project_members_all pm WHERE pm.id = p.id) AND pv.visibility != 4) <endif>) AND <endif> " +
|
||||
" plv.platform = :platform AND" +
|
||||
@ -78,13 +207,14 @@ public interface VersionsApiDAO {
|
||||
" lower(p.owner_name) = lower(:author) AND" +
|
||||
" lower(p.slug) = lower(:slug) AND" +
|
||||
" lower(pv.version_string) = lower(:versionString)" +
|
||||
" GROUP BY p.id, pv.id, u.id, pc.id, d.id, plv.id, pvt.id" +
|
||||
" GROUP BY p.id, pv.id, u.id, pc.id, d.id, plv.id, pvt.id, pdp.id" +
|
||||
" ORDER BY pv.created_at DESC")
|
||||
Version getVersion(String author, String slug, String versionString, @EnumByOrdinal Platform platform, @Define boolean canSeeHidden, @Define Long userId);
|
||||
|
||||
@UseEnumStrategy(EnumStrategy.BY_ORDINAL)
|
||||
@UseRowReducer(VersionReducer.class)
|
||||
@RegisterConstructorMapper(value = PluginDependency.class, prefix = "pd_")
|
||||
@UseStringTemplateEngine
|
||||
@SqlQuery("SELECT pv.id," +
|
||||
" pv.created_at," +
|
||||
" pv.version_string," +
|
||||
@ -106,7 +236,8 @@ public interface VersionsApiDAO {
|
||||
" d.platform pd_platform," +
|
||||
" d.name pd_name," +
|
||||
" d.required pd_required," +
|
||||
" d.project_id pd_project_id," +
|
||||
" pdp.owner_name pd_owner," +
|
||||
" pdp.slug pd_slug," +
|
||||
" d.external_url pd_external_url," +
|
||||
" plv.platform p_platform," +
|
||||
" plv.version p_version," +
|
||||
@ -119,51 +250,23 @@ public interface VersionsApiDAO {
|
||||
" JOIN project_version_platform_dependencies pvpd ON pv.id = pvpd.version_id" +
|
||||
" JOIN platform_versions plv ON pvpd.platform_version_id = plv.id" +
|
||||
" LEFT JOIN project_version_dependencies d ON pv.id = d.version_id" +
|
||||
" LEFT JOIN projects pdp ON d.project_id = pdp.id" +
|
||||
" WHERE <if(!canSeeHidden)>(pv.visibility = 0 " +
|
||||
" <if(userId)>OR (<userId> IN (SELECT pm.user_id FROM project_members_all pm WHERE pm.id = p.id) AND pv.visibility != 4) <endif>) AND <endif> " +
|
||||
" pvt.name IS NOT NULL AND" +
|
||||
" lower(p.owner_name) = lower(:author) AND" +
|
||||
" lower(p.slug) = lower(:slug) AND" +
|
||||
" lower(pv.version_string) = lower(:versionString)" +
|
||||
" GROUP BY p.id, pv.id, u.id, pc.id, d.id, plv.id, pvt.id" +
|
||||
" GROUP BY p.id, pv.id, u.id, pc.id, d.id, plv.id, pvt.id, pdp.id" +
|
||||
" ORDER BY pv.created_at DESC")
|
||||
List<Version> getVersions(String author, String slug, String versionString, @Define boolean canSeeHidden, @Define Long userId);
|
||||
|
||||
class VersionReducer implements LinkedHashMapRowReducer<Long, Version> {
|
||||
@Override
|
||||
public void accumulate(Map<Long, Version> container, RowView rowView) {
|
||||
final Version version = container.computeIfAbsent(rowView.getColumn("id", Long.class), id -> rowView.getRow(Version.class));
|
||||
VersionReducer._accumulateVersion(rowView, version.getPluginDependencies(), version.getPlatformDependencies(), version.getTags(), version);
|
||||
}
|
||||
|
||||
public static <T extends Version> void _accumulateVersion(RowView rowView, Map<Platform, Set<PluginDependency>> pluginDependencies, Map<Platform, Set<String>> platformDependencies, Set<Tag> tags, T version) { // What a mess really
|
||||
Platform pluginPlatform = rowView.getColumn("pd_platform", Platform.class);
|
||||
if (pluginPlatform != null) {
|
||||
pluginDependencies.computeIfAbsent(pluginPlatform, _pl -> new HashSet<>());
|
||||
pluginDependencies.get(pluginPlatform).add(rowView.getRow(PluginDependency.class));
|
||||
}
|
||||
|
||||
Platform platformPlatform = rowView.getColumn("p_platform", Platform.class);
|
||||
platformDependencies.computeIfAbsent(platformPlatform, _pl -> new HashSet<>());
|
||||
platformDependencies.get(platformPlatform).add(rowView.getColumn("p_version", String.class));
|
||||
|
||||
if (rowView.getColumn("ch_tag_name", String.class) != null) {
|
||||
tags.add(new Tag(rowView.getColumn("ch_tag_name", String.class), rowView.getColumn("ch_tag_data", String.class), new TagColor(null, rowView.getColumn("ch_tag_color", Color.class).getHex())));
|
||||
}
|
||||
|
||||
if (rowView.getColumn("tag_name", String.class) != null) {
|
||||
tags.add(new Tag(
|
||||
rowView.getColumn("tag_name", String.class),
|
||||
StringUtils.formatVersionNumbers(Arrays.asList(rowView.getColumn("tag_data", String[].class))),
|
||||
rowView.getColumn("tag_color", io.papermc.hangar.model.common.TagColor.class).toTagColor()
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@UseEnumStrategy(EnumStrategy.BY_ORDINAL)
|
||||
@UseRowReducer(VersionReducer.class)
|
||||
@RegisterConstructorMapper(value = PluginDependency.class, prefix = "pd_")
|
||||
@UseStringTemplateEngine
|
||||
@SqlQuery("SELECT pv.id," +
|
||||
" pv.created_at," +
|
||||
" pv.version_string," +
|
||||
@ -185,11 +288,13 @@ public interface VersionsApiDAO {
|
||||
" d.platform pd_platform," +
|
||||
" d.name pd_name," +
|
||||
" d.required pd_required," +
|
||||
" d.project_id pd_project_id," +
|
||||
" pdp.owner_name pd_owner," +
|
||||
" pdp.slug pd_slug," +
|
||||
" d.external_url pd_external_url," +
|
||||
" plv.platform p_platform," +
|
||||
" plv.version p_version," +
|
||||
" exists(SELECT 1 FROM recommended_project_versions rpv WHERE rpv.version_id = pv.id) as recommended" +
|
||||
" exists(SELECT 1 FROM recommended_project_versions rpv WHERE rpv.version_id = pv.id) as recommended," +
|
||||
" ru.name approved_by" +
|
||||
" FROM project_versions pv" +
|
||||
" JOIN projects p ON pv.project_id = p.id" +
|
||||
" LEFT JOIN users u ON pv.author_id = u.id" +
|
||||
@ -198,32 +303,35 @@ public interface VersionsApiDAO {
|
||||
" JOIN project_version_platform_dependencies pvpd ON pv.id = pvpd.version_id" +
|
||||
" JOIN platform_versions plv ON pvpd.platform_version_id = plv.id" +
|
||||
" LEFT JOIN project_version_dependencies d ON pv.id = d.version_id" +
|
||||
" LEFT JOIN projects pdp ON d.project_id = pdp.id" +
|
||||
" LEFT JOIN users ru ON pv.reviewer_id = ru.id" +
|
||||
" WHERE <if(!canSeeHidden)>(pv.visibility = 0 " +
|
||||
" <if(userId)>OR (<userId> IN (SELECT pm.user_id FROM project_members_all pm WHERE pm.id = p.id) AND pv.visibility != 4) <endif>) AND <endif> " +
|
||||
" pvt.name IS NOT NULL AND" +
|
||||
" lower(p.owner_name) = lower(:author) AND" +
|
||||
" lower(p.slug) = lower(:slug)" +
|
||||
" GROUP BY p.id, pv.id, u.id, pc.id, d.id, plv.id, pvt.id" +
|
||||
" GROUP BY p.id, pv.id, u.id, pc.id, d.id, plv.id, pvt.id, pdp.id, ru.id" +
|
||||
" ORDER BY pv.created_at DESC LIMIT :limit OFFSET :offset")
|
||||
List<Version> getVersions(String author, String slug, @BindList(onEmpty = BindList.EmptyHandling.NULL_VALUE) List<String> tags, @Define boolean canSeeHidden, @Define Long userId, long limit, long offset);
|
||||
List<Version> getVersions(String author, String slug, @BindList(onEmpty = BindList.EmptyHandling.NULL_VALUE) List<String> tags, @Define boolean canSeeHidden, @Define Long userId, long limit, long offset);*/
|
||||
|
||||
@SqlQuery("SELECT COUNT(*) " +
|
||||
"FROM projects p" +
|
||||
" JOIN project_versions pv ON p.id = pv.project_id" +
|
||||
" LEFT JOIN users u ON pv.author_id = u.id" +
|
||||
" LEFT JOIN project_version_tags pvt ON pv.id = pvt.version_id" +
|
||||
" LEFT JOIN project_channels pc ON pv.channel_id = pc.id " +
|
||||
" LEFT JOIN users u ON pv.author_id = u.id " +
|
||||
// " LEFT JOIN project_version_tags pvt ON pv.id = pvt.version_id" +
|
||||
// " LEFT JOIN project_channels pc ON pv.channel_id = pc.id " +
|
||||
"WHERE <if(!canSeeHidden)>(pv.visibility = 0 " +
|
||||
"<if(userId)>OR (<userId> IN (SELECT pm.user_id FROM project_members_all pm WHERE pm.id = p.id) AND pv.visibility != 4) <endif>) AND <endif> " +
|
||||
"p.slug = :slug AND " +
|
||||
"p.owner_name = :author <if(tags)> AND " +
|
||||
"lower(p.slug) = lower(:slug) AND " +
|
||||
"lower(p.owner_name) = lower(:author)" + /* <if(tags)> AND " +
|
||||
// TODO tags
|
||||
"(" +
|
||||
" pvt.name || ':' || pvt.data IN (<tags>) OR " +
|
||||
" pvt.name IN (<tags>) OR " +
|
||||
" 'Channel:' || pc.name IN (<tags>) OR " +
|
||||
" 'Channel' IN (<tags>)" +
|
||||
" )<endif> " +
|
||||
"GROUP BY p.id, pv.id, u.id, pc.id")
|
||||
" )<endif> " + */
|
||||
"GROUP BY p.id, pv.id, u.id")
|
||||
Long getVersionCount(String author, String slug, @BindList(onEmpty = BindList.EmptyHandling.NULL_VALUE) List<String> tags, @Define boolean canSeeHidden, @Define Long userId);
|
||||
|
||||
// TODO this might be totally screwed up by adding the platform check
|
||||
@ -242,4 +350,36 @@ public interface VersionsApiDAO {
|
||||
" AND plv.platform = :platform" +
|
||||
" AND (pvd IS NULL OR (pvd.project_id = p.id AND pvd.version_id = pv.id));")
|
||||
Map<String, VersionStats> getVersionStats(String author, String slug, String versionString, @EnumByOrdinal Platform platform, OffsetDateTime fromDate, OffsetDateTime toDate);
|
||||
|
||||
/*class VersionReducer implements LinkedHashMapRowReducer<Long, Version> {
|
||||
@Override
|
||||
public void accumulate(Map<Long, Version> container, RowView rowView) {
|
||||
final Version version = container.computeIfAbsent(rowView.getColumn("id", Long.class), id -> rowView.getRow(Version.class));
|
||||
VersionReducer._accumulateVersion(rowView, version);
|
||||
}
|
||||
|
||||
public static <T extends Version> void _accumulateVersion(RowView rowView, T version) { // What a mess really
|
||||
Platform pluginPlatform = rowView.getColumn("pd_platform", Platform.class);
|
||||
if (pluginPlatform != null) {
|
||||
version.getPluginDependencies().computeIfAbsent(pluginPlatform, _pl -> new HashSet<>());
|
||||
version.getPluginDependencies().get(pluginPlatform).add(rowView.getRow(PluginDependency.class));
|
||||
}
|
||||
|
||||
Platform platformPlatform = rowView.getColumn("p_platform", Platform.class);
|
||||
version.getPlatformDependencies().computeIfAbsent(platformPlatform, _pl -> new HashSet<>());
|
||||
version.getPlatformDependencies().get(platformPlatform).add(rowView.getColumn("p_version", String.class));
|
||||
|
||||
if (rowView.getColumn("ch_tag_name", String.class) != null) {
|
||||
version.getTags().add(new Tag(rowView.getColumn("ch_tag_name", String.class), rowView.getColumn("ch_tag_data", String.class), new TagColor(null, rowView.getColumn("ch_tag_color", Color.class).getHex())));
|
||||
}
|
||||
|
||||
if (rowView.getColumn("tag_name", String.class) != null) {
|
||||
version.getTags().add(new Tag(
|
||||
rowView.getColumn("tag_name", String.class),
|
||||
StringUtils.formatVersionNumbers(Arrays.asList(rowView.getColumn("tag_data", String[].class))),
|
||||
rowView.getColumn("tag_color", io.papermc.hangar.model.common.TagColor.class).toTagColor()
|
||||
));
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
22
src/main/java/io/papermc/hangar/db/mappers/TagMapper.java
Normal file
22
src/main/java/io/papermc/hangar/db/mappers/TagMapper.java
Normal file
@ -0,0 +1,22 @@
|
||||
package io.papermc.hangar.db.mappers;
|
||||
|
||||
import io.papermc.hangar.model.api.color.TagColor;
|
||||
import io.papermc.hangar.model.api.project.version.Tag;
|
||||
import io.papermc.hangar.util.StringUtils;
|
||||
import org.jdbi.v3.core.mapper.RowMapper;
|
||||
import org.jdbi.v3.core.statement.StatementContext;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class TagMapper implements RowMapper<Tag> {
|
||||
|
||||
@Override
|
||||
public Tag map(ResultSet rs, StatementContext ctx) throws SQLException {
|
||||
String name = rs.getString("name");
|
||||
String[] data = (String[]) rs.getArray("data").getArray();
|
||||
TagColor tagColor = io.papermc.hangar.model.common.TagColor.getValues()[rs.getInt("color")].toTagColor();
|
||||
return new Tag(name, data != null ? StringUtils.formatVersionNumbers(Arrays.asList(data)) : null, tagColor);
|
||||
}
|
||||
}
|
@ -1,11 +1,15 @@
|
||||
package io.papermc.hangar.model.api.project;
|
||||
|
||||
import org.jdbi.v3.core.mapper.PropagateNull;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class ProjectNamespace {
|
||||
|
||||
private final String owner;
|
||||
private final String slug;
|
||||
|
||||
public ProjectNamespace(String owner, String slug) {
|
||||
public ProjectNamespace(@PropagateNull String owner, String slug) {
|
||||
this.owner = owner;
|
||||
this.slug = slug;
|
||||
}
|
||||
@ -25,5 +29,18 @@ public class ProjectNamespace {
|
||||
", slug='" + slug + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
ProjectNamespace that = (ProjectNamespace) o;
|
||||
return owner.equals(that.owner) && slug.equals(that.slug);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(owner, slug);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,9 @@ package io.papermc.hangar.model.api.project.version;
|
||||
|
||||
import io.papermc.hangar.controller.validations.AtLeastOneNotNull;
|
||||
import io.papermc.hangar.model.Named;
|
||||
import io.papermc.hangar.model.api.project.ProjectNamespace;
|
||||
import org.jdbi.v3.core.mapper.Nested;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.util.Objects;
|
||||
@ -12,13 +15,13 @@ public class PluginDependency implements Named {
|
||||
@NotBlank(message = "Must have a dependency name")
|
||||
private final String name;
|
||||
private final boolean required;
|
||||
private final Long projectId;
|
||||
private final ProjectNamespace namespace;
|
||||
private final String externalUrl;
|
||||
|
||||
public PluginDependency(String name, boolean required, Long projectId, String externalUrl) {
|
||||
public PluginDependency(String name, boolean required, @Nested("pn") @Nullable ProjectNamespace namespace, String externalUrl) {
|
||||
this.name = name;
|
||||
this.required = required;
|
||||
this.projectId = projectId;
|
||||
this.namespace = namespace;
|
||||
this.externalUrl = externalUrl;
|
||||
}
|
||||
|
||||
@ -31,8 +34,9 @@ public class PluginDependency implements Named {
|
||||
return required;
|
||||
}
|
||||
|
||||
public Long getProjectId() {
|
||||
return projectId;
|
||||
@Nullable
|
||||
public ProjectNamespace getNamespace() {
|
||||
return namespace;
|
||||
}
|
||||
|
||||
public String getExternalUrl() {
|
||||
@ -44,7 +48,7 @@ public class PluginDependency implements Named {
|
||||
return "PluginDependency{" +
|
||||
"name='" + name + '\'' +
|
||||
", required=" + required +
|
||||
", projectId=" + projectId +
|
||||
", namespace=" + namespace +
|
||||
", externalUrl='" + externalUrl + '\'' +
|
||||
'}';
|
||||
}
|
||||
@ -54,11 +58,11 @@ public class PluginDependency implements Named {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
PluginDependency that = (PluginDependency) o;
|
||||
return required == that.required && name.equals(that.name) && Objects.equals(projectId, that.projectId) && Objects.equals(externalUrl, that.externalUrl);
|
||||
return required == that.required && name.equals(that.name) && Objects.equals(namespace, that.namespace) && Objects.equals(externalUrl, that.externalUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(name, required, projectId, externalUrl);
|
||||
return Objects.hash(name, required, namespace, externalUrl);
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
// TODO CompactVersion w/o dependencies for the version list page
|
||||
public class Version extends Model implements Named, Visible {
|
||||
|
||||
private final String name;
|
||||
|
@ -11,6 +11,7 @@ import io.papermc.hangar.model.common.Platform;
|
||||
import io.papermc.hangar.model.db.projects.ProjectChannelTable;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
@ -24,9 +25,8 @@ public class PendingVersion {
|
||||
@NotBlank(message = "version.new.error.invalidVersionString")
|
||||
@Validate(SpEL = "#root matches @hangarConfig.projects.versionNameRegex", message = "version.new.error.invalidVersionString")
|
||||
private final String versionString;
|
||||
// TODO validate below by uncommenting the @Valid annotation
|
||||
private final Map<Platform, Set</*@Valid */PluginDependency>> pluginDependencies;
|
||||
@Validate(SpEL = "#root.size lt 1 or #root.size gt T(io.papermc.hangar.model.common.Platform).getValues().length", message = "version.new.error.invalidNumOfPlatforms")
|
||||
private final Map<Platform, Set<@Valid PluginDependency>> pluginDependencies;
|
||||
@Size(min = 1, max = 3, message = "version.new.error.invalidNumOfPlatforms")
|
||||
private final Map<Platform, @Size(min = 1, message = "Empty platform version list") Set<@NotBlank(message = "version.new.error.invalidPlatformVersion") String>> platformDependencies;
|
||||
@NotBlank(message = "version.new.error.noDescription")
|
||||
private final String description;
|
||||
@ -64,7 +64,7 @@ public class PendingVersion {
|
||||
this.versionString = versionString;
|
||||
this.pluginDependencies = pluginDependencies;
|
||||
this.platformDependencies = platformDependencies;
|
||||
this.description = "## " + this.versionString + "\n\n" + description;
|
||||
this.description = "## " + this.versionString + (description != null ? "\n\n" + description : "");
|
||||
this.fileInfo = fileInfo;
|
||||
this.forumSync = forumSync;
|
||||
this.externalUrl = null;
|
||||
|
@ -10,7 +10,10 @@ import io.papermc.hangar.model.api.project.version.VersionStats;
|
||||
import io.papermc.hangar.model.api.requests.RequestPagination;
|
||||
import io.papermc.hangar.model.common.Permission;
|
||||
import io.papermc.hangar.model.common.Platform;
|
||||
import io.papermc.hangar.model.db.versions.ProjectVersionTable;
|
||||
import io.papermc.hangar.service.HangarService;
|
||||
import io.papermc.hangar.service.internal.versions.VersionDependencyService;
|
||||
import io.papermc.hangar.service.internal.versions.VersionService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -18,23 +21,33 @@ import org.springframework.stereotype.Service;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class VersionsApiService extends HangarService {
|
||||
|
||||
private final VersionsApiDAO versionsApiDAO;
|
||||
private final VersionService versionService;
|
||||
private final VersionDependencyService versionDependencyService;
|
||||
|
||||
@Autowired
|
||||
public VersionsApiService(HangarDao<VersionsApiDAO> versionsApiDAO) {
|
||||
public VersionsApiService(HangarDao<VersionsApiDAO> versionsApiDAO, VersionService versionService, VersionDependencyService versionDependencyService) {
|
||||
this.versionsApiDAO = versionsApiDAO.get();
|
||||
this.versionService = versionService;
|
||||
this.versionDependencyService = versionDependencyService;
|
||||
}
|
||||
|
||||
public Version getVersion(String author, String slug, String versionString, Platform platform) {
|
||||
return versionsApiDAO.getVersion(author, slug, versionString, platform, getGlobalPermissions().has(Permission.SeeHidden), getHangarUserId());
|
||||
ProjectVersionTable projectVersionTable = versionService.getProjectVersionTable(author, slug, versionString, platform);
|
||||
if (projectVersionTable == null) {
|
||||
throw new HangarApiException(HttpStatus.NOT_FOUND);
|
||||
}
|
||||
var entry = versionsApiDAO.getVersion(projectVersionTable.getId(), getGlobalPermissions().has(Permission.SeeHidden), getHangarUserId());
|
||||
return versionDependencyService.addDependenciesAndTags(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
public List<Version> getVersions(String author, String slug, String versionString) {
|
||||
List<Version> versions = versionsApiDAO.getVersions(author, slug, versionString, getGlobalPermissions().has(Permission.SeeHidden), getHangarUserId());
|
||||
List<Version> versions = versionsApiDAO.getVersionsWithVersionString(author, slug, versionString, getGlobalPermissions().has(Permission.SeeHidden), getHangarUserId()).entrySet().stream().map(entry -> versionDependencyService.addDependenciesAndTags(entry.getKey(), entry.getValue())).collect(Collectors.toList());
|
||||
if (versions.isEmpty()) {
|
||||
throw new HangarApiException(HttpStatus.NOT_FOUND);
|
||||
}
|
||||
@ -42,7 +55,7 @@ public class VersionsApiService extends HangarService {
|
||||
}
|
||||
|
||||
public PaginatedResult<Version> getVersions(String author, String slug, List<String> tags, RequestPagination pagination) {
|
||||
List<Version> versions = versionsApiDAO.getVersions(author, slug, tags, getGlobalPermissions().has(Permission.SeeHidden), getHangarUserId(), pagination.getLimit(), pagination.getOffset());
|
||||
List<Version> versions = versionsApiDAO.getVersions(author, slug, tags, getGlobalPermissions().has(Permission.SeeHidden), getHangarUserId(), pagination.getLimit(), pagination.getOffset()).entrySet().stream().map(entry -> versionDependencyService.addDependenciesAndTags(entry.getKey(), entry.getValue())).collect(Collectors.toList());
|
||||
Long versionCount = versionsApiDAO.getVersionCount(author, slug, tags, getGlobalPermissions().has(Permission.SeeHidden), getHangarUserId());
|
||||
return new PaginatedResult<>(new Pagination(versionCount == null ? 0 : versionCount, pagination), versions);
|
||||
}
|
||||
|
@ -49,6 +49,10 @@ public class ChannelService extends HangarService {
|
||||
return projectChannelsDAO.getProjectChannel(projectId, name, color);
|
||||
}
|
||||
|
||||
public ProjectChannelTable getProjectChannelForVersion(long versionId) {
|
||||
return projectChannelsDAO.getProjectChannelForVersion(versionId);
|
||||
}
|
||||
|
||||
public ProjectChannelTable getFirstChannel(long projectId) {
|
||||
return projectChannelsDAO.getFirstChannel(projectId);
|
||||
}
|
||||
|
@ -1,27 +1,37 @@
|
||||
package io.papermc.hangar.service.internal.versions;
|
||||
|
||||
import io.papermc.hangar.db.dao.HangarDao;
|
||||
import io.papermc.hangar.db.dao.internal.table.PlatformVersionDAO;
|
||||
import io.papermc.hangar.db.dao.internal.table.versions.ProjectVersionDependenciesDAO;
|
||||
import io.papermc.hangar.db.dao.internal.table.versions.ProjectVersionPlatformDependenciesDAO;
|
||||
import io.papermc.hangar.db.dao.v1.VersionsApiDAO;
|
||||
import io.papermc.hangar.model.api.color.TagColor;
|
||||
import io.papermc.hangar.model.api.project.version.PluginDependency;
|
||||
import io.papermc.hangar.model.api.project.version.Tag;
|
||||
import io.papermc.hangar.model.api.project.version.Version;
|
||||
import io.papermc.hangar.model.common.Platform;
|
||||
import io.papermc.hangar.model.db.projects.ProjectChannelTable;
|
||||
import io.papermc.hangar.model.db.versions.ProjectVersionDependencyTable;
|
||||
import io.papermc.hangar.model.db.versions.ProjectVersionPlatformDependencyTable;
|
||||
import io.papermc.hangar.service.HangarService;
|
||||
import io.papermc.hangar.service.internal.projects.ChannelService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Service
|
||||
public class VersionDependencyService extends HangarService {
|
||||
|
||||
private final ProjectVersionDependenciesDAO projectVersionDependenciesDAO;
|
||||
private final VersionsApiDAO versionsApiDAO;
|
||||
private final ProjectVersionPlatformDependenciesDAO projectVersionPlatformDependenciesDAO;
|
||||
private final PlatformVersionDAO platformVersionDAO;
|
||||
private final ChannelService channelService;
|
||||
|
||||
public VersionDependencyService(HangarDao<ProjectVersionDependenciesDAO> projectVersionDependencyDAO, HangarDao<ProjectVersionPlatformDependenciesDAO> projectVersionPlatformDependencyDAO, HangarDao<PlatformVersionDAO> platformVersionDAO) {
|
||||
public VersionDependencyService(HangarDao<ProjectVersionDependenciesDAO> projectVersionDependencyDAO, HangarDao<VersionsApiDAO> versionsApiDAO, HangarDao<ProjectVersionPlatformDependenciesDAO> projectVersionPlatformDependencyDAO, ChannelService channelService) {
|
||||
this.projectVersionDependenciesDAO = projectVersionDependencyDAO.get();
|
||||
this.versionsApiDAO = versionsApiDAO.get();
|
||||
this.projectVersionPlatformDependenciesDAO = projectVersionPlatformDependencyDAO.get();
|
||||
this.platformVersionDAO = platformVersionDAO.get();
|
||||
this.channelService = channelService;
|
||||
}
|
||||
|
||||
public List<ProjectVersionDependencyTable> getProjectVersionDependencyTables(long versionId) {
|
||||
@ -32,4 +42,18 @@ public class VersionDependencyService extends HangarService {
|
||||
return projectVersionPlatformDependenciesDAO.getForVersion(versionId);
|
||||
}
|
||||
|
||||
public <T extends Version> T addDependenciesAndTags(Long versionId, T version) {
|
||||
version.getPlatformDependencies().putAll(versionsApiDAO.getPlatformDependencies(versionId));
|
||||
for (Platform platform : Platform.getValues()) {
|
||||
Set<PluginDependency> pluginDependencySet = versionsApiDAO.getPluginDependencies(versionId, platform);
|
||||
if (!pluginDependencySet.isEmpty()) {
|
||||
version.getPluginDependencies().put(platform, pluginDependencySet);
|
||||
}
|
||||
}
|
||||
version.getTags().addAll(versionsApiDAO.getVersionTags(versionId));
|
||||
ProjectChannelTable projectChannelTable = channelService.getProjectChannelForVersion(versionId);
|
||||
version.getTags().add(new Tag("Channel", projectChannelTable.getName(), new TagColor(null, projectChannelTable.getColor().getHex())));
|
||||
return version;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
public class VersionFactory extends HangarService {
|
||||
@ -205,7 +206,15 @@ public class VersionFactory extends HangarService {
|
||||
List<ProjectVersionDependencyTable> pluginDependencyTables = new ArrayList<>();
|
||||
for (var platformListEntry : pendingVersion.getPluginDependencies().entrySet()) {
|
||||
for (PluginDependency pluginDependency : platformListEntry.getValue()) {
|
||||
pluginDependencyTables.add(new ProjectVersionDependencyTable(projectVersionTable.getId(), platformListEntry.getKey(), pluginDependency.getName(), pluginDependency.isRequired(), pluginDependency.getProjectId(), pluginDependency.getExternalUrl()));
|
||||
Long depProjectId = null;
|
||||
if (pluginDependency.getNamespace() != null) {
|
||||
Optional<ProjectTable> depProjectTable = Optional.ofNullable(projectService.getProjectTable(pluginDependency.getNamespace().getOwner(), pluginDependency.getNamespace().getSlug()));
|
||||
if (depProjectTable.isEmpty()) {
|
||||
throw new HangarApiException(HttpStatus.BAD_REQUEST, "version.new.error.invalidPluginDependencyNamespace");
|
||||
}
|
||||
depProjectId = depProjectTable.get().getProjectId();
|
||||
}
|
||||
pluginDependencyTables.add(new ProjectVersionDependencyTable(projectVersionTable.getId(), platformListEntry.getKey(), pluginDependency.getName(), pluginDependency.isRequired(), depProjectId, pluginDependency.getExternalUrl()));
|
||||
}
|
||||
}
|
||||
projectVersionDependenciesDAO.insertAll(pluginDependencyTables);
|
||||
|
@ -19,6 +19,7 @@ import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class VersionService extends HangarService {
|
||||
@ -26,12 +27,14 @@ public class VersionService extends HangarService {
|
||||
private final ProjectVersionsDAO projectVersionsDAO;
|
||||
private final HangarVersionsDAO hangarVersionsDAO;
|
||||
private final ProjectVersionVisibilityService projectVersionVisibilityService;
|
||||
private final VersionDependencyService versionDependencyService;
|
||||
|
||||
@Autowired
|
||||
public VersionService(HangarDao<ProjectVersionsDAO> projectVersionDAO, HangarDao<HangarVersionsDAO> hangarProjectsDAO, ProjectVersionVisibilityService projectVersionVisibilityService) {
|
||||
public VersionService(HangarDao<ProjectVersionsDAO> projectVersionDAO, HangarDao<HangarVersionsDAO> hangarProjectsDAO, ProjectVersionVisibilityService projectVersionVisibilityService, VersionDependencyService versionDependencyService) {
|
||||
this.projectVersionsDAO = projectVersionDAO.get();
|
||||
this.hangarVersionsDAO = hangarProjectsDAO.get();
|
||||
this.projectVersionVisibilityService = projectVersionVisibilityService;
|
||||
this.versionDependencyService = versionDependencyService;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@ -52,15 +55,20 @@ public class VersionService extends HangarService {
|
||||
}
|
||||
|
||||
public HangarVersion getHangarVersion(String author, String slug, String versionString, Platform platform) {
|
||||
return hangarVersionsDAO.getVersion(author, slug, versionString, platform, getGlobalPermissions().has(Permission.SeeHidden), getHangarUserId()).orElseThrow(() -> new HangarApiException(HttpStatus.NOT_FOUND));
|
||||
ProjectVersionTable projectVersionTable = getProjectVersionTable(author, slug, versionString, platform);
|
||||
if (projectVersionTable == null) {
|
||||
throw new HangarApiException(HttpStatus.NOT_FOUND);
|
||||
}
|
||||
HangarVersion hangarVersion = hangarVersionsDAO.getVersion(projectVersionTable.getId(), getGlobalPermissions().has(Permission.SeeHidden), getHangarUserId());
|
||||
return versionDependencyService.addDependenciesAndTags(hangarVersion.getId(), hangarVersion);
|
||||
}
|
||||
|
||||
public List<HangarVersion> getHangarVersions(String author, String slug, String versionString) {
|
||||
List<HangarVersion> versions = hangarVersionsDAO.getVersions(author, slug, versionString, getGlobalPermissions().has(Permission.SeeHidden), getHangarUserId());
|
||||
List<HangarVersion> versions = hangarVersionsDAO.getVersionsWithVersionString(author, slug, versionString, getGlobalPermissions().has(Permission.SeeHidden), getHangarUserId());
|
||||
if (versions.isEmpty()) {
|
||||
throw new HangarApiException(HttpStatus.NOT_FOUND);
|
||||
}
|
||||
return versions;
|
||||
return versions.stream().map(v -> versionDependencyService.addDependenciesAndTags(v.getId(), v)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public void addUnstableTag(long versionId) {
|
||||
|
@ -187,7 +187,7 @@ public class VersionService extends HangarService {
|
||||
} else {
|
||||
path = null;
|
||||
}
|
||||
dependencies.get(pvdt.getPlatform()).put(new PluginDependency(pvdt.getName(), pvdt.isRequired(), pvdt.getProjectId(), pvdt.getExternalUrl()), path);
|
||||
// dependencies.get(pvdt.getPlatform()).put(new PluginDependency(pvdt.getName(), pvdt.isRequired(), pvdt.getProjectId(), pvdt.getExternalUrl()), path);
|
||||
});
|
||||
if (true) throw new NotImplementedException();
|
||||
return new VersionData(
|
||||
|
Loading…
Reference in New Issue
Block a user