feat(submissions): sync scopes admin from token
This commit is contained in:
@@ -3,9 +3,10 @@ import { computed, onMounted, ref } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useTitle } from "@vueuse/core";
|
||||
import { submissionsApiListAvailableScopes } from "@/api";
|
||||
import { submissionsApiListAvailableScopes, submissionsApiSyncScopes } from "@/api";
|
||||
import { useQueryClient } from "@tanstack/vue-query";
|
||||
import { eventGamesQuery } from "@/queries";
|
||||
import { eventGamesQuery, userQuery } from "@/queries";
|
||||
import { useUser } from "@/composables/useUser";
|
||||
import type { ScopeOut } from "@/api/types.gen";
|
||||
|
||||
interface Props {
|
||||
@@ -18,6 +19,7 @@ const props = defineProps<Props>();
|
||||
const router = useRouter();
|
||||
const queryClient = useQueryClient();
|
||||
const { t } = useI18n();
|
||||
const userInfo = useUser();
|
||||
useTitle(computed(() => t("submissionsSelect.title")));
|
||||
|
||||
const gameName = ref("");
|
||||
@@ -25,6 +27,11 @@ const scopes = ref<ScopeOut[]>([]);
|
||||
const loading = ref(true);
|
||||
const notAssigned = ref(false);
|
||||
|
||||
const syncing = ref(false);
|
||||
const syncMessage = ref<{ type: "success" | "info" | "error"; text: string } | null>(null);
|
||||
const isTokenModalOpen = ref(false);
|
||||
const apibotToken = ref("");
|
||||
|
||||
const scopeRoute = (scope: ScopeOut) => ({
|
||||
name: "submissions",
|
||||
params: { eventPath: props.eventPath, gamePath: props.gamePath, scopeId: scope.id },
|
||||
@@ -34,12 +41,46 @@ const goToScope = (scope: ScopeOut) => {
|
||||
router.push(scopeRoute(scope));
|
||||
};
|
||||
|
||||
const syncScopes = async (token?: string) => {
|
||||
syncing.value = true;
|
||||
syncMessage.value = null;
|
||||
|
||||
const { data, error } = await submissionsApiSyncScopes({
|
||||
path: { event_path: props.eventPath, game_path: props.gamePath },
|
||||
body: { apibot_token: token ?? null },
|
||||
});
|
||||
|
||||
syncing.value = false;
|
||||
|
||||
if (error?.token_required) {
|
||||
isTokenModalOpen.value = true;
|
||||
return;
|
||||
}
|
||||
|
||||
isTokenModalOpen.value = false;
|
||||
apibotToken.value = "";
|
||||
|
||||
if (!data) {
|
||||
syncMessage.value = { type: "error", text: t("submissionsSelect.syncFailed") };
|
||||
} else if (data.started) {
|
||||
syncMessage.value = { type: "success", text: t("submissionsSelect.syncStarted") };
|
||||
} else {
|
||||
syncMessage.value = { type: "info", text: t("submissionsSelect.syncAlreadyRunning") };
|
||||
}
|
||||
};
|
||||
|
||||
const closeTokenModal = () => {
|
||||
isTokenModalOpen.value = false;
|
||||
apibotToken.value = "";
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
const [games, scopesResponse] = await Promise.all([
|
||||
const [games, scopesResponse, user] = await Promise.all([
|
||||
queryClient.ensureQueryData(eventGamesQuery(props.eventPath)),
|
||||
submissionsApiListAvailableScopes({
|
||||
path: { event_path: props.eventPath, game_path: props.gamePath },
|
||||
}),
|
||||
queryClient.ensureQueryData(userQuery()),
|
||||
]);
|
||||
|
||||
gameName.value = games.find((game) => game.path === props.gamePath)?.name ?? "";
|
||||
@@ -48,7 +89,8 @@ onMounted(async () => {
|
||||
|
||||
// Mirrors the server-side behavior this replaced: skip the picker
|
||||
// straight to the only option, or bounce out if there's nothing to pick.
|
||||
if (availableScopes.length === 1) {
|
||||
// Superusers always land here, it's where the scope sync button lives.
|
||||
if (availableScopes.length === 1 && !user.is_superuser) {
|
||||
router.replace(scopeRoute(availableScopes[0]));
|
||||
return;
|
||||
}
|
||||
@@ -64,7 +106,18 @@ onMounted(async () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex-1 bg-base-200 flex items-center justify-center p-4">
|
||||
<div class="flex-1 bg-base-200 flex flex-col items-center justify-center gap-4 p-4">
|
||||
<div v-if="userInfo.isSuperuser && !loading" class="w-full max-w-md flex flex-col gap-2">
|
||||
<button @click="syncScopes()" :disabled="syncing" class="btn btn-primary btn-sm self-end">
|
||||
<span v-if="syncing" class="loading loading-spinner loading-xs"></span>
|
||||
<i v-else class="mdi mdi-sync"></i>
|
||||
{{ t("submissionsSelect.syncScopes") }}
|
||||
</button>
|
||||
<div v-if="syncMessage" :class="['alert', `alert-${syncMessage.type}`]">
|
||||
{{ syncMessage.text }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="loading" class="flex justify-center py-20">
|
||||
<span class="loading loading-spinner loading-lg"></span>
|
||||
</div>
|
||||
@@ -89,5 +142,23 @@ onMounted(async () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Apibot token modal, only shown when the game has none configured yet -->
|
||||
<div :class="['modal', { 'modal-open': isTokenModalOpen }]">
|
||||
<form class="modal-box" @submit.prevent="syncScopes(apibotToken)">
|
||||
<h3 class="font-bold text-lg mb-2">{{ t("submissionsSelect.tokenTitle") }}</h3>
|
||||
<p class="text-base-content/70 mb-4">{{ t("submissionsSelect.tokenDescription") }}</p>
|
||||
<input v-model="apibotToken" type="password" autocomplete="off" required
|
||||
:placeholder="t('submissionsSelect.tokenPlaceholder')" class="input input-bordered w-full" />
|
||||
<div class="modal-action">
|
||||
<button type="button" @click="closeTokenModal" class="btn">{{ t("common.cancel") }}</button>
|
||||
<button type="submit" :disabled="syncing || !apibotToken.trim()" class="btn btn-primary">
|
||||
<span v-if="syncing" class="loading loading-spinner loading-xs"></span>
|
||||
{{ t("submissionsSelect.tokenSubmit") }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<div class="modal-backdrop" @click="closeTokenModal"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
import { type DefaultError, type InfiniteData, infiniteQueryOptions, queryOptions, type UseMutationOptions } from '@tanstack/vue-query';
|
||||
|
||||
import { client } from '../client.gen';
|
||||
import { animationsApiPuzzleResults, animationsApiResults, animationsApiTopSubmissions, clockApiCurrentState, clockApiMyStats, gamesApiListEventGames, gamesApiListEventSteamGames, gamesApiListGames, marketApiBetHistory, marketApiCloseMarket, marketApiCreateBet, marketApiGetUserPoints, marketApiListMarkets, marketApiListUserBets, marketApiResolveMarket, noitaApiGetLeaderboard, noitaApiGetResults, noitaApiSubmitLogFile, type Options, opusMagnumApiCreateSubmission, opusMagnumApiDeleteSubmission, opusMagnumApiGetCollection, opusMagnumApiGetStats, opusMagnumApiGetSubmission, opusMagnumApiListPuzzles, opusMagnumApiListResponsesNeedingValidation, opusMagnumApiListSubmissions, opusMagnumApiValidateAuto, opusMagnumApiValidateResponse, opusMagnumApiValidateSubmission, placeApiCanvas, placeApiEvolutionGif, polylanSubmitterApiClearCache, polylanSubmitterApiGetUserInfo, polylanSubmitterApiHealthCheck, submissionsApiCreateImageCrop, submissionsApiCreateSubmission, submissionsApiDeleteImageCrop, submissionsApiGetSubmission, submissionsApiListAvailableScopes, submissionsApiListMyScopes, submissionsApiListSubmissionsByGame, submissionsApiListUserSubmissions, submissionsApiProcessCropOcr, submissionsApiProcessFileOcr } from '../sdk.gen';
|
||||
import type { AnimationsApiPuzzleResultsData, AnimationsApiPuzzleResultsResponse, AnimationsApiResultsData, AnimationsApiResultsResponse, AnimationsApiTopSubmissionsData, AnimationsApiTopSubmissionsResponse, ClockApiCurrentStateData, ClockApiCurrentStateResponse, ClockApiMyStatsData, ClockApiMyStatsResponse, GamesApiListEventGamesData, GamesApiListEventGamesResponse, GamesApiListEventSteamGamesData, GamesApiListEventSteamGamesResponse, GamesApiListGamesData, GamesApiListGamesResponse, MarketApiBetHistoryData, MarketApiBetHistoryResponse, MarketApiCloseMarketData, MarketApiCreateBetData, MarketApiCreateBetResponse, MarketApiGetUserPointsData, MarketApiGetUserPointsResponse, MarketApiListMarketsData, MarketApiListMarketsResponse, MarketApiListUserBetsData, MarketApiListUserBetsResponse, MarketApiResolveMarketData, MarketApiResolveMarketResponse, NoitaApiGetLeaderboardData, NoitaApiGetLeaderboardResponse, NoitaApiGetResultsData, NoitaApiGetResultsResponse, NoitaApiSubmitLogFileData, NoitaApiSubmitLogFileError, NoitaApiSubmitLogFileResponse, OpusMagnumApiCreateSubmissionData, OpusMagnumApiCreateSubmissionResponse, OpusMagnumApiDeleteSubmissionData, OpusMagnumApiGetCollectionData, OpusMagnumApiGetCollectionResponse, OpusMagnumApiGetStatsData, OpusMagnumApiGetSubmissionData, OpusMagnumApiGetSubmissionResponse, OpusMagnumApiListPuzzlesData, OpusMagnumApiListPuzzlesResponse, OpusMagnumApiListResponsesNeedingValidationData, OpusMagnumApiListResponsesNeedingValidationResponse, OpusMagnumApiListSubmissionsData, OpusMagnumApiListSubmissionsResponse, OpusMagnumApiValidateAutoData, OpusMagnumApiValidateAutoResponse, OpusMagnumApiValidateResponseData, OpusMagnumApiValidateResponseResponse, OpusMagnumApiValidateSubmissionData, OpusMagnumApiValidateSubmissionResponse, PlaceApiCanvasData, PlaceApiEvolutionGifData, PolylanSubmitterApiClearCacheData, PolylanSubmitterApiGetUserInfoData, PolylanSubmitterApiGetUserInfoResponse, PolylanSubmitterApiHealthCheckData, SubmissionsApiCreateImageCropData, SubmissionsApiCreateImageCropResponse, SubmissionsApiCreateSubmissionData, SubmissionsApiCreateSubmissionError, SubmissionsApiCreateSubmissionResponse, SubmissionsApiDeleteImageCropData, SubmissionsApiDeleteImageCropResponse, SubmissionsApiGetSubmissionData, SubmissionsApiGetSubmissionResponse, SubmissionsApiListAvailableScopesData, SubmissionsApiListAvailableScopesError, SubmissionsApiListAvailableScopesResponse, SubmissionsApiListMyScopesData, SubmissionsApiListMyScopesError, SubmissionsApiListMyScopesResponse, SubmissionsApiListSubmissionsByGameData, SubmissionsApiListSubmissionsByGameResponse, SubmissionsApiListUserSubmissionsData, SubmissionsApiListUserSubmissionsError, SubmissionsApiListUserSubmissionsResponse, SubmissionsApiProcessCropOcrData, SubmissionsApiProcessCropOcrResponse, SubmissionsApiProcessFileOcrData, SubmissionsApiProcessFileOcrResponse } from '../types.gen';
|
||||
import { animationsApiPuzzleResults, animationsApiResults, animationsApiTopSubmissions, clockApiCurrentState, clockApiMyStats, gamesApiListEventGames, gamesApiListEventSteamGames, gamesApiListGames, marketApiBetHistory, marketApiCloseMarket, marketApiCreateBet, marketApiGetUserPoints, marketApiListMarkets, marketApiListUserBets, marketApiResolveMarket, noitaApiGetLeaderboard, noitaApiGetResults, noitaApiSubmitLogFile, type Options, opusMagnumApiCreateSubmission, opusMagnumApiDeleteSubmission, opusMagnumApiGetCollection, opusMagnumApiGetStats, opusMagnumApiGetSubmission, opusMagnumApiListPuzzles, opusMagnumApiListResponsesNeedingValidation, opusMagnumApiListSubmissions, opusMagnumApiValidateAuto, opusMagnumApiValidateResponse, opusMagnumApiValidateSubmission, placeApiCanvas, placeApiEvolutionGif, polylanSubmitterApiClearCache, polylanSubmitterApiGetUserInfo, polylanSubmitterApiHealthCheck, submissionsApiCreateImageCrop, submissionsApiCreateSubmission, submissionsApiDeleteImageCrop, submissionsApiGetSubmission, submissionsApiListAvailableScopes, submissionsApiListMyScopes, submissionsApiListSubmissionsByGame, submissionsApiListUserSubmissions, submissionsApiProcessCropOcr, submissionsApiProcessFileOcr, submissionsApiSyncScopes } from '../sdk.gen';
|
||||
import type { AnimationsApiPuzzleResultsData, AnimationsApiPuzzleResultsResponse, AnimationsApiResultsData, AnimationsApiResultsResponse, AnimationsApiTopSubmissionsData, AnimationsApiTopSubmissionsResponse, ClockApiCurrentStateData, ClockApiCurrentStateResponse, ClockApiMyStatsData, ClockApiMyStatsResponse, GamesApiListEventGamesData, GamesApiListEventGamesResponse, GamesApiListEventSteamGamesData, GamesApiListEventSteamGamesResponse, GamesApiListGamesData, GamesApiListGamesResponse, MarketApiBetHistoryData, MarketApiBetHistoryResponse, MarketApiCloseMarketData, MarketApiCreateBetData, MarketApiCreateBetResponse, MarketApiGetUserPointsData, MarketApiGetUserPointsResponse, MarketApiListMarketsData, MarketApiListMarketsResponse, MarketApiListUserBetsData, MarketApiListUserBetsResponse, MarketApiResolveMarketData, MarketApiResolveMarketResponse, NoitaApiGetLeaderboardData, NoitaApiGetLeaderboardResponse, NoitaApiGetResultsData, NoitaApiGetResultsResponse, NoitaApiSubmitLogFileData, NoitaApiSubmitLogFileError, NoitaApiSubmitLogFileResponse, OpusMagnumApiCreateSubmissionData, OpusMagnumApiCreateSubmissionResponse, OpusMagnumApiDeleteSubmissionData, OpusMagnumApiGetCollectionData, OpusMagnumApiGetCollectionResponse, OpusMagnumApiGetStatsData, OpusMagnumApiGetSubmissionData, OpusMagnumApiGetSubmissionResponse, OpusMagnumApiListPuzzlesData, OpusMagnumApiListPuzzlesResponse, OpusMagnumApiListResponsesNeedingValidationData, OpusMagnumApiListResponsesNeedingValidationResponse, OpusMagnumApiListSubmissionsData, OpusMagnumApiListSubmissionsResponse, OpusMagnumApiValidateAutoData, OpusMagnumApiValidateAutoResponse, OpusMagnumApiValidateResponseData, OpusMagnumApiValidateResponseResponse, OpusMagnumApiValidateSubmissionData, OpusMagnumApiValidateSubmissionResponse, PlaceApiCanvasData, PlaceApiEvolutionGifData, PolylanSubmitterApiClearCacheData, PolylanSubmitterApiGetUserInfoData, PolylanSubmitterApiGetUserInfoResponse, PolylanSubmitterApiHealthCheckData, SubmissionsApiCreateImageCropData, SubmissionsApiCreateImageCropResponse, SubmissionsApiCreateSubmissionData, SubmissionsApiCreateSubmissionError, SubmissionsApiCreateSubmissionResponse, SubmissionsApiDeleteImageCropData, SubmissionsApiDeleteImageCropResponse, SubmissionsApiGetSubmissionData, SubmissionsApiGetSubmissionResponse, SubmissionsApiListAvailableScopesData, SubmissionsApiListAvailableScopesError, SubmissionsApiListAvailableScopesResponse, SubmissionsApiListMyScopesData, SubmissionsApiListMyScopesError, SubmissionsApiListMyScopesResponse, SubmissionsApiListSubmissionsByGameData, SubmissionsApiListSubmissionsByGameResponse, SubmissionsApiListUserSubmissionsData, SubmissionsApiListUserSubmissionsError, SubmissionsApiListUserSubmissionsResponse, SubmissionsApiProcessCropOcrData, SubmissionsApiProcessCropOcrResponse, SubmissionsApiProcessFileOcrData, SubmissionsApiProcessFileOcrResponse, SubmissionsApiSyncScopesData, SubmissionsApiSyncScopesError, SubmissionsApiSyncScopesResponse } from '../types.gen';
|
||||
|
||||
export type QueryKey<TOptions extends Options> = [
|
||||
Pick<TOptions, 'baseUrl' | 'body' | 'headers' | 'path' | 'query'> & {
|
||||
@@ -593,6 +593,27 @@ export const submissionsApiListAvailableScopesOptions = (options: Options<Submis
|
||||
queryKey: submissionsApiListAvailableScopesQueryKey(options)
|
||||
});
|
||||
|
||||
/**
|
||||
* Sync Scopes
|
||||
*
|
||||
* Start the AAndT scope sync loop for a (non custom path) game, superusers
|
||||
* only. Stores `apibot_token` first when given; without one and none stored
|
||||
* yet, answers 400 with `token_required` so the frontend asks for it.
|
||||
*/
|
||||
export const submissionsApiSyncScopesMutation = (options?: Partial<Options<SubmissionsApiSyncScopesData>>): UseMutationOptions<SubmissionsApiSyncScopesResponse, SubmissionsApiSyncScopesError, Options<SubmissionsApiSyncScopesData>> => {
|
||||
const mutationOptions: UseMutationOptions<SubmissionsApiSyncScopesResponse, SubmissionsApiSyncScopesError, Options<SubmissionsApiSyncScopesData>> = {
|
||||
mutationFn: async (fnOptions) => {
|
||||
const { data } = await submissionsApiSyncScopes({
|
||||
...options,
|
||||
...fnOptions,
|
||||
throwOnError: true
|
||||
});
|
||||
return data;
|
||||
}
|
||||
};
|
||||
return mutationOptions;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create Submission
|
||||
*/
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -2,7 +2,7 @@
|
||||
|
||||
import { type Client, formDataBodySerializer, type Options as Options2, type TDataShape } from './client';
|
||||
import { client } from './client.gen';
|
||||
import type { AnimationsApiPuzzleResultsData, AnimationsApiPuzzleResultsResponses, AnimationsApiResultsData, AnimationsApiResultsResponses, AnimationsApiTopSubmissionsData, AnimationsApiTopSubmissionsResponses, ClockApiCurrentStateData, ClockApiCurrentStateResponses, ClockApiMyStatsData, ClockApiMyStatsResponses, GamesApiListEventGamesData, GamesApiListEventGamesResponses, GamesApiListEventSteamGamesData, GamesApiListEventSteamGamesResponses, GamesApiListGamesData, GamesApiListGamesResponses, MarketApiBetHistoryData, MarketApiBetHistoryResponses, MarketApiCloseMarketData, MarketApiCloseMarketResponses, MarketApiCreateBetData, MarketApiCreateBetResponses, MarketApiGetUserPointsData, MarketApiGetUserPointsResponses, MarketApiListMarketsData, MarketApiListMarketsResponses, MarketApiListUserBetsData, MarketApiListUserBetsResponses, MarketApiResolveMarketData, MarketApiResolveMarketResponses, NoitaApiGetLeaderboardData, NoitaApiGetLeaderboardResponses, NoitaApiGetResultsData, NoitaApiGetResultsResponses, NoitaApiSubmitLogFileData, NoitaApiSubmitLogFileErrors, NoitaApiSubmitLogFileResponses, OpusMagnumApiCreateSubmissionData, OpusMagnumApiCreateSubmissionResponses, OpusMagnumApiDeleteSubmissionData, OpusMagnumApiDeleteSubmissionResponses, OpusMagnumApiGetCollectionData, OpusMagnumApiGetCollectionResponses, OpusMagnumApiGetStatsData, OpusMagnumApiGetStatsResponses, OpusMagnumApiGetSubmissionData, OpusMagnumApiGetSubmissionResponses, OpusMagnumApiListPuzzlesData, OpusMagnumApiListPuzzlesResponses, OpusMagnumApiListResponsesNeedingValidationData, OpusMagnumApiListResponsesNeedingValidationResponses, OpusMagnumApiListSubmissionsData, OpusMagnumApiListSubmissionsResponses, OpusMagnumApiValidateAutoData, OpusMagnumApiValidateAutoResponses, OpusMagnumApiValidateResponseData, OpusMagnumApiValidateResponseResponses, OpusMagnumApiValidateSubmissionData, OpusMagnumApiValidateSubmissionResponses, PlaceApiCanvasData, PlaceApiCanvasResponses, PlaceApiEvolutionGifData, PlaceApiEvolutionGifResponses, PolylanSubmitterApiClearCacheData, PolylanSubmitterApiClearCacheResponses, PolylanSubmitterApiGetUserInfoData, PolylanSubmitterApiGetUserInfoResponses, PolylanSubmitterApiHealthCheckData, PolylanSubmitterApiHealthCheckResponses, SubmissionsApiCreateImageCropData, SubmissionsApiCreateImageCropResponses, SubmissionsApiCreateSubmissionData, SubmissionsApiCreateSubmissionErrors, SubmissionsApiCreateSubmissionResponses, SubmissionsApiDeleteImageCropData, SubmissionsApiDeleteImageCropResponses, SubmissionsApiGetSubmissionData, SubmissionsApiGetSubmissionResponses, SubmissionsApiListAvailableScopesData, SubmissionsApiListAvailableScopesErrors, SubmissionsApiListAvailableScopesResponses, SubmissionsApiListMyScopesData, SubmissionsApiListMyScopesErrors, SubmissionsApiListMyScopesResponses, SubmissionsApiListSubmissionsByGameData, SubmissionsApiListSubmissionsByGameResponses, SubmissionsApiListUserSubmissionsData, SubmissionsApiListUserSubmissionsErrors, SubmissionsApiListUserSubmissionsResponses, SubmissionsApiProcessCropOcrData, SubmissionsApiProcessCropOcrResponses, SubmissionsApiProcessFileOcrData, SubmissionsApiProcessFileOcrResponses } from './types.gen';
|
||||
import type { AnimationsApiPuzzleResultsData, AnimationsApiPuzzleResultsResponses, AnimationsApiResultsData, AnimationsApiResultsResponses, AnimationsApiTopSubmissionsData, AnimationsApiTopSubmissionsResponses, ClockApiCurrentStateData, ClockApiCurrentStateResponses, ClockApiMyStatsData, ClockApiMyStatsResponses, GamesApiListEventGamesData, GamesApiListEventGamesResponses, GamesApiListEventSteamGamesData, GamesApiListEventSteamGamesResponses, GamesApiListGamesData, GamesApiListGamesResponses, MarketApiBetHistoryData, MarketApiBetHistoryResponses, MarketApiCloseMarketData, MarketApiCloseMarketResponses, MarketApiCreateBetData, MarketApiCreateBetResponses, MarketApiGetUserPointsData, MarketApiGetUserPointsResponses, MarketApiListMarketsData, MarketApiListMarketsResponses, MarketApiListUserBetsData, MarketApiListUserBetsResponses, MarketApiResolveMarketData, MarketApiResolveMarketResponses, NoitaApiGetLeaderboardData, NoitaApiGetLeaderboardResponses, NoitaApiGetResultsData, NoitaApiGetResultsResponses, NoitaApiSubmitLogFileData, NoitaApiSubmitLogFileErrors, NoitaApiSubmitLogFileResponses, OpusMagnumApiCreateSubmissionData, OpusMagnumApiCreateSubmissionResponses, OpusMagnumApiDeleteSubmissionData, OpusMagnumApiDeleteSubmissionResponses, OpusMagnumApiGetCollectionData, OpusMagnumApiGetCollectionResponses, OpusMagnumApiGetStatsData, OpusMagnumApiGetStatsResponses, OpusMagnumApiGetSubmissionData, OpusMagnumApiGetSubmissionResponses, OpusMagnumApiListPuzzlesData, OpusMagnumApiListPuzzlesResponses, OpusMagnumApiListResponsesNeedingValidationData, OpusMagnumApiListResponsesNeedingValidationResponses, OpusMagnumApiListSubmissionsData, OpusMagnumApiListSubmissionsResponses, OpusMagnumApiValidateAutoData, OpusMagnumApiValidateAutoResponses, OpusMagnumApiValidateResponseData, OpusMagnumApiValidateResponseResponses, OpusMagnumApiValidateSubmissionData, OpusMagnumApiValidateSubmissionResponses, PlaceApiCanvasData, PlaceApiCanvasResponses, PlaceApiEvolutionGifData, PlaceApiEvolutionGifResponses, PolylanSubmitterApiClearCacheData, PolylanSubmitterApiClearCacheResponses, PolylanSubmitterApiGetUserInfoData, PolylanSubmitterApiGetUserInfoResponses, PolylanSubmitterApiHealthCheckData, PolylanSubmitterApiHealthCheckResponses, SubmissionsApiCreateImageCropData, SubmissionsApiCreateImageCropResponses, SubmissionsApiCreateSubmissionData, SubmissionsApiCreateSubmissionErrors, SubmissionsApiCreateSubmissionResponses, SubmissionsApiDeleteImageCropData, SubmissionsApiDeleteImageCropResponses, SubmissionsApiGetSubmissionData, SubmissionsApiGetSubmissionResponses, SubmissionsApiListAvailableScopesData, SubmissionsApiListAvailableScopesErrors, SubmissionsApiListAvailableScopesResponses, SubmissionsApiListMyScopesData, SubmissionsApiListMyScopesErrors, SubmissionsApiListMyScopesResponses, SubmissionsApiListSubmissionsByGameData, SubmissionsApiListSubmissionsByGameResponses, SubmissionsApiListUserSubmissionsData, SubmissionsApiListUserSubmissionsErrors, SubmissionsApiListUserSubmissionsResponses, SubmissionsApiProcessCropOcrData, SubmissionsApiProcessCropOcrResponses, SubmissionsApiProcessFileOcrData, SubmissionsApiProcessFileOcrResponses, SubmissionsApiSyncScopesData, SubmissionsApiSyncScopesErrors, SubmissionsApiSyncScopesResponses } from './types.gen';
|
||||
|
||||
export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean, TResponse = unknown> = Options2<TData, ThrowOnError, TResponse> & {
|
||||
/**
|
||||
@@ -219,6 +219,22 @@ export const submissionsApiListMyScopes = <ThrowOnError extends boolean = false>
|
||||
*/
|
||||
export const submissionsApiListAvailableScopes = <ThrowOnError extends boolean = false>(options: Options<SubmissionsApiListAvailableScopesData, ThrowOnError>) => (options.client ?? client).get<SubmissionsApiListAvailableScopesResponses, SubmissionsApiListAvailableScopesErrors, ThrowOnError>({ url: '/api/events/{event_path}/submissions/{game_path}/available-scopes', ...options });
|
||||
|
||||
/**
|
||||
* Sync Scopes
|
||||
*
|
||||
* Start the AAndT scope sync loop for a (non custom path) game, superusers
|
||||
* only. Stores `apibot_token` first when given; without one and none stored
|
||||
* yet, answers 400 with `token_required` so the frontend asks for it.
|
||||
*/
|
||||
export const submissionsApiSyncScopes = <ThrowOnError extends boolean = false>(options: Options<SubmissionsApiSyncScopesData, ThrowOnError>) => (options.client ?? client).post<SubmissionsApiSyncScopesResponses, SubmissionsApiSyncScopesErrors, ThrowOnError>({
|
||||
url: '/api/events/{event_path}/submissions/{game_path}/sync-scopes',
|
||||
...options,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
...options.headers
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Create Submission
|
||||
*/
|
||||
|
||||
@@ -1000,6 +1000,26 @@ export type ScopeOut = {
|
||||
created_at: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* SyncScopesOut
|
||||
*/
|
||||
export type SyncScopesOut = {
|
||||
/**
|
||||
* Started
|
||||
*/
|
||||
started: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* SyncScopesIn
|
||||
*/
|
||||
export type SyncScopesIn = {
|
||||
/**
|
||||
* Apibot Token
|
||||
*/
|
||||
apibot_token?: string | null;
|
||||
};
|
||||
|
||||
/**
|
||||
* ImageCropOut
|
||||
*/
|
||||
@@ -1873,6 +1893,52 @@ export type SubmissionsApiListAvailableScopesResponses = {
|
||||
|
||||
export type SubmissionsApiListAvailableScopesResponse = SubmissionsApiListAvailableScopesResponses[keyof SubmissionsApiListAvailableScopesResponses];
|
||||
|
||||
export type SubmissionsApiSyncScopesData = {
|
||||
body: SyncScopesIn;
|
||||
path: {
|
||||
/**
|
||||
* Event Path
|
||||
*/
|
||||
event_path: string;
|
||||
/**
|
||||
* Game Path
|
||||
*/
|
||||
game_path: string;
|
||||
};
|
||||
query?: never;
|
||||
url: '/api/events/{event_path}/submissions/{game_path}/sync-scopes';
|
||||
};
|
||||
|
||||
export type SubmissionsApiSyncScopesErrors = {
|
||||
/**
|
||||
* Response
|
||||
*
|
||||
* Bad Request
|
||||
*/
|
||||
400: {
|
||||
[key: string]: unknown;
|
||||
};
|
||||
/**
|
||||
* Response
|
||||
*
|
||||
* Forbidden
|
||||
*/
|
||||
403: {
|
||||
[key: string]: unknown;
|
||||
};
|
||||
};
|
||||
|
||||
export type SubmissionsApiSyncScopesError = SubmissionsApiSyncScopesErrors[keyof SubmissionsApiSyncScopesErrors];
|
||||
|
||||
export type SubmissionsApiSyncScopesResponses = {
|
||||
/**
|
||||
* OK
|
||||
*/
|
||||
200: SyncScopesOut;
|
||||
};
|
||||
|
||||
export type SubmissionsApiSyncScopesResponse = SubmissionsApiSyncScopesResponses[keyof SubmissionsApiSyncScopesResponses];
|
||||
|
||||
export type SubmissionsApiCreateSubmissionData = {
|
||||
/**
|
||||
* MultiPartBodyParams
|
||||
|
||||
@@ -9,5 +9,6 @@ export const useUser = () => {
|
||||
username: data.value?.username ?? "",
|
||||
isAuthenticated: data.value?.is_authenticated ?? false,
|
||||
isStaff: data.value?.is_staff ?? false,
|
||||
isSuperuser: data.value?.is_superuser ?? false,
|
||||
}));
|
||||
};
|
||||
|
||||
@@ -209,7 +209,15 @@
|
||||
"title": "Select your match",
|
||||
"description": "You're assigned to multiple matches for {game}. Pick which one you want to submit for.",
|
||||
"notAssignedTitle": "No match assigned",
|
||||
"notAssignedMessage": "You are not assigned to a scope/matches, you cannot submit a score."
|
||||
"notAssignedMessage": "You are not assigned to a scope/matches, you cannot submit a score.",
|
||||
"syncScopes": "Sync scopes",
|
||||
"syncStarted": "Scope sync started, it keeps running until the AAndT is done. Refresh in a few seconds to see new matches.",
|
||||
"syncAlreadyRunning": "Scope sync is already running.",
|
||||
"syncFailed": "Failed to start the scope sync.",
|
||||
"tokenTitle": "AAndT apibot token",
|
||||
"tokenDescription": "No apibot token is configured for this game yet. Paste the one from the AAndT's 'apibot' admin page.",
|
||||
"tokenPlaceholder": "Apibot token",
|
||||
"tokenSubmit": "Save & sync"
|
||||
},
|
||||
"errorPage": {
|
||||
"notFound": {
|
||||
|
||||
Reference in New Issue
Block a user