Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged PR 298: v1.26.0 - Rename teams, black pronunciation guides, styling fixes #272

Merged
merged 1 commit into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "modaq",
"version": "1.25.0",
"version": "1.26.0",
"description": "Quiz Bowl Reader using TypeScript, React, and MobX",
"repository": {
"type": "git",
Expand Down
1 change: 1 addition & 0 deletions src/components/FormattedText.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ const useStyles = memoizeFunction(
mergeStyleSets({
text: {
display: "inline",
textDecorationSkipInk: "none",
},
pronunciationGuide: {
// Don't override the color if it's disabled; the container has that responsibility
Expand Down
45 changes: 32 additions & 13 deletions src/components/GameBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,14 @@ export const GameBar = observer(function GameBar(): JSX.Element {
uiState.dialogState.showReorderPlayersDialog(game.players);
}, [uiState, game]);

const renameTeamHandler = React.useCallback(() => {
if (game.players.length === 0) {
return;
}

uiState.dialogState.showRenameTeamDialog(game.players[0].teamName);
}, [uiState, game]);

const items: ICommandBarItemProps[] = appState.uiState.hideNewGame
? []
: [
Expand Down Expand Up @@ -147,6 +155,7 @@ export const GameBar = observer(function GameBar(): JSX.Element {
addPlayerHandler,
protestBonusHandler,
reorderPlayersHandler,
renameTeamHandler,
addQuestionsHandler
);
items.push({
Expand Down Expand Up @@ -219,6 +228,7 @@ function getActionSubMenuItems(
addPlayerHandler: () => void,
protestBonusHandler: () => void,
reorderPlayersHandler: () => void,
renameTeamHandler: () => void,
addQuestionsHandler: () => void
): ICommandBarItemProps[] {
const items: ICommandBarItemProps[] = [];
Expand All @@ -230,7 +240,8 @@ function getActionSubMenuItems(
game,
uiState,
addPlayerHandler,
reorderPlayersHandler
reorderPlayersHandler,
renameTeamHandler
);
items.push(playerManagementSection);

Expand Down Expand Up @@ -420,10 +431,11 @@ function getPlayerManagementSubMenuItems(
game: GameState,
uiState: UIState,
addPlayerHandler: () => void,
reorderPlayersHandler: () => void
reorderPlayersHandler: () => void,
renameTeamHandler: () => void
): ICommandBarItemProps {
const teamNames: string[] = game.teamNames;
const swapActivePlayerMenus: ICommandBarItemProps[] = [];
const playerActionsMenus: ICommandBarItemProps[] = [];
for (const teamName of teamNames) {
const players: Player[] = game.getPlayers(teamName);
const activePlayers: Set<Player> = game.getActivePlayers(teamName, uiState.cycleIndex);
Expand Down Expand Up @@ -502,7 +514,7 @@ function getPlayerManagementSubMenuItems(
});
}

swapActivePlayerMenus.push({
playerActionsMenus.push({
key: `active_${teamName}`,
itemType: ContextualMenuItemType.Section,
sectionProps: {
Expand All @@ -514,13 +526,13 @@ function getPlayerManagementSubMenuItems(
}

// TODO: This should be under a section for player management (add player, subs)
const swapPlayerItem: ICommandBarItemProps = {
key: "swapPlayer",
text: "Substitute/Remove",
const playerActionsItem: ICommandBarItemProps = {
key: "player",
text: "Player",
subMenuProps: {
items: swapActivePlayerMenus,
items: playerActionsMenus,
},
disabled: swapActivePlayerMenus.length === 0,
disabled: playerActionsMenus.length === 0,
// This needs its own submenu, with all the starters, then all the possible subs
// We should disable this if there are no subs available
};
Expand Down Expand Up @@ -549,13 +561,20 @@ function getPlayerManagementSubMenuItems(
disabled: appState.game.cycles.length === 0,
};

const renameTeamItem: ICommandBarItemProps = {
key: "renameTeam",
text: "Rename team...",
onClick: renameTeamHandler,
disabled: appState.game.cycles.length === 0,
};

return {
key: "playerManagement",
key: "teamManagement",
itemType: ContextualMenuItemType.Section,
sectionProps: {
bottomDivider: true,
title: "Player Management",
items: [swapPlayerItem, addPlayerItem, reorderPlayersItem],
title: "Team Management",
items: [playerActionsItem, addPlayerItem, reorderPlayersItem, renameTeamItem],
},
};
}
Expand Down Expand Up @@ -766,7 +785,7 @@ function onSwapPlayerClick(

const additionalHint: string =
Math.abs(cycleIndex - halftimeIndex) <= 1
? ` If you want to substitue a player at halftime, do it on question ${Math.floor(halftimeIndex + 1)}.`
? ` If you want to substitute a player at halftime, do it on question ${Math.floor(halftimeIndex + 1)}.`
: "";
item.data.appState.uiState.dialogState.showOKCancelMessageDialog(
"Substitute Player",
Expand Down
2 changes: 2 additions & 0 deletions src/components/ModalDialogContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { ScoresheetDialog } from "./dialogs/ScoresheetDialog";
import { StateContext } from "../contexts/StateContext";
import { AppState } from "../state/AppState";
import { ModalVisibilityStatus } from "../state/ModalVisibilityStatus";
import { RenameTeamDialog } from "./dialogs/RenameTeamDialog";

export const ModalDialogContainer = observer(function ModalDialogContainer() {
// The Protest dialogs aren't here because they require extra information
Expand All @@ -38,6 +39,7 @@ export const ModalDialogContainer = observer(function ModalDialogContainer() {
<MessageDialog />
<NewGameDialog />
<RenamePlayerDialog />
<RenameTeamDialog />
<ReorderPlayerDialog />
<ScoresheetDialog />
</>
Expand Down
49 changes: 6 additions & 43 deletions src/components/dialogs/AddPlayerDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,65 +1,28 @@
import * as React from "react";
import { observer } from "mobx-react-lite";
import {
Dropdown,
TextField,
IDropdownOption,
IDialogContentProps,
DialogType,
IModalProps,
ContextualMenu,
Dialog,
DialogFooter,
PrimaryButton,
DefaultButton,
} from "@fluentui/react";
import { Dropdown, TextField, IDropdownOption, DialogFooter, PrimaryButton, DefaultButton } from "@fluentui/react";

import * as AddPlayerDialogController from "../../components/dialogs/AddPlayerDialogController";
import { IPlayer } from "../../state/TeamState";
import { AppState } from "../../state/AppState";
import { StateContext } from "../../contexts/StateContext";
import { ModalVisibilityStatus } from "../../state/ModalVisibilityStatus";

const content: IDialogContentProps = {
type: DialogType.normal,
title: "Add Player",
closeButtonAriaLabel: "Close",
showCloseButton: true,
styles: {
innerContent: {
display: "flex",
flexDirection: "column",
},
},
};

const modalProps: IModalProps = {
isBlocking: false,
dragOptions: {
moveMenuItemText: "Move",
closeMenuItemText: "Close",
menu: ContextualMenu,
},
topOffsetFixed: true,
};
import { ModalDialog } from "./ModalDialog";

// TODO: Look into making a DefaultDialog, which handles the footers and default props
export const AddPlayerDialog = observer(function AddPlayerDialog(): JSX.Element {
const appState: AppState = React.useContext(StateContext);

return (
<Dialog
hidden={appState.uiState.dialogState.visibleDialog !== ModalVisibilityStatus.AddPlayer}
dialogContentProps={content}
modalProps={modalProps}
<ModalDialog
title="Add Player"
visibilityStatus={ModalVisibilityStatus.AddPlayer}
onDismiss={AddPlayerDialogController.hideDialog}
>
<AddPlayerDialogBody />
<DialogFooter>
<PrimaryButton text="Add" onClick={AddPlayerDialogController.addPlayer} />
<DefaultButton text="Cancel" onClick={AddPlayerDialogController.hideDialog} />
</DialogFooter>
</Dialog>
</ModalDialog>
);
});

Expand Down
45 changes: 6 additions & 39 deletions src/components/dialogs/AddQuestionsDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,61 +1,28 @@
import * as React from "react";
import { observer } from "mobx-react-lite";
import {
IDialogContentProps,
DialogType,
IModalProps,
ContextualMenu,
Dialog,
DialogFooter,
PrimaryButton,
DefaultButton,
} from "@fluentui/react";
import { DialogFooter, PrimaryButton, DefaultButton } from "@fluentui/react";

import * as AddQuestionsDialogController from "./AddQuestionsDialogController";
import { AppState } from "../../state/AppState";
import { PacketLoader } from "../PacketLoader";
import { StateContext } from "../../contexts/StateContext";
import { ModalVisibilityStatus } from "../../state/ModalVisibilityStatus";

const content: IDialogContentProps = {
type: DialogType.normal,
title: "Add Questions",
closeButtonAriaLabel: "Close",
showCloseButton: true,
styles: {
innerContent: {
display: "flex",
flexDirection: "column",
},
},
};

const modalProps: IModalProps = {
isBlocking: false,
dragOptions: {
moveMenuItemText: "Move",
closeMenuItemText: "Close",
menu: ContextualMenu,
},
topOffsetFixed: true,
};
import { ModalDialog } from "./ModalDialog";

// TODO: Look into making a DefaultDialog, which handles the footers and default props
export const AddQuestionsDialog = observer(function AddQuestionsDialog(): JSX.Element {
const appState: AppState = React.useContext(StateContext);
return (
<Dialog
hidden={appState.uiState.dialogState.visibleDialog !== ModalVisibilityStatus.AddQuestions}
dialogContentProps={content}
modalProps={modalProps}
<ModalDialog
title="Add Questions"
visibilityStatus={ModalVisibilityStatus.AddQuestions}
onDismiss={AddQuestionsDialogController.cancel}
>
<AddQuestionsDialogBody />
<DialogFooter>
<PrimaryButton text="Load" onClick={AddQuestionsDialogController.commit} />
<DefaultButton text="Cancel" onClick={AddQuestionsDialogController.cancel} />
</DialogFooter>
</Dialog>
</ModalDialog>
);
});

Expand Down
2 changes: 1 addition & 1 deletion src/components/dialogs/BonusProtestDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ export const BonusProtestDialog = observer(function BonusProtestDialog(props: IB
<ProtestDialogBase
appState={props.appState}
givenAnswer={protestEvent.givenAnswer}
hidden={props.appState.uiState.dialogState.visibleDialog !== ModalVisibilityStatus.BonusProtest}
hideDialog={BonusProtestDialogController.cancel}
onSubmit={submitHandler}
reason={protestEvent.reason}
visibilityStatus={ModalVisibilityStatus.BonusProtest}
>
{children}
</ProtestDialogBase>
Expand Down
30 changes: 5 additions & 25 deletions src/components/dialogs/CustomizeGameFormatDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ import { observer } from "mobx-react-lite";
import {
IDialogContentProps,
DialogType,
IModalProps,
ContextualMenu,
Dialog,
DialogFooter,
PrimaryButton,
DefaultButton,
Expand All @@ -28,6 +25,7 @@ import { StateContext } from "../../contexts/StateContext";
import { GameFormatPicker } from "../GameFormatPicker";
import { SheetType } from "../../state/SheetState";
import { ModalVisibilityStatus } from "../../state/ModalVisibilityStatus";
import { ModalDialog } from "./ModalDialog";

const content: IDialogContentProps = {
type: DialogType.normal,
Expand All @@ -43,24 +41,6 @@ const content: IDialogContentProps = {
},
};

const modalProps: IModalProps = {
isBlocking: false,
dragOptions: {
moveMenuItemText: "Move",
closeMenuItemText: "Close",
menu: ContextualMenu,
},
styles: {
main: {
// To have max width respected normally, we'd need to pass in an IDialogStyleProps, but it ridiculously
// requires you to pass in an entire theme to modify the max width. We could also use a modal, but that
// requires building much of what Dialogs offer easily (close buttons, footer for buttons)
minWidth: "30vw !important",
},
},
topOffsetFixed: true,
};

const pivotStyles: Partial<IPivotStyles> = {
root: {
marginBottom: 10,
Expand All @@ -76,18 +56,18 @@ export const CustomizeGameFormatDialog = observer(function CustomizeGameFormatDi
const cancelHandler = React.useCallback(() => CustomizeGameFormatDialogController.cancel(appState), [appState]);

return (
<Dialog
hidden={appState.uiState.dialogState.visibleDialog !== ModalVisibilityStatus.CustomizeGameFormat}
<ModalDialog
title="Customize Game Format"
visibilityStatus={ModalVisibilityStatus.CustomizeGameFormat}
dialogContentProps={content}
modalProps={modalProps}
onDismiss={cancelHandler}
>
<CustomizeGameFormatDialogBody />
<DialogFooter>
<PrimaryButton text="Save" onClick={submitHandler} />
<DefaultButton text="Cancel" onClick={cancelHandler} />
</DialogFooter>
</Dialog>
</ModalDialog>
);
});

Expand Down
Loading
Loading