mirror of
https://github.com/HangarMC/Hangar.git
synced 2025-02-17 15:01:42 +08:00
whole bunch of random stuff
This commit is contained in:
parent
1964e5a470
commit
0b58c92390
@ -29,13 +29,13 @@
|
||||
<template #activator="{ on }">
|
||||
<v-btn icon to="/authors" nuxt class="mr-1" v-on="on"><v-icon>mdi-account-group</v-icon></v-btn>
|
||||
</template>
|
||||
<span>{{ $t('pages.authors') }}</span>
|
||||
<span>{{ $t('pages.authorsTitle') }}</span>
|
||||
</v-tooltip>
|
||||
<v-tooltip bottom>
|
||||
<template #activator="{ on }">
|
||||
<v-btn icon to="/staff" nuxt class="mr-1" v-on="on"><v-icon>mdi-account-tie</v-icon></v-btn>
|
||||
</template>
|
||||
<span>{{ $t('pages.staff') }}</span>
|
||||
<span>{{ $t('pages.staffTitle') }}</span>
|
||||
</v-tooltip>
|
||||
|
||||
<v-menu v-if="isLoggedIn" bottom offset-y transition="slide-y-transition" close-delay="100">
|
||||
|
@ -38,8 +38,14 @@ const msgs: LocaleMessageObject = {
|
||||
sponsoredBy: 'Sponsored by',
|
||||
},
|
||||
pages: {
|
||||
authors: 'Authors',
|
||||
staff: 'Staff',
|
||||
staffTitle: 'Staff',
|
||||
authorsTitle: 'Authors',
|
||||
headers: {
|
||||
username: 'Username',
|
||||
roles: 'Roles',
|
||||
joined: 'Joined',
|
||||
projects: 'Projects',
|
||||
},
|
||||
},
|
||||
nav: {
|
||||
login: 'Login',
|
||||
|
@ -24,11 +24,11 @@
|
||||
</v-btn>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-tabs v-model="selectedTab" vertical>
|
||||
<v-tab href="#general">{{ $t('project.settings.tabs.general') }}</v-tab>
|
||||
<v-tab href="#optional">{{ $t('project.settings.tabs.optional') }}</v-tab>
|
||||
<v-tab href="#management">{{ $t('project.settings.tabs.management') }}</v-tab>
|
||||
<v-tab href="#donation">{{ $t('project.settings.tabs.donation') }}</v-tab>
|
||||
<v-tabs vertical>
|
||||
<v-tab to="#general" replace nuxt>{{ $t('project.settings.tabs.general') }}</v-tab>
|
||||
<v-tab to="#optional" replace nuxt>{{ $t('project.settings.tabs.optional') }}</v-tab>
|
||||
<v-tab to="#management" replace nuxt>{{ $t('project.settings.tabs.management') }}</v-tab>
|
||||
<v-tab to="#donation" replace nuxt>{{ $t('project.settings.tabs.donation') }}</v-tab>
|
||||
|
||||
<v-tab-item id="general">
|
||||
<v-form v-model="validForm.settings">
|
||||
@ -132,6 +132,7 @@
|
||||
:rules="[$util.$vc.maxLength(validations.project.keywords.max)]"
|
||||
:delimiters="[' ', ',', '.']"
|
||||
:label="$t('project.new.step3.keywords')"
|
||||
append-icon=""
|
||||
prepend-inner-icon="mdi-file-word-box"
|
||||
/>
|
||||
</div>
|
||||
@ -420,20 +421,12 @@ export default class ProjectManagePage extends HangarProjectMixin {
|
||||
rename: false,
|
||||
};
|
||||
|
||||
selectedTab: string = '';
|
||||
|
||||
@Watch('$route.hash')
|
||||
onRouteTabChange(newVal: string) {
|
||||
this.selectedTab = newVal;
|
||||
}
|
||||
|
||||
@Watch('selectedTab')
|
||||
onSelectedTabChange(newVal: string) {
|
||||
history.pushState({}, '', this.$route.path + '#' + newVal);
|
||||
}
|
||||
|
||||
mounted() {
|
||||
this.selectedTab = this.$route.hash.substr(1) || 'general';
|
||||
if (!this.$route.hash) {
|
||||
this.$router.replace({
|
||||
hash: '#general',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
get settingsEqual() {
|
||||
@ -597,15 +590,12 @@ export default class ProjectManagePage extends HangarProjectMixin {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.settings-card {
|
||||
.v-text-field .v-text-field__details {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '~vuetify/src/styles/styles';
|
||||
.settings-card .v-text-field::v-deep .v-text-field__details {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
hr {
|
||||
margin-top: 6px;
|
||||
margin-bottom: 5px;
|
||||
@ -629,7 +619,7 @@ h2 {
|
||||
|
||||
.theme--dark {
|
||||
.sticky {
|
||||
background-color: #1e1e1e;
|
||||
background-color: map-get($material-dark, 'cards');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,10 +4,6 @@
|
||||
<ProjectList :projects="projects" />
|
||||
</v-col>
|
||||
<v-col cols="12" md="4">
|
||||
<!-- TODO project manager (for organizations) (so what this is, is accepting invites to other projects AS the organization, I don't think we really need to have that. You couldn't be able to invite organizations to other projects/organizations) -->
|
||||
<v-card v-if="user.isOrganization && $perms.canEditSubjectSettings">
|
||||
<v-card-title>Project Manager</v-card-title>
|
||||
</v-card>
|
||||
<template v-if="!user.isOrganization">
|
||||
<v-card>
|
||||
<v-card-title>{{ $t('author.orgs') }}</v-card-title>
|
||||
|
@ -37,18 +37,17 @@ import { UserListPage } from '~/components/mixins';
|
||||
components: { UserAvatar },
|
||||
})
|
||||
export default class AuthorsPage extends UserListPage {
|
||||
// TODO i18n for headers
|
||||
headers: DataTableHeader[] = [
|
||||
{ text: '', value: 'pic', sortable: false },
|
||||
{ text: 'Username', value: 'username' },
|
||||
{ text: 'Roles', value: 'roles', sortable: false },
|
||||
{ text: 'Joined', value: 'joinDate' },
|
||||
{ text: 'Projects', value: 'projectCount' },
|
||||
{ text: this.$t('pages.headers.username') as string, value: 'username' },
|
||||
{ text: this.$t('pages.headers.roles') as string, value: 'roles', sortable: false },
|
||||
{ text: this.$t('pages.headers.joined') as string, value: 'joinDate' },
|
||||
{ text: this.$t('pages.headers.projects') as string, value: 'projectCount' },
|
||||
];
|
||||
|
||||
head() {
|
||||
return {
|
||||
title: this.$t('pages.authors'),
|
||||
title: this.$t('pages.authorsTitle'),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,6 @@
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" md="6">
|
||||
<!-- todo custom rule to check if a name exist already -->
|
||||
<v-text-field
|
||||
v-model.trim="form.name"
|
||||
autofocus
|
||||
@ -203,7 +202,6 @@
|
||||
</v-container>
|
||||
</v-card>
|
||||
</StepperStepContent>
|
||||
<!-- TODO donation settings as a step as well -->
|
||||
<StepperStepContent
|
||||
:step="4"
|
||||
@back="step = 3"
|
||||
@ -273,6 +271,7 @@ export default class NewProjectPage extends HangarComponent {
|
||||
projectLoading = true;
|
||||
projectError = false;
|
||||
projectOwners!: ProjectOwner[];
|
||||
licences!: string[];
|
||||
error = null as string | null;
|
||||
form: NewProjectForm = {
|
||||
category: ProjectCategory.ADMIN_TOOLS,
|
||||
@ -305,14 +304,14 @@ export default class NewProjectPage extends HangarComponent {
|
||||
return this.step !== 2 || this.forms.step2;
|
||||
}
|
||||
|
||||
// TODO do we want to get those from the server? Jake: I think so, it'd be nice to admins to be able to configure default licenses, but not needed for MVP
|
||||
get licences() {
|
||||
return ['MIT', 'Apache 2.0', 'GPL', 'LGPL', '(custom)'];
|
||||
}
|
||||
|
||||
async asyncData({ $api }: Context) {
|
||||
async asyncData({ $api, $util }: Context) {
|
||||
const data = await Promise.all([$api.requestInternal('data/possibleOwners'), $api.requestInternal('data/licenses', false)]).catch(
|
||||
$util.handlePageRequestError
|
||||
);
|
||||
if (typeof data === 'undefined') return;
|
||||
return {
|
||||
projectOwners: await $api.requestInternal<ProjectOwner[]>('projects/possibleOwners'),
|
||||
licenses: data[0],
|
||||
projectOwners: data[1],
|
||||
};
|
||||
}
|
||||
|
||||
@ -321,7 +320,6 @@ export default class NewProjectPage extends HangarComponent {
|
||||
}
|
||||
|
||||
createProject() {
|
||||
console.log(this.form);
|
||||
this.$api
|
||||
.requestInternal<string>('projects/create', true, 'post', this.form)
|
||||
.then((url) => {
|
||||
@ -342,7 +340,6 @@ export default class NewProjectPage extends HangarComponent {
|
||||
this.projectError = false;
|
||||
}
|
||||
|
||||
// This is very useful. Prob should have a generalization of this that works elsewhere. I didn't make it a rule because it relies on other input (the ownerId)
|
||||
@Watch('form.name')
|
||||
onProjectNameChange(val: string) {
|
||||
if (!val) {
|
||||
|
@ -3,33 +3,39 @@
|
||||
<v-card>
|
||||
<v-card-title v-text="$t('organization.new.title')" />
|
||||
<v-card-subtitle>{{ $t('organization.new.text') }}</v-card-subtitle>
|
||||
<!--TODO error message if already at max orgs-->
|
||||
<v-card-text>
|
||||
<v-form v-model="validForm">
|
||||
<v-text-field
|
||||
v-model="form.name"
|
||||
class="mt-2"
|
||||
filled
|
||||
:loading="validateLoading"
|
||||
:label="$t('organization.new.name')"
|
||||
:rules="[
|
||||
$util.$vc.require($t('organization.new.name')),
|
||||
$util.$vc.regex($t('organization.new.name'), validations.org.regex),
|
||||
$util.$vc.minLength(validations.org.min),
|
||||
$util.$vc.maxLength(validations.org.max),
|
||||
]"
|
||||
:error-messages="nameErrorMessages"
|
||||
/>
|
||||
<v-divider />
|
||||
<MemberList ref="memberList" class="mt-7 elevation-5" no-save-btn :roles="roles" always-editing :search-filter="searchFilter" />
|
||||
</v-form>
|
||||
<template v-if="currentUser.headerData.organizationCount < 1">
|
||||
<v-card-text>
|
||||
<v-form v-model="validForm">
|
||||
<v-text-field
|
||||
v-model="form.name"
|
||||
class="mt-2"
|
||||
filled
|
||||
:loading="validateLoading"
|
||||
:label="$t('organization.new.name')"
|
||||
:rules="[
|
||||
$util.$vc.require($t('organization.new.name')),
|
||||
$util.$vc.regex($t('organization.new.name'), validations.org.regex),
|
||||
$util.$vc.minLength(validations.org.min),
|
||||
$util.$vc.maxLength(validations.org.max),
|
||||
]"
|
||||
:error-messages="nameErrorMessages"
|
||||
/>
|
||||
<v-divider />
|
||||
<MemberList ref="memberList" class="mt-7 elevation-5" no-save-btn :roles="roles" always-editing :search-filter="searchFilter" />
|
||||
</v-form>
|
||||
</v-card-text>
|
||||
<v-card-actions class="justify-end">
|
||||
<v-btn color="success" :disabled="!canCreate" :loading="loading" @click="create">
|
||||
<v-icon left>mdi-check</v-icon>
|
||||
{{ $t('form.memberList.create') }}
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</template>
|
||||
<v-card-text v-else>
|
||||
<v-alert type="warning">
|
||||
{{ $t('organization.new.error.tooManyOrgs', [validations.maxOrgCount]) }}
|
||||
</v-alert>
|
||||
</v-card-text>
|
||||
<v-card-actions class="justify-end">
|
||||
<v-btn color="success" :disabled="!canCreate" :loading="loading" @click="create">
|
||||
<v-icon left>mdi-check</v-icon>
|
||||
{{ $t('form.memberList.create') }}
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</template>
|
||||
|
@ -37,17 +37,16 @@ import { UserListPage } from '~/components/mixins';
|
||||
components: { UserAvatar },
|
||||
})
|
||||
export default class StaffPage extends UserListPage {
|
||||
// TODO i18n for headers
|
||||
headers: DataTableHeader[] = [
|
||||
{ text: '', value: 'pic', sortable: false },
|
||||
{ text: 'Username', value: 'username' },
|
||||
{ text: 'Roles', value: 'roles', sortable: false },
|
||||
{ text: 'Joined', value: 'joinDate' },
|
||||
{ text: this.$t('pages.headers.username') as string, value: 'username' },
|
||||
{ text: this.$t('pages.headers.roles') as string, value: 'roles', sortable: false },
|
||||
{ text: this.$t('pages.headers.joined') as string, value: 'joinDate' },
|
||||
];
|
||||
|
||||
head() {
|
||||
return {
|
||||
title: this.$t('pages.staff'),
|
||||
title: this.$t('pages.staffTitle'),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ public interface ActivityDAO {
|
||||
" FROM project_version_platform_dependencies pvpd " +
|
||||
" JOIN platform_versions plv ON pvpd.platform_version_id = plv.id" +
|
||||
" WHERE pv.id = pvpd.version_id" +
|
||||
" ORDER BY plv.platform" +
|
||||
" ) platforms" +
|
||||
" FROM project_version_reviews pvr" +
|
||||
" JOIN project_versions pv ON pvr.version_id = pv.id" +
|
||||
|
@ -66,7 +66,7 @@ public interface ProjectVersionsDAO {
|
||||
|
||||
@SingleValue
|
||||
@UseEnumStrategy(EnumStrategy.BY_ORDINAL)
|
||||
@SqlQuery("SELECT array_agg(DISTINCT plv.platform)" +
|
||||
@SqlQuery("SELECT array_agg(DISTINCT plv.platform ORDER BY plv.platform)" +
|
||||
" FROM project_versions pv" +
|
||||
" JOIN project_version_platform_dependencies pvpd ON pv.id = pvpd.version_id" +
|
||||
" JOIN platform_versions plv ON pvpd.platform_version_id = plv.id" +
|
||||
|
@ -3,14 +3,15 @@ package io.papermc.hangar.db.dao.internal.table.versions;
|
||||
import io.papermc.hangar.model.common.Platform;
|
||||
import io.papermc.hangar.model.db.versions.RecommendedProjectVersionTable;
|
||||
import org.jdbi.v3.core.enums.EnumByOrdinal;
|
||||
import org.jdbi.v3.sqlobject.config.KeyColumn;
|
||||
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.SqlQuery;
|
||||
import org.jdbi.v3.sqlobject.statement.SqlUpdate;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Repository
|
||||
public interface RecommendedProjectVersionsDAO {
|
||||
@ -22,6 +23,8 @@ public interface RecommendedProjectVersionsDAO {
|
||||
@SqlUpdate("DELETE FROM recommended_project_versions WHERE project_id = :projectId AND platform = :platform")
|
||||
void delete(long projectId, @EnumByOrdinal Platform platform);
|
||||
|
||||
@SqlQuery("SELECT platform, version_id FROM recommended_project_versions WHERE project_id = :projectId")
|
||||
List<Pair<Long, Long>> getRecommendedVersions(long projectId);
|
||||
@KeyColumn("platform")
|
||||
@ValueColumn("version_id")
|
||||
@SqlQuery("SELECT platform, version_id FROM recommended_project_versions WHERE project_id = :projectId ORDER BY platform")
|
||||
Map<Platform, Long> getRecommendedVersions(long projectId);
|
||||
}
|
||||
|
@ -60,6 +60,7 @@ public interface HangarReviewsDAO {
|
||||
" FROM project_version_platform_dependencies pvpd " +
|
||||
" JOIN platform_versions plv ON pvpd.platform_version_id = plv.id" +
|
||||
" WHERE pv.id = pvpd.version_id" +
|
||||
" ORDER BY plv.platform" +
|
||||
" ) platforms," +
|
||||
" pv.created_at version_created_at," +
|
||||
" coalesce(pvu.name, 'DELETED USER') version_author," +
|
||||
|
@ -29,7 +29,7 @@ public interface HangarVersionsDAO {
|
||||
" pv.external_url," +
|
||||
" u.name author," +
|
||||
" pv.review_state," +
|
||||
" array(SELECT DISTINCT rpv.platform FROM recommended_project_versions rpv WHERE rpv.version_id = pv.id) as recommended," +
|
||||
" array(SELECT DISTINCT rpv.platform FROM recommended_project_versions rpv WHERE rpv.version_id = pv.id ORDER BY rpv.platform) as recommended," +
|
||||
" ru.name approved_by" +
|
||||
" FROM project_versions pv" +
|
||||
" JOIN projects p ON pv.project_id = p.id" +
|
||||
@ -60,7 +60,7 @@ public interface HangarVersionsDAO {
|
||||
" pv.external_url," +
|
||||
" u.name author," +
|
||||
" pv.review_state," +
|
||||
" array(SELECT DISTINCT rpv.platform FROM recommended_project_versions rpv WHERE rpv.version_id = pv.id) as recommended," +
|
||||
" array(SELECT DISTINCT rpv.platform FROM recommended_project_versions rpv WHERE rpv.version_id = pv.id ORDER BY rpv.platform) as recommended," +
|
||||
" ru.name approved_by" +
|
||||
" FROM project_versions pv" +
|
||||
" JOIN projects p ON pv.project_id = p.id" +
|
||||
|
@ -46,7 +46,7 @@ public interface VersionsApiDAO {
|
||||
" pv.external_url," +
|
||||
" u.name author," +
|
||||
" pv.review_state," +
|
||||
" array(SELECT DISTINCT rpv.platform FROM recommended_project_versions rpv WHERE rpv.version_id = pv.id) as recommended" +
|
||||
" array(SELECT DISTINCT rpv.platform FROM recommended_project_versions rpv WHERE rpv.version_id = pv.id ORDER BY rpv.platform) 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" +
|
||||
@ -76,7 +76,7 @@ public interface VersionsApiDAO {
|
||||
" pv.external_url," +
|
||||
" u.name author," +
|
||||
" pv.review_state," +
|
||||
" array(SELECT DISTINCT rpv.platform FROM recommended_project_versions rpv WHERE rpv.version_id = pv.id) as recommended" +
|
||||
" array(SELECT DISTINCT rpv.platform FROM recommended_project_versions rpv WHERE rpv.version_id = pv.id ORDER BY rpv.platform) 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" +
|
||||
@ -108,7 +108,7 @@ public interface VersionsApiDAO {
|
||||
" pv.external_url," +
|
||||
" u.name author," +
|
||||
" pv.review_state," +
|
||||
" array(SELECT DISTINCT rpv.platform FROM recommended_project_versions rpv WHERE rpv.version_id = pv.id) as recommended" +
|
||||
" array(SELECT DISTINCT rpv.platform FROM recommended_project_versions rpv WHERE rpv.version_id = pv.id ORDER BY rpv.platform) as recommended" +
|
||||
" FROM project_versions pv" +
|
||||
" JOIN projects p ON pv.project_id = p.id" +
|
||||
" JOIN project_channels pc ON pv.channel_id = pc.id" +
|
||||
|
@ -12,6 +12,7 @@ import java.util.stream.Collectors;
|
||||
@EnumByOrdinal
|
||||
public enum Platform {
|
||||
|
||||
// NOTE: The order here should always be the order they are displayed whenever there is a list somewhere on the frontend
|
||||
PAPER("Paper", Category.SERVER, TagColor.PAPER, "https://papermc.io/downloads"),
|
||||
WATERFALL("Waterfall", Category.PROXY, TagColor.WATERFALL, "https://papermc.io/downloads#Waterfall"),
|
||||
VELOCITY("Velocity", Category.PROXY, TagColor.VELOCITY, "https://www.velocitypowered.com/downloads");
|
||||
|
@ -5,11 +5,10 @@ import io.papermc.hangar.db.dao.HangarDao;
|
||||
import io.papermc.hangar.db.dao.internal.table.versions.RecommendedProjectVersionsDAO;
|
||||
import io.papermc.hangar.model.common.Platform;
|
||||
import io.papermc.hangar.model.db.versions.RecommendedProjectVersionTable;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class RecommendedVersionService extends HangarComponent {
|
||||
@ -27,6 +26,6 @@ public class RecommendedVersionService extends HangarComponent {
|
||||
}
|
||||
|
||||
public Map<Platform, Long> getRecommendedVersions(long projectId) {
|
||||
return recommendedProjectVersionsDAO.getRecommendedVersions(projectId).stream().collect(Collectors.toMap(pair -> Platform.values()[pair.getKey().intValue()], Pair::getValue));
|
||||
return recommendedProjectVersionsDAO.getRecommendedVersions(projectId);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user