mirror of
https://github.com/HangarMC/Hangar.git
synced 2024-11-27 06:01:08 +08:00
platform versions admin
This commit is contained in:
parent
bb9d9f3933
commit
5069763e0b
@ -625,6 +625,7 @@ const msgs: LocaleMessageObject = {
|
||||
versions: 'Versions',
|
||||
addVersion: 'Add Version',
|
||||
saveChanges: 'Save Changes',
|
||||
success: 'Updated platform versions',
|
||||
},
|
||||
flagReview: {
|
||||
title: 'Flags',
|
||||
|
@ -3,35 +3,35 @@
|
||||
<v-card-title>{{ $t('platformVersions.title') }}</v-card-title>
|
||||
<v-card-text>
|
||||
<v-simple-table>
|
||||
<template #default>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-left">{{ $t('platformVersions.platform') }}</th>
|
||||
<th class="text-left">{{ $t('platformVersions.versions') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="platform in platforms" :key="platform.name">
|
||||
<td>{{ platform.name }}</td>
|
||||
<td>
|
||||
<v-combobox
|
||||
v-model="platform.possibleVersions"
|
||||
small-chips
|
||||
deletable-chips
|
||||
multiple
|
||||
dense
|
||||
hide-details
|
||||
filled
|
||||
:delimiters="[' ', ',', ';']"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</template>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-left">{{ $t('platformVersions.platform') }}</th>
|
||||
<th class="text-left">{{ $t('platformVersions.versions') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="platform in platforms" :key="platform.name">
|
||||
<td>{{ platform.name }}</td>
|
||||
<td>
|
||||
<v-combobox
|
||||
v-model="platform.possibleVersions"
|
||||
small-chips
|
||||
deletable-chips
|
||||
multiple
|
||||
dense
|
||||
hide-details
|
||||
filled
|
||||
:delimiters="[' ', ',', ';']"
|
||||
append-icon=""
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</v-simple-table>
|
||||
</v-card-text>
|
||||
<v-card-actions class="justify-end">
|
||||
<v-btn color="success" :loading="loading" @click="save">{{ $t('platformVersions.saveChanges') }}</v-btn>
|
||||
<v-btn text color="info" :disabled="!hasChanged" @click="reset">{{ $t('general.reset') }}</v-btn>
|
||||
<v-btn color="success" :loading="loading" :disabled="!hasChanged" @click="save">{{ $t('platformVersions.saveChanges') }}</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</template>
|
||||
@ -39,7 +39,8 @@
|
||||
<script lang="ts">
|
||||
import { Component } from 'nuxt-property-decorator';
|
||||
import { IPlatform } from 'hangar-internal';
|
||||
import { RootState } from '~/store';
|
||||
import { cloneDeep, isEqual } from 'lodash-es';
|
||||
import { Context } from '@nuxt/types';
|
||||
import { GlobalPermission } from '~/utils/perms';
|
||||
import { NamedPermission } from '~/types/enums';
|
||||
import { HangarComponent } from '~/components/mixins';
|
||||
@ -48,13 +49,39 @@ import { HangarComponent } from '~/components/mixins';
|
||||
@GlobalPermission(NamedPermission.MANUAL_VALUE_CHANGES)
|
||||
export default class AdminVersionsPage extends HangarComponent {
|
||||
loading = false;
|
||||
originalPlatforms!: IPlatform[];
|
||||
platforms!: IPlatform[];
|
||||
|
||||
get platforms(): IPlatform[] {
|
||||
return Array.from((this.$store.state as RootState).platforms.values());
|
||||
save() {
|
||||
this.loading = true;
|
||||
const data: { [key: string]: string[] } = {};
|
||||
this.platforms.forEach((pl) => {
|
||||
data[pl.enumName] = pl.possibleVersions;
|
||||
});
|
||||
this.$api
|
||||
.requestInternal('admin/platformVersions', true, 'post', data)
|
||||
.then(() => {
|
||||
this.$util.success(this.$t('platformVersions.success'));
|
||||
this.$nuxt.refresh();
|
||||
})
|
||||
.catch(this.$util.handleRequestError)
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
// todo send to server, sort versions (here or on server?)!
|
||||
save() {}
|
||||
reset() {
|
||||
this.platforms = cloneDeep(this.originalPlatforms);
|
||||
}
|
||||
|
||||
get hasChanged() {
|
||||
return !isEqual(this.platforms, this.originalPlatforms);
|
||||
}
|
||||
|
||||
async asyncData({ $api, $util }: Context) {
|
||||
const data = await $api.requestInternal<IPlatform[]>('data/platforms', false).catch<any>($util.handlePageRequestError);
|
||||
return { platforms: data, originalPlatforms: cloneDeep(data) };
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
@ -5,8 +5,10 @@
|
||||
<script lang="ts">
|
||||
import { Component } from 'nuxt-property-decorator';
|
||||
import { HangarComponent } from '~/components/mixins';
|
||||
import { NotLoggedIn } from '~/utils/perms';
|
||||
|
||||
@Component
|
||||
@NotLoggedIn
|
||||
export default class LoggedOutPage extends HangarComponent {}
|
||||
</script>
|
||||
|
||||
|
@ -12,6 +12,14 @@ const loggedInMiddleware = (code: number, msg?: string): Middleware => ({ store,
|
||||
}
|
||||
};
|
||||
|
||||
export function NotLoggedIn(constructor: Function) {
|
||||
addMiddleware(constructor, ({ store, redirect }) => {
|
||||
if (store.state.auth.authenticated) {
|
||||
redirect('/');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function LoggedIn(constructor: Function) {
|
||||
addMiddleware(constructor, loggedInMiddleware(401, 'You must be logged in to perform this action'));
|
||||
}
|
||||
|
@ -1,145 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<table class="table table-bordered">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
<th scope="col">Platform</th>
|
||||
<th scope="col"><i class="fas fa-tags"></i>Versions</th>
|
||||
<th scope="col"><i class="fas fa-plus"></i>Add Version</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="{ platform, versions } in data" :key="`${platform}-row`">
|
||||
<td>{{ platform }}</td>
|
||||
<td>
|
||||
<div class="platform-version" v-for="(v, index) in versions" :key="index">
|
||||
<span @click="removeVersion(versions, v)" style="cursor: pointer">
|
||||
<i class="fas fa-times" style="color: #bb0400"></i>
|
||||
</span>
|
||||
{{ v }}
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="input-group float-left">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">Version Identifier</span>
|
||||
</div>
|
||||
<label for="add-version-input" class="sr-only">Add Version</label>
|
||||
<input type="text" id="add-version-input" class="form-control" v-model="inputs[platform]" />
|
||||
<div class="input-group-append">
|
||||
<button type="button" class="btn btn-primary" @click="addVersion(platform)" :disabled="!inputs[platform]">
|
||||
<i class="fas fa-plus"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<button v-if="!loading" type="button" class="btn btn-success" @click="save" :disabled="!changesMade">
|
||||
<span class="glyphicon glyphicon-floppy-disk"></span>
|
||||
Save Changes
|
||||
</button>
|
||||
<div v-else>
|
||||
<i class="fas fa-spinner fa-spin"></i>
|
||||
<span>Loading projects for you...</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { difference, remove } from 'lodash-es';
|
||||
import axios from 'axios';
|
||||
|
||||
export default {
|
||||
name: 'PlatformVersionTable',
|
||||
props: {
|
||||
platforms: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
changesMade: false,
|
||||
data: [],
|
||||
inputs: {},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
addVersion(platform) {
|
||||
const versions = this.data.find((o) => o.platform === platform).versions;
|
||||
if (versions.indexOf(this.inputs[platform]) < 0) {
|
||||
versions.push(this.inputs[platform]);
|
||||
this.changesMade = true;
|
||||
}
|
||||
this.inputs[platform] = '';
|
||||
},
|
||||
removeVersion(versions, version) {
|
||||
remove(versions, (v) => v === version);
|
||||
this.changesMade = true;
|
||||
},
|
||||
save() {
|
||||
const additions = {};
|
||||
const removals = {};
|
||||
for (const platform in this.platforms) {
|
||||
const versions = this.data.find((o) => o.platform === platform.toLowerCase()).versions;
|
||||
additions[platform] = difference(versions, this.platforms[platform]);
|
||||
removals[platform] = difference(this.platforms[platform], versions);
|
||||
}
|
||||
let hasChanges = false;
|
||||
for (const platform in this.platforms) {
|
||||
if (additions[platform].length > 0 || removals[platform].length > 0) {
|
||||
hasChanges = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasChanges) {
|
||||
// NO actual changes
|
||||
return;
|
||||
}
|
||||
this.loading = true;
|
||||
axios
|
||||
.post('/admin/versions/', {
|
||||
additions,
|
||||
removals,
|
||||
})
|
||||
.then(() => {
|
||||
this.changesMade = false;
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
},
|
||||
created() {
|
||||
for (const platform in this.platforms) {
|
||||
this.inputs[platform] = '';
|
||||
this.data.push({
|
||||
platform: platform.toLowerCase(),
|
||||
versions: [...this.platforms[platform]],
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.table {
|
||||
th svg {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
tr th:first-child,
|
||||
tr td:first-child {
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
.platform-version {
|
||||
display: inline-block;
|
||||
padding: 1px 4px 0 4px;
|
||||
margin-right: 5px;
|
||||
background-color: #cdcdcd;
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,9 +0,0 @@
|
||||
import { createApp } from 'vue';
|
||||
import axios from 'axios';
|
||||
import PlatformVersionTable from '@/components/entrypoints/admin/PlatformVersionTable';
|
||||
|
||||
axios.defaults.headers.post[window.csrfInfo.headerName] = window.csrfInfo.token;
|
||||
|
||||
createApp(PlatformVersionTable, {
|
||||
platforms: window.PLATFORMS,
|
||||
}).mount('#platform-version-table');
|
@ -0,0 +1,36 @@
|
||||
package io.papermc.hangar.controller.internal;
|
||||
|
||||
import io.papermc.hangar.controller.HangarController;
|
||||
import io.papermc.hangar.model.common.NamedPermission;
|
||||
import io.papermc.hangar.model.internal.api.requests.admin.ChangePlatformVersionsForm;
|
||||
import io.papermc.hangar.security.annotations.permission.PermissionRequired;
|
||||
import io.papermc.hangar.service.internal.PlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/api/internal/admin")
|
||||
public class AdminController extends HangarController {
|
||||
|
||||
private final PlatformService platformService;
|
||||
|
||||
@Autowired
|
||||
public AdminController(PlatformService platformService) {
|
||||
this.platformService = platformService;
|
||||
}
|
||||
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
@PostMapping(path = "/platformVersions", consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
@PermissionRequired(perms = NamedPermission.MANUAL_VALUE_CHANGES)
|
||||
public void changePlatformVersions(@RequestBody @Valid ChangePlatformVersionsForm form) {
|
||||
platformService.updatePlatformVersions(form);
|
||||
}
|
||||
}
|
@ -19,7 +19,7 @@ import io.papermc.hangar.model.common.projects.Visibility;
|
||||
import io.papermc.hangar.model.common.roles.OrganizationRole;
|
||||
import io.papermc.hangar.model.common.roles.ProjectRole;
|
||||
import io.papermc.hangar.security.annotations.Anyone;
|
||||
import io.papermc.hangar.service.internal.projects.PlatformService;
|
||||
import io.papermc.hangar.service.internal.PlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
@ -1,21 +1,14 @@
|
||||
package io.papermc.hangar.controllerold;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.vladsch.flexmark.ext.admonition.AdmonitionExtension;
|
||||
import io.papermc.hangar.controllerold.forms.UserAdminForm;
|
||||
import io.papermc.hangar.db.customtypes.RoleCategory;
|
||||
import io.papermc.hangar.db.dao.HangarDao;
|
||||
import io.papermc.hangar.db.daoold.PlatformVersionsDao;
|
||||
import io.papermc.hangar.db.modelold.PlatformVersionsTable;
|
||||
import io.papermc.hangar.db.modelold.RoleTable;
|
||||
import io.papermc.hangar.db.modelold.Stats;
|
||||
import io.papermc.hangar.db.modelold.UserOrganizationRolesTable;
|
||||
import io.papermc.hangar.db.modelold.UserProjectRolesTable;
|
||||
import io.papermc.hangar.model.common.NamedPermission;
|
||||
import io.papermc.hangar.model.common.Permission;
|
||||
import io.papermc.hangar.model.common.Platform;
|
||||
import io.papermc.hangar.model.common.projects.Visibility;
|
||||
import io.papermc.hangar.model.internal.logs.HangarLoggedAction;
|
||||
import io.papermc.hangar.modelold.Role;
|
||||
@ -51,7 +44,6 @@ import java.time.LocalDate;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -59,7 +51,6 @@ import java.util.stream.Collectors;
|
||||
@Deprecated(forRemoval = true)
|
||||
public class ApplicationController extends HangarController {
|
||||
|
||||
private final HangarDao<PlatformVersionsDao> platformVersionsDao;
|
||||
private final UserService userService;
|
||||
private final ProjectService projectService;
|
||||
private final OrgService orgService;
|
||||
@ -67,20 +58,17 @@ public class ApplicationController extends HangarController {
|
||||
private final JobService jobService;
|
||||
private final StatsService statsService;
|
||||
private final RoleService roleService;
|
||||
private final ObjectMapper mapper;
|
||||
|
||||
private final Supplier<UserData> userData;
|
||||
|
||||
@Autowired
|
||||
public ApplicationController(HangarDao<PlatformVersionsDao> platformVersionsDao, UserService userService, ProjectService projectService, OrgService orgService, UserActionLogService userActionLogService, JobService jobService, StatsService statsService, RoleService roleService, ObjectMapper mapper, Supplier<UserData> userData) {
|
||||
this.platformVersionsDao = platformVersionsDao;
|
||||
public ApplicationController(UserService userService, ProjectService projectService, OrgService orgService, UserActionLogService userActionLogService, JobService jobService, StatsService statsService, RoleService roleService, Supplier<UserData> userData) {
|
||||
this.userService = userService;
|
||||
this.projectService = projectService;
|
||||
this.orgService = orgService;
|
||||
this.userActionLogService = userActionLogService;
|
||||
this.jobService = jobService;
|
||||
this.roleService = roleService;
|
||||
this.mapper = mapper;
|
||||
this.statsService = statsService;
|
||||
this.userData = userData;
|
||||
}
|
||||
@ -173,40 +161,6 @@ public class ApplicationController extends HangarController {
|
||||
return fillModel(mav);
|
||||
}
|
||||
|
||||
@GlobalPermission(NamedPermission.MANUAL_VALUE_CHANGES)
|
||||
@Secured("ROLE_USER")
|
||||
@GetMapping("/admin/versions")
|
||||
public ModelAndView showPlatformVersions() {
|
||||
ModelAndView mav = new ModelAndView("users/admin/platformVersions");
|
||||
Map<Platform, List<String>> versions = platformVersionsDao.get().getVersions();
|
||||
for (Platform p : Platform.getValues()) {
|
||||
versions.putIfAbsent(p, new ArrayList<>());
|
||||
}
|
||||
mav.addObject("platformVersions", mapper.valueToTree(versions));
|
||||
return fillModel(mav);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@GlobalPermission(NamedPermission.MANUAL_VALUE_CHANGES)
|
||||
@Secured("ROLE_USER")
|
||||
@PostMapping("/admin/versions/")
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public void updatePlatformVersions(@RequestBody ObjectNode object) {
|
||||
Map<String, List<String>> additions;
|
||||
Map<String, List<String>> removals;
|
||||
try {
|
||||
additions = mapper.treeToValue(object.get("additions"), (Class<Map<String, List<String>>>) (Class) Map.class);
|
||||
removals = mapper.treeToValue(object.get("removals"), (Class<Map<String, List<String>>>) (Class) Map.class);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Bad formatting", e);
|
||||
}
|
||||
if (additions == null || removals == null) {
|
||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Bad formatting");
|
||||
}
|
||||
additions.forEach((platform, versions) -> platformVersionsDao.get().insert(versions.stream().map(v -> new PlatformVersionsTable(Platform.valueOf(platform), v)).collect(Collectors.toList())));
|
||||
removals.forEach((platform, versions) -> platformVersionsDao.get().delete(versions, Platform.valueOf(platform).ordinal()));
|
||||
}
|
||||
|
||||
@GlobalPermission(NamedPermission.EDIT_ALL_USER_SETTINGS)
|
||||
@Secured("ROLE_USER")
|
||||
@GetMapping("/admin/user/{user}")
|
||||
|
@ -16,6 +16,7 @@ import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
@Repository
|
||||
@ -25,7 +26,10 @@ public interface PlatformVersionDAO {
|
||||
|
||||
@Timestamped
|
||||
@SqlBatch("INSERT INTO platform_versions (created_at, platform, version) VALUES (:now, :platform, :version)")
|
||||
void insert(@BindBean Collection<PlatformVersionTable> platformVersionTables);
|
||||
void insertAll(@BindBean Collection<PlatformVersionTable> platformVersionTables);
|
||||
|
||||
@SqlBatch("DELETE FROM platform_versions WHERE id = :id")
|
||||
void deleteAll(@BindBean Collection<PlatformVersionTable> platformVersionTables);
|
||||
|
||||
@SqlQuery("SELECT * FROM platform_versions WHERE version = :version AND platform = :platform")
|
||||
PlatformVersionTable getByPlatformAndVersion(@EnumByOrdinal Platform platform, String version);
|
||||
@ -45,6 +49,7 @@ public interface PlatformVersionDAO {
|
||||
" WHERE p.version_string = :versionString AND p.project_id = :projectId")
|
||||
List<PlatformVersionTable> getPlatformsForVersionString(long projectId, String versionString);
|
||||
|
||||
// TODO
|
||||
// Map<Platform, List<PlatformVersionTable>> getPlatformVersionsForVersion(long versionId);
|
||||
@KeyColumn("version")
|
||||
@SqlQuery("SELECT * FROM platform_versions WHERE platform = :platform")
|
||||
Map<String, PlatformVersionTable> getForPlatform(@EnumByOrdinal Platform platform);
|
||||
}
|
||||
|
@ -1,48 +1,14 @@
|
||||
package io.papermc.hangar.db.daoold;
|
||||
|
||||
import io.papermc.hangar.db.modelold.PlatformVersionsTable;
|
||||
import io.papermc.hangar.model.common.Platform;
|
||||
import org.jdbi.v3.core.enums.EnumByOrdinal;
|
||||
import org.jdbi.v3.core.enums.EnumStrategy;
|
||||
import org.jdbi.v3.sqlobject.config.KeyColumn;
|
||||
import org.jdbi.v3.sqlobject.config.RegisterBeanMapper;
|
||||
import org.jdbi.v3.sqlobject.config.UseEnumStrategy;
|
||||
import org.jdbi.v3.sqlobject.config.ValueColumn;
|
||||
import org.jdbi.v3.sqlobject.customizer.BindBean;
|
||||
import org.jdbi.v3.sqlobject.customizer.Timestamped;
|
||||
import org.jdbi.v3.sqlobject.statement.SqlBatch;
|
||||
import org.jdbi.v3.sqlobject.statement.SqlQuery;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.TreeMap;
|
||||
|
||||
@Repository
|
||||
@RegisterBeanMapper(PlatformVersionsTable.class)
|
||||
@Deprecated(forRemoval = true)
|
||||
public interface PlatformVersionsDao {
|
||||
|
||||
@Timestamped
|
||||
@SqlBatch("INSERT INTO platform_versions (created_at, platform, version) VALUES (:now, :platform, :version)")
|
||||
void insert(@BindBean Collection<PlatformVersionsTable> platformVersionsTableCollection);
|
||||
|
||||
@SqlBatch("DELETE FROM platform_versions WHERE version = :version AND platform = :platform")
|
||||
void delete(List<String> version, int platform);
|
||||
|
||||
@KeyColumn("platform")
|
||||
@ValueColumn("versions")
|
||||
@UseEnumStrategy(EnumStrategy.BY_ORDINAL)
|
||||
@SqlQuery("SELECT platform, (array_agg(version ORDER BY string_to_array(version, '.')::INT[])) versions FROM platform_versions GROUP BY platform")
|
||||
TreeMap<Platform, List<String>> getVersions();
|
||||
|
||||
@SqlQuery("SELECT version FROM platform_versions WHERE platform = :platform ORDER BY string_to_array(version, '.')::INT[]")
|
||||
List<String> getVersionsForPlatform(int platform);
|
||||
|
||||
@SqlQuery("SELECT * FROM platform_versions WHERE platform = :platform")
|
||||
List<PlatformVersionsTable> getVersionsForPlatform(@EnumByOrdinal io.papermc.hangar.modelold.Platform platform);
|
||||
|
||||
@SqlQuery("SELECT pv.* FROM project_version_platform_dependencies pvpd JOIN platform_versions pv ON pv.id = pvpd.platform_version_id WHERE pvpd.version_id = :versionId")
|
||||
List<PlatformVersionsTable> getPlatformVersionsForVersion(long versionId);
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,15 @@
|
||||
package io.papermc.hangar.model.internal.api.requests.admin;
|
||||
|
||||
import io.papermc.hangar.model.common.Platform;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
|
||||
public class ChangePlatformVersionsForm extends EnumMap<Platform, @Size(min = 1) List<@NotBlank String>> {
|
||||
|
||||
public ChangePlatformVersionsForm() {
|
||||
super(Platform.class);
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package io.papermc.hangar.service.internal;
|
||||
|
||||
import io.papermc.hangar.db.dao.HangarDao;
|
||||
import io.papermc.hangar.db.dao.internal.table.PlatformVersionDAO;
|
||||
import io.papermc.hangar.model.common.Platform;
|
||||
import io.papermc.hangar.model.db.PlatformVersionTable;
|
||||
import io.papermc.hangar.service.HangarService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
public class PlatformService extends HangarService {
|
||||
|
||||
private final PlatformVersionDAO platformVersionDAO;
|
||||
|
||||
@Autowired
|
||||
public PlatformService(HangarDao<PlatformVersionDAO> platformVersionDAO) {
|
||||
this.platformVersionDAO = platformVersionDAO.get();
|
||||
}
|
||||
|
||||
public List<String> getVersionsForPlatform(Platform platform) {
|
||||
return platformVersionDAO.getVersionsForPlatform(platform);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void updatePlatformVersions(Map<Platform, List<String>> platformVersions) {
|
||||
final Map<Platform, Map<String, PlatformVersionTable>> toBeRemovedMap = new EnumMap<>(Platform.class);
|
||||
final Map<Platform, Map<String, PlatformVersionTable>> toBeAddedMap = new EnumMap<>(Platform.class);
|
||||
platformVersions.forEach((platform, versions) -> {
|
||||
Map<String, PlatformVersionTable> platformVersionTables = platformVersionDAO.getForPlatform(platform);
|
||||
final Map<String, PlatformVersionTable> toBeRemoved = new HashMap<>();
|
||||
final Map<String, PlatformVersionTable> toBeAdded = new HashMap<>();
|
||||
platformVersionTables.forEach((version, pvt) -> {
|
||||
if (!versions.contains(version)) {
|
||||
toBeRemoved.put(version, pvt);
|
||||
}
|
||||
});
|
||||
versions.forEach(v -> {
|
||||
if (!platformVersionTables.containsKey(v)) {
|
||||
toBeAdded.put(v, new PlatformVersionTable(platform, v));
|
||||
}
|
||||
});
|
||||
platformVersionDAO.deleteAll(toBeRemoved.values());
|
||||
platformVersionDAO.insertAll(toBeAdded.values());
|
||||
toBeRemovedMap.put(platform, toBeRemoved);
|
||||
toBeAddedMap.put(platform, toBeAdded);
|
||||
});
|
||||
// TODO logging
|
||||
}
|
||||
}
|
@ -65,9 +65,9 @@ public class PopulationService {
|
||||
Map<Platform, List<String>> platformVersions = platformVersionDAO.getVersions();
|
||||
if (platformVersions.isEmpty()) {
|
||||
log.info("Populating 'platform_versions' table with initial values");
|
||||
platformVersionDAO.insert(paperVersions.stream().map(v -> new PlatformVersionTable(Platform.PAPER, v)).collect(Collectors.toList()));
|
||||
platformVersionDAO.insert(velocityVersions.stream().map(v -> new PlatformVersionTable(Platform.VELOCITY, v)).collect(Collectors.toList()));
|
||||
platformVersionDAO.insert(waterfallVersions.stream().map(v -> new PlatformVersionTable(Platform.WATERFALL, v)).collect(Collectors.toList()));
|
||||
platformVersionDAO.insertAll(paperVersions.stream().map(v -> new PlatformVersionTable(Platform.PAPER, v)).collect(Collectors.toList()));
|
||||
platformVersionDAO.insertAll(velocityVersions.stream().map(v -> new PlatformVersionTable(Platform.VELOCITY, v)).collect(Collectors.toList()));
|
||||
platformVersionDAO.insertAll(waterfallVersions.stream().map(v -> new PlatformVersionTable(Platform.WATERFALL, v)).collect(Collectors.toList()));
|
||||
} else {
|
||||
log.info("The 'platform_versions' table is already populated");
|
||||
}
|
||||
|
@ -1,25 +0,0 @@
|
||||
package io.papermc.hangar.service.internal.projects;
|
||||
|
||||
import io.papermc.hangar.db.dao.HangarDao;
|
||||
import io.papermc.hangar.db.dao.internal.table.PlatformVersionDAO;
|
||||
import io.papermc.hangar.model.common.Platform;
|
||||
import io.papermc.hangar.service.HangarService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class PlatformService extends HangarService {
|
||||
|
||||
private final PlatformVersionDAO platformVersionDAO;
|
||||
|
||||
@Autowired
|
||||
public PlatformService(HangarDao<PlatformVersionDAO> platformVersionDAO) {
|
||||
this.platformVersionDAO = platformVersionDAO.get();
|
||||
}
|
||||
|
||||
public List<String> getVersionsForPlatform(Platform platform) {
|
||||
return platformVersionDAO.getVersionsForPlatform(platform);
|
||||
}
|
||||
}
|
@ -118,6 +118,7 @@ public class VersionDependencyService extends HangarService {
|
||||
versionTagService.updateTag(projectVersionTagTable);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void updateVersionPluginDependencies(long projectId, long versionId, UpdatePluginDependencies form) {
|
||||
Map<String, ProjectVersionDependencyTable> projectVersionDependencies = projectVersionDependenciesDAO.getForVersionAndPlatform(versionId, form.getPlatform());
|
||||
final Set<ProjectVersionDependencyTable> toBeRemoved = new HashSet<>();
|
||||
|
@ -23,8 +23,8 @@ import io.papermc.hangar.model.internal.logs.contexts.VersionContext;
|
||||
import io.papermc.hangar.model.internal.versions.PendingVersion;
|
||||
import io.papermc.hangar.service.HangarService;
|
||||
import io.papermc.hangar.service.api.UsersApiService;
|
||||
import io.papermc.hangar.service.internal.PlatformService;
|
||||
import io.papermc.hangar.service.internal.projects.ChannelService;
|
||||
import io.papermc.hangar.service.internal.projects.PlatformService;
|
||||
import io.papermc.hangar.service.internal.projects.ProjectService;
|
||||
import io.papermc.hangar.service.internal.uploads.ProjectFiles;
|
||||
import io.papermc.hangar.service.internal.users.NotificationService;
|
||||
|
@ -1,20 +0,0 @@
|
||||
<#import "/spring.ftl" as spring />
|
||||
<#import "*/utils/hangar.ftlh" as hangar />
|
||||
<#import "*/utils/form.ftlh" as form />
|
||||
<#import "*/utils/csrf.ftlh" as csrf />
|
||||
<#import "*/layout/base.ftlh" as base />
|
||||
|
||||
<#assign scriptsVar>
|
||||
<link rel="stylesheet" href="${hangar.url("css/platform-version-table.css")}">
|
||||
<script nonce="${nonce}">
|
||||
<#outputformat "JavaScript">
|
||||
window.PLATFORMS = ${platformVersions}
|
||||
</#outputformat>
|
||||
</script>
|
||||
<script type="text/javascript" src="${hangar.url("js/platform-version-table.js")}"></script>
|
||||
</#assign>
|
||||
|
||||
<#assign message><@spring.message "admin.platformVersions.title" /></#assign>
|
||||
<@base.base title="${message}" additionalScripts=scriptsVar>
|
||||
<div id="platform-version-table"></div>
|
||||
</@base.base>
|
Loading…
Reference in New Issue
Block a user