Skip to content

Commit

Permalink
Merge branch 'development' into El-Limon-patch-3
Browse files Browse the repository at this point in the history
  • Loading branch information
niekcandaele authored Nov 9, 2024
2 parents d0f456b + 6492441 commit cd51d45
Show file tree
Hide file tree
Showing 25 changed files with 617 additions and 429 deletions.
190 changes: 61 additions & 129 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@
"class-validator-jsonschema": "5.0.1",
"concurrently": "9.0.1",
"convict": "6.2.4",
"cronstrue": "2.51.0",
"csv": "6.3.10",
"discord-api-types": "0.37.101",
"discord.js": "14.16.3",
Expand Down
2 changes: 1 addition & 1 deletion packages/lib-apiclient/src/generated/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Takaro app-api
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: development - 0bc7fc2d56d414efbaeec289a550061e62ac1608
* The version of the OpenAPI document: development - c5bbf18435f3a3215b38be548ffc69028bd2ace0
* Contact: [email protected]
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
Expand Down
2 changes: 1 addition & 1 deletion packages/lib-apiclient/src/generated/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Takaro app-api
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: development - 0bc7fc2d56d414efbaeec289a550061e62ac1608
* The version of the OpenAPI document: development - c5bbf18435f3a3215b38be548ffc69028bd2ace0
* Contact: [email protected]
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
Expand Down
2 changes: 1 addition & 1 deletion packages/lib-apiclient/src/generated/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Takaro app-api
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: development - 0bc7fc2d56d414efbaeec289a550061e62ac1608
* The version of the OpenAPI document: development - c5bbf18435f3a3215b38be548ffc69028bd2ace0
* Contact: [email protected]
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
Expand Down
2 changes: 1 addition & 1 deletion packages/lib-apiclient/src/generated/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Takaro app-api
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: development - 0bc7fc2d56d414efbaeec289a550061e62ac1608
* The version of the OpenAPI document: development - c5bbf18435f3a3215b38be548ffc69028bd2ace0
* Contact: [email protected]
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
Expand Down
2 changes: 1 addition & 1 deletion packages/lib-apiclient/src/generated/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Takaro app-api
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: development - 0bc7fc2d56d414efbaeec289a550061e62ac1608
* The version of the OpenAPI document: development - c5bbf18435f3a3215b38be548ffc69028bd2ace0
* Contact: [email protected]
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
Expand Down
4 changes: 2 additions & 2 deletions packages/lib-components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"@rjsf/validator-ajv8": "5.20.0",
"@sentry/react": "8.32.0",
"@tanstack/react-table": "8.20.5",
"@tanstack/react-router": "1.58.15",
"@tanstack/react-router": "1.79.0",
"@types/luxon": "3.4.2",
"@visx/axis": "3.10.1",
"@visx/brush": "3.10.4",
Expand All @@ -51,7 +51,7 @@
"@visx/shape": "3.5.0",
"@visx/tooltip": "3.3.0",
"@visx/vendor": "3.5.0",
"@visx/zoom": "^3.3.0",
"@visx/zoom": "3.3.0",
"framer-motion": "11.9.0",
"luxon": "3.5.0",
"notistack": "3.0.1",
Expand Down
127 changes: 77 additions & 50 deletions packages/lib-components/src/components/inputs/TextField/Generic.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { cloneElement, useState, ChangeEvent, ReactElement, forwardRef } from 'react';
import { InputContainer, Input, PrefixContainer, SuffixContainer } from './style';
import {
InputWrapper,
InputContainer,
Input,
PrefixContainer,
SuffixContainer,
HumanReadableCronContainer,
} from './style';
import cronstrue from 'cronstrue';

import { Size } from '../../../styled';
import { AiOutlineEye as ShowPasswordIcon, AiOutlineEyeInvisible as HidePasswordIcon } from 'react-icons/ai';
Expand All @@ -12,7 +20,7 @@ export function isNumber(value: unknown) {
return !isNaN(number) && isFinite(number);
}

export type TextFieldType = 'text' | 'password' | 'email' | 'number';
export type TextFieldType = 'text' | 'password' | 'email' | 'number' | 'cron';

export interface TextFieldProps {
type?: TextFieldType;
Expand Down Expand Up @@ -61,55 +69,74 @@ export const GenericTextField = forwardRef<HTMLInputElement, GenericTextFieldPro
}
};

const cronOutput = type === 'cron' ? showHumanReadableCron(value) : null;

return (
<InputContainer>
{prefix && <PrefixContainer hasError={hasError}>{prefix}</PrefixContainer>}
{icon && cloneElement(icon, { size: 18, className: 'icon' })}
<Input
autoCapitalize="off"
autoComplete={type === 'password' ? 'new-password' : 'off'}
hasError={hasError}
hasIcon={!!icon}
hasPrefix={!!prefix}
hasSuffix={!!suffix}
isPassword={type === 'password'}
id={id}
name={name}
onChange={handleOnChange}
onBlur={onBlur}
onFocus={onFocus}
placeholder={placeholder}
disabled={disabled}
readOnly={readOnly}
role="presentation"
inputMode={getInputMode(type)}
type={getFieldType(type, showPassword)}
ref={ref}
value={value}
aria-readonly={readOnly}
aria-required={required}
aria-describedby={setAriaDescribedBy(name, hasDescription)}
/>
{type === 'password' &&
(showPassword ? (
<HidePasswordIcon
className="password-icon"
onClick={() => {
setShowPassword(false);
}}
size={18}
/>
) : (
<ShowPasswordIcon
className="password-icon"
onClick={() => {
setShowPassword(true);
}}
size={18}
/>
))}
{suffix && <SuffixContainer hasError={hasError}>{suffix}</SuffixContainer>}
</InputContainer>
<InputWrapper>
<InputContainer>
{prefix && <PrefixContainer hasError={hasError}>{prefix}</PrefixContainer>}
{icon && cloneElement(icon, { size: 18, className: 'icon' })}
<Input
autoCapitalize="off"
autoComplete={type === 'password' ? 'new-password' : 'off'}
hasError={hasError}
hasIcon={!!icon}
hasPrefix={!!prefix}
hasSuffix={!!suffix}
isPassword={type === 'password'}
id={id}
name={name}
onChange={handleOnChange}
onBlur={onBlur}
onFocus={onFocus}
placeholder={placeholder}
disabled={disabled}
readOnly={readOnly}
role="presentation"
inputMode={getInputMode(type)}
type={getFieldType(type, showPassword)}
ref={ref}
value={value}
aria-readonly={readOnly}
aria-required={required}
aria-describedby={setAriaDescribedBy(name, hasDescription)}
/>
{type === 'password' &&
(showPassword ? (
<HidePasswordIcon
className="password-icon"
onClick={() => {
setShowPassword(false);
}}
size={18}
/>
) : (
<ShowPasswordIcon
className="password-icon"
onClick={() => {
setShowPassword(true);
}}
size={18}
/>
))}
{suffix && <SuffixContainer hasError={hasError}>{suffix}</SuffixContainer>}
</InputContainer>
{cronOutput && (
<HumanReadableCronContainer isError={cronOutput.isError}>{cronOutput.value}</HumanReadableCronContainer>
)}
</InputWrapper>
);
},
);

function showHumanReadableCron(cron: string) {
if (cron === '') {
return { value: '', isError: false };
}

try {
return { value: cronstrue.toString(cron), isError: false };
} catch (e) {
return { value: `${e}`, isError: true };
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export const OnChange: StoryFn<TextFieldProps> = (args) => {
return (
<>
<TextField
type={args.type}
type="cron"
name={args.name}
description={args.description}
control={control}
Expand Down Expand Up @@ -193,3 +193,23 @@ export const Generic: StoryFn = () => {
</>
);
};

export const Cron: StoryFn = () => {
const [value, setValue] = useState<string>('');

return (
<GenericTextField
type="cron"
hasError={false}
onChange={(e) => setValue(e.target.value)}
placeholder="placeholder"
required={false}
name="name"
value={value}
id="generic-text-field"
hasDescription={false}
disabled={false}
readOnly={false}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ export const Container = styled.div`
position: relative;
`;

export const InputWrapper = styled.div``;

export const InputContainer = styled.div`
width: 100%;
position: relative;
Expand Down Expand Up @@ -66,6 +68,10 @@ export const SuffixContainer = styled.div<{ hasError: boolean }>`
white-space: nowrap;
`;

export const HumanReadableCronContainer = styled.div<{ isError: boolean }>`
color: ${({ theme, isError }) => (isError ? theme.colors.error : theme.colors.textAlt)};
`;

export const Input = styled.input<{
hasIcon: boolean;
hasError: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { TextFieldType } from './Generic';
export const getFieldType = (type: TextFieldType, passwordVisible: boolean) => {
// we only use the type number to transform the output to number
// so that zod is happy
if (passwordVisible || type === 'number') {
if (passwordVisible || type === 'number' || type === 'cron') {
return 'text';
}

Expand All @@ -13,7 +13,7 @@ export const getFieldType = (type: TextFieldType, passwordVisible: boolean) => {
type InputModes = 'text' | 'email' | 'search' | 'tel' | 'url' | 'none' | 'numeric' | 'decimal';

export const getInputMode = (type: TextFieldType): InputModes => {
if (type === 'password') return 'text';
if (type === 'password' || type === 'cron') return 'text';
if (type === 'number') return 'numeric';
return type;
};
6 changes: 3 additions & 3 deletions packages/web-main/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
"@sentry/tracing": "7.114.0",
"@tanstack/react-query": "5.56.2",
"@tanstack/react-query-devtools": "5.58.0",
"@tanstack/react-router": "1.58.15",
"@tanstack/router-devtools": "1.58.15",
"@tanstack/router-vite-plugin": "1.58.12",
"@tanstack/react-router": "1.79.0",
"@tanstack/router-devtools": "1.79.0",
"@tanstack/router-vite-plugin": "1.79.0",
"luxon": "3.5.0",
"react-dnd": "16.0.1",
"react-dnd-html5-backend": "16.0.1",
Expand Down
4 changes: 2 additions & 2 deletions packages/web-main/src/components/Navbar/GameServerNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ export const GameServerNav: FC = () => {

return (
<Nav data-testid="server-nav">
{gameServerId && gameServerId !== '' && gameservers && gameservers.length > 0 ? (
{gameServerId && gameServerId !== '' && gameservers && gameservers.data.length > 0 ? (
<>
<h3>Game Server</h3>
{gameservers.length > 1 && <GlobalGameServerSelect currentSelectedGameServerId={gameServerId} />}
{gameservers.data.length > 1 && <GlobalGameServerSelect currentSelectedGameServerId={gameServerId} />}
{gameServerLinks.map((link) => renderLink(link))}
</>
) : (
Expand Down
24 changes: 15 additions & 9 deletions packages/web-main/src/components/Player.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Avatar, Chip, getInitials } from '@takaro/lib-components';
import { Avatar, Chip, getInitials, Tooltip } from '@takaro/lib-components';
import { playerQueryOptions } from 'queries/player';
import { FC } from 'react';
import { Link } from '@tanstack/react-router';
Expand Down Expand Up @@ -46,13 +46,19 @@ export const Player: FC<PlayerProps> = ({ playerId, name, avatarUrl, showAvatar,
);

return (
<Link
to={'/player/$playerId'}
params={{ playerId }}
style={{ display: 'flex', alignItems: 'center', gap: '0.5rem', width: 'fit-content' }}
>
{showAvatar && avatar}
<span>{name}</span>
</Link>
<Tooltip>
<Tooltip.Trigger>
<Link
className="underline"
to={'/player/$playerId'}
params={{ playerId }}
style={{ display: 'flex', alignItems: 'center', gap: '0.5rem', width: 'fit-content' }}
>
{showAvatar && avatar}
<span>{name}</span>
</Link>
</Tooltip.Trigger>
<Tooltip.Content>Open player profile</Tooltip.Content>
</Tooltip>
);
};
Loading

0 comments on commit cd51d45

Please sign in to comment.