implement project flagging

This commit is contained in:
MiniDigger | Martin 2022-06-15 11:29:51 +02:00
parent 97a49e3886
commit ed404fc6bf
3 changed files with 75 additions and 1 deletions

View File

@ -0,0 +1,68 @@
<script lang="ts" setup>
import { useI18n } from "vue-i18n";
import Button from "~/components/design/Button.vue";
import Modal from "~/components/modals/Modal.vue";
import Tooltip from "~/components/design/Tooltip.vue";
import { useContext } from "vite-ssr/vue";
import { Project } from "hangar-api";
import { useRouter } from "vue-router";
import InputRadio from "~/components/ui/InputRadio.vue";
import { useBackendDataStore } from "~/store/backendData";
import { ref } from "vue";
import InputTextarea from "~/components/ui/InputTextarea.vue";
import { required } from "~/composables/useValidationHelpers";
import { useInternalApi } from "~/composables/useApi";
import { HangarProject } from "hangar-internal";
import { handleRequestError } from "~/composables/useErrorHandling";
import { AxiosError } from "axios";
import { useNotificationStore } from "~/store/notification";
const props = defineProps<{
project: HangarProject;
}>();
const i18n = useI18n();
const ctx = useContext();
const router = useRouter();
const backendData = useBackendDataStore();
const flagReason = ref<string>();
const flagComment = ref<string>();
async function submit(close: () => void) {
try {
await useInternalApi("flags/", true, "POST", {
projectId: props.project.id,
reason: flagReason.value,
comment: flagComment.value,
});
close();
useNotificationStore().success(i18n.t("project.flag.flagSend"));
await router.go(0);
} catch (e) {
handleRequestError(e as AxiosError, ctx, i18n);
}
}
</script>
<template>
<Modal :title="i18n.t('project.flag.flagProject', [project.name])">
<template #default="{ on }">
<InputRadio v-for="(reason, index) in backendData.flagReasons" :key="index" v-model="flagReason" :label="i18n.t(reason.title)" :value="reason.type" />
<div class="py-2"></div>
<InputTextarea v-model.trim="flagComment" rows="3" :rules="[required()]" :label="i18n.t('general.comment')" />
<Button button-type="secondary" class="mt-4" @click="on.click">{{ i18n.t("general.close") }}</Button>
<Button button-type="primary" class="mt-4 ml-2" @click="submit(on.click)">{{ i18n.t("general.submit") }}</Button>
</template>
<template #activator="{ on }">
<Tooltip>
<template #content> Flag </template>
<Button button-type="secondary" size="small" :disabled="project.userActions.flagged" v-on="on">
<IconMdiFlag />
<span class="w-0 overflow-hidden !m-0">0</span>
</Button>
</Tooltip>
</template>
</Modal>
</template>

View File

@ -13,6 +13,7 @@ import { useContext } from "vite-ssr/vue";
import Tooltip from "~/components/design/Tooltip.vue"; import Tooltip from "~/components/design/Tooltip.vue";
import { useAuthStore } from "~/store/auth"; import { useAuthStore } from "~/store/auth";
import { useNotificationStore } from "~/store/notification"; import { useNotificationStore } from "~/store/notification";
import FlagModal from "~/components/modals/FlagModal.vue";
const ctx = useContext(); const ctx = useContext();
const i18n = useI18n(); const i18n = useI18n();
@ -111,6 +112,8 @@ function toggleWatch() {
<span class="ml-2">{{ watchingCount }}</span> <span class="ml-2">{{ watchingCount }}</span>
</Button> </Button>
</Tooltip> </Tooltip>
<div class="px-1"></div>
<FlagModal :project="project" />
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,7 +1,7 @@
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { computed, ref } from "vue"; import { computed, ref } from "vue";
import { IPlatform, IProjectCategory, IPrompt, IVisibility, Color } from "hangar-internal"; import { IPlatform, IProjectCategory, IPrompt, IVisibility, Color, FlagReason } from "hangar-internal";
import { NamedPermission, Platform, ProjectCategory, Prompt } from "~/types/enums"; import { NamedPermission, Platform, ProjectCategory, Prompt } from "~/types/enums";
import { Announcement as AnnouncementObject, Announcement, IPermission, Role } from "hangar-api"; import { Announcement as AnnouncementObject, Announcement, IPermission, Role } from "hangar-api";
@ -45,6 +45,7 @@ export const useBackendDataStore = defineStore("backendData", () => {
const orgRoles = ref<Role[]>([]); const orgRoles = ref<Role[]>([]);
const projectRoles = ref<Role[]>([]); const projectRoles = ref<Role[]>([]);
const channelColors = ref<Color[]>([]); const channelColors = ref<Color[]>([]);
const flagReasons = ref<FlagReason[]>([]);
async function initBackendData() { async function initBackendData() {
try { try {
@ -85,6 +86,7 @@ export const useBackendDataStore = defineStore("backendData", () => {
fetchIfNeeded(async () => useInternalApi("data/orgRoles", false), orgRoles), fetchIfNeeded(async () => useInternalApi("data/orgRoles", false), orgRoles),
fetchIfNeeded(async () => useInternalApi("data/channelColors", false), channelColors), fetchIfNeeded(async () => useInternalApi("data/channelColors", false), channelColors),
fetchIfNeeded(async () => useInternalApi("data/projectRoles", false), projectRoles), fetchIfNeeded(async () => useInternalApi("data/projectRoles", false), projectRoles),
fetchIfNeeded(async () => useInternalApi("data/flagReasons", false), flagReasons),
]); ]);
} catch (e) { } catch (e) {
console.error("ERROR FETCHING BACKEND DATA"); console.error("ERROR FETCHING BACKEND DATA");
@ -112,6 +114,7 @@ export const useBackendDataStore = defineStore("backendData", () => {
orgRoles, orgRoles,
projectRoles, projectRoles,
channelColors, channelColors,
flagReasons,
initBackendData, initBackendData,
visibleCategories, visibleCategories,
visiblePlatforms, visiblePlatforms,