Skip to content

Commit

Permalink
Merge pull request #6 from marmelab/features/game-search
Browse files Browse the repository at this point in the history
Make the game list searchable by user
  • Loading branch information
slax57 authored Feb 3, 2025
2 parents bc2ff06 + a2435a5 commit 86b007d
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 19 deletions.
6 changes: 5 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,11 @@ const App = () => {

return (
<Admin dataProvider={dataProvider}>
<Resource name="games" list={GameList}></Resource>
<Resource
name="games_view"
list={GameList}
options={{ label: "Games" }}
></Resource>
</Admin>
);
};
Expand Down
38 changes: 28 additions & 10 deletions src/games/GameList.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,45 @@
import {
AutocompleteInput,
Datagrid,
DateField,
List,
ReferenceField,
ReferenceInput,
SearchInput,
SelectInput,
TextField,
WrapperField,
} from "react-admin";
import { GameStatus } from "./GameStatus";
import { GameStatus, statusChoices } from "./GameStatus";

const filterToQuery = (searchText: any) => ({
"username@ilike": `%${searchText}%`,
});

const postFilters = [
<SearchInput source="_players@ilike" alwaysOn />,
<ReferenceInput source="winner_id" reference="users" alwaysOn>
<AutocompleteInput filterToQuery={filterToQuery} optionText="username" />
</ReferenceInput>,
<SelectInput
label="Game status"
source="_game_status"
choices={statusChoices}
alwaysOn
/>,
];

export const GameList = () => (
<List>
<List filters={postFilters}>
<Datagrid>
<TextField source="id" />
<ReferenceField source="first_player_id" reference="users">
<TextField source="username" />
</ReferenceField>
<ReferenceField source="second_player_id" reference="users">
<TextField source="username" />
</ReferenceField>
<TextField source="first_player" label="First player" />
<TextField source="second_player" label="Second player" />
<WrapperField label="Game status">
<GameStatus />
</WrapperField>
<DateField source="last_update_date" />
<TextField source="winner" label="Winner" />
<DateField source="creation_date" label="Game creation date" />
<DateField source="last_update_date" label="Game last update date" />
</Datagrid>
</List>
);
13 changes: 7 additions & 6 deletions src/games/GameStatus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ const Status = {
Finished: { label: "Finished", color: "#9E9E9E" },
} as const;

export const statusChoices = Object.entries(Status).map(([key, value]) => ({
id: key,
name: value.label,
}));

export const GameStatus = () => {
const gameState = useFieldValue({ source: "game_state" });
const gameStatus = useFieldValue({ source: "_game_status" });

const gameStateVal = JSON.parse(gameState);
const status =
gameStateVal.victoryState.player != null ||
gameStateVal.victoryState?.isDraw
? Status.Finished
: Status.Ongoing;
gameStatus === Status.Finished.label ? Status.Finished : Status.Ongoing;

return (
<>
Expand Down
4 changes: 2 additions & 2 deletions supabase/migrations/20240130152000_create_model.sql
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,5 @@ CREATE TABLE IF NOT EXISTS games (
second_player_id INT REFERENCES users(id) ON DELETE CASCADE,
creation_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_update_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
game_state VARCHAR(255) NOT NULL
);
game_state VARCHAR(255) NOT NULL
);
3 changes: 3 additions & 0 deletions supabase/migrations/20240131101200_update_game_state_type.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ALTER TABLE games
ALTER COLUMN game_state TYPE JSONB
USING game_state::JSONB;
27 changes: 27 additions & 0 deletions supabase/migrations/20240131112500_create_game_view.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
CREATE INDEX idx_games_winner ON games ((game_state->'victoryState'->>'player'));

CREATE VIEW games_view AS
SELECT
g.id,
g.first_player_id,
u1.username as first_player,
g.second_player_id,
u2.username as second_player,
g.game_state->'victoryState'->>'player' as winner_id,
w.username as winner,
g.creation_date,
g.last_update_date,
g.game_state,
CONCAT(u1.username,' ',u2.username) as _players,
CASE
WHEN (g.game_state->'victoryState'->>'player') IS NOT NULL
OR COALESCE((g.game_state->'victoryState'->>'isDraw')::BOOLEAN, FALSE) = TRUE
THEN 'Finished'
ELSE 'Ongoing'
END as _game_status

FROM games g
LEFT JOIN users as u1 on first_player_id=u1.id
LEFT JOIN users as u2 on second_player_id=u2.id
LEFT JOIN users as w on (g.game_state->'victoryState'->>'player')::INT=w.id
;

0 comments on commit 86b007d

Please sign in to comment.