From 40641f80a389c1a8b600a5cbf1eda1570b85c905 Mon Sep 17 00:00:00 2001 From: HumanoidSandvichDispenser Date: Thu, 5 Dec 2024 17:20:02 -0800 Subject: [PATCH] feat: Implement changing team settings --- availabili.tf/src/assets/base.css | 7 +- availabili.tf/src/assets/main.css | 15 ++++ .../src/client/services/DefaultService.ts | 25 +++++++ availabili.tf/src/stores/teams.ts | 8 +- .../src/views/TeamRegistrationView.vue | 7 ++ .../src/views/TeamSettings/GeneralView.vue | 74 ++++++++++++++++++- backend-flask/team.py | 23 +++++- 7 files changed, 151 insertions(+), 8 deletions(-) diff --git a/availabili.tf/src/assets/base.css b/availabili.tf/src/assets/base.css index c5a4edc..7798ac5 100644 --- a/availabili.tf/src/assets/base.css +++ b/availabili.tf/src/assets/base.css @@ -38,6 +38,7 @@ --crust: #dce0e8; --red: #d20f39; + --blue: #1e66f5; --flamingo: #dd7878; --flamingo-transparent: #f0c6c655; @@ -52,13 +53,11 @@ */ --green-transparent: color-mix(in srgb, var(--green), transparent 80%); --yellow-transparent: color-mix(in srgb, var(--yellow), transparent 80%); - /* - --green-transparent-50: #a6e3a1; - --yellow-transparent-50: #f9e2af; -*/ + --blue-transparent: color-mix(in srgb, var(--blue), transparent 80%); --lavender: #7287fd; --accent: var(--lavender); + --lavender-transparent: color-mix(in srgb, var(--lavender), transparent 80%); --accent-transparent-80: color-mix(in srgb, var(--accent), transparent 80%); --accent-transparent-50: color-mix(in srgb, var(--accent), transparent 50%); --accent-transparent: var(--accent-transparent-80); diff --git a/availabili.tf/src/assets/main.css b/availabili.tf/src/assets/main.css index 98f1900..b4cfff8 100644 --- a/availabili.tf/src/assets/main.css +++ b/availabili.tf/src/assets/main.css @@ -313,3 +313,18 @@ div[role="menu"] div[role="menuitem"]:last-child button { background-color: var(--surface-0); width: 100%; } + +div.banner { + padding: 0.5rem 1rem; + font-size: 10pt; +} + +div.banner.warning { + background-color: var(--yellow-transparent); + color: var(--yellow); +} + +div.banner.info { + background-color: var(--lavender-transparent); + color: var(--lavender); +} diff --git a/availabili.tf/src/client/services/DefaultService.ts b/availabili.tf/src/client/services/DefaultService.ts index ffb0f33..0f19739 100644 --- a/availabili.tf/src/client/services/DefaultService.ts +++ b/availabili.tf/src/client/services/DefaultService.ts @@ -17,6 +17,7 @@ import type { SetUsernameJson } from '../models/SetUsernameJson'; import type { TeamIntegrationSchema } from '../models/TeamIntegrationSchema'; import type { TeamInviteSchema } from '../models/TeamInviteSchema'; import type { TeamInviteSchemaList } from '../models/TeamInviteSchemaList'; +import type { TeamSchema } from '../models/TeamSchema'; import type { UpdateEventJson } from '../models/UpdateEventJson'; import type { ViewAvailablePlayersResponse } from '../models/ViewAvailablePlayersResponse'; import type { ViewScheduleResponse } from '../models/ViewScheduleResponse'; @@ -458,6 +459,30 @@ export class DefaultService { }, }); } + /** + * update_team + * @param teamId + * @param requestBody + * @returns TeamSchema OK + * @throws ApiError + */ + public updateTeam( + teamId: number, + requestBody?: CreateTeamJson, + ): CancelablePromise { + return this.httpRequest.request({ + method: 'PATCH', + url: '/api/team/id/{team_id}/', + path: { + 'team_id': teamId, + }, + body: requestBody, + mediaType: 'application/json', + errors: { + 422: `Unprocessable Content`, + }, + }); + } /** * consume_invite * @param teamId diff --git a/availabili.tf/src/stores/teams.ts b/availabili.tf/src/stores/teams.ts index 974a289..b434c26 100644 --- a/availabili.tf/src/stores/teams.ts +++ b/availabili.tf/src/stores/teams.ts @@ -2,7 +2,7 @@ import { defineStore } from "pinia"; import { reactive, type Reactive } from "vue"; import { useClientStore } from "./client"; import { useAuthStore } from "./auth"; -import { type TeamSchema, type RoleSchema, type ViewTeamMembersResponse } from "@/client"; +import { type TeamSchema, type RoleSchema, type ViewTeamMembersResponse, type CreateTeamJson } from "@/client"; export type TeamMap = { [id: number]: TeamSchema }; @@ -55,6 +55,11 @@ export const useTeamsStore = defineStore("teams", () => { }); } + async function updateTeam(teamId: number, args: CreateTeamJson) { + return await client.default.updateTeam(teamId, args) + .then((response) => teams[teamId] = response); + } + async function updateRoles(teamId: number, playerId: string, roles: RoleSchema[]) { return await client.default.editMemberRoles(teamId.toString(), playerId, { roles }); } @@ -70,6 +75,7 @@ export const useTeamsStore = defineStore("teams", () => { fetchTeam, fetchTeamMembers, createTeam, + updateTeam, updateRoles, leaveTeam, }; diff --git a/availabili.tf/src/views/TeamRegistrationView.vue b/availabili.tf/src/views/TeamRegistrationView.vue index f1a606e..e08f91b 100644 --- a/availabili.tf/src/views/TeamRegistrationView.vue +++ b/availabili.tf/src/views/TeamRegistrationView.vue @@ -75,6 +75,13 @@ function createTeam() { past the hour. +
+ +
diff --git a/availabili.tf/src/views/TeamSettings/GeneralView.vue b/availabili.tf/src/views/TeamSettings/GeneralView.vue index 7b8937f..24b1a60 100644 --- a/availabili.tf/src/views/TeamSettings/GeneralView.vue +++ b/availabili.tf/src/views/TeamSettings/GeneralView.vue @@ -1,6 +1,10 @@ + + diff --git a/backend-flask/team.py b/backend-flask/team.py index 3b9ae62..e93eefd 100644 --- a/backend-flask/team.py +++ b/backend-flask/team.py @@ -10,7 +10,7 @@ from models.player_team import PlayerTeam from models.player_team_availability import PlayerTeamAvailability from models.player_team_role import PlayerTeamRole, RoleSchema from models.team import Team, TeamSchema -from middleware import requires_authentication +from middleware import assert_team_authority, requires_authentication, requires_team_membership from spec import spec, BaseModel from team_invite import api_team_invite from team_integration import api_team_integration @@ -86,6 +86,27 @@ def create_team(json: CreateTeamJson, player: Player, **kwargs): response = ViewTeamResponse(team=TeamSchema.from_model(team)) return response.dict(by_alias=True), 200 +@api_team.patch("/id//") +@spec.validate( + resp=Response( + HTTP_200=TeamSchema, + ), + operation_id="update_team", +) +@requires_authentication +@requires_team_membership() +def update_team(player_team: PlayerTeam, team_id: int, json: CreateTeamJson, **kwargs): + assert_team_authority(player_team) + + team = player_team.team + team.team_name = json.team_name + team.tz_timezone = json.league_timezone + team.minute_offset = json.minute_offset + + db.session.commit() + + return TeamSchema.from_model(team).dict(by_alias=True), 200 + @api_team.delete("/id//") @spec.validate( resp=Response(