Skip to content
Open
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
9 changes: 8 additions & 1 deletion .github/workflows/diracx-web-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,11 @@ jobs:
with:
browser: chrome
config: baseUrl=${{ env.DIRACX_URL }}
project: packages/diracx-web
project: packages/diracx-web

- name: Upload Cypress screenshots
if: failure()
uses: actions/upload-artifact@v4
with:
name: cypress-screenshots
path: packages/diracx-web/cypress/screenshots
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
24.6.0
19,992 changes: 9,129 additions & 10,863 deletions package-lock.json

Large diffs are not rendered by default.

10 changes: 7 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@
"packages/diracx-web",
"packages/extensions"
],
"engines": {
"node": ">=24.6.0 < 25",
"npm": ">=11.5.0"
},
"devDependencies": {
"@commitlint/cli": "^19.7.1",
"@commitlint/config-conventional": "^19.7.1",
"husky": "^9.0.11"
"@commitlint/cli": "^19.8.1",
"@commitlint/config-conventional": "^19.8.1",
"husky": "^9.1.7"
},
"scripts": {
"dev": "npm --prefix packages/diracx-web run dev",
Expand Down
5 changes: 4 additions & 1 deletion packages/diracx-web-components/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,7 @@ next-env.d.ts

# Storybook
*storybook.log
storybook-static
storybook-static

# swap files
.swp
3 changes: 2 additions & 1 deletion packages/diracx-web-components/.storybook/Readme.mdx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Markdown } from "@storybook/blocks";
import { Meta, Markdown } from "@storybook/addon-docs/blocks";
import Readme from "../../../README.md";

<Meta title="README" />
<Markdown> {Readme} </Markdown>
5 changes: 1 addition & 4 deletions packages/diracx-web-components/.storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@ const config: StorybookConfig = {

addons: [
getAbsolutePath("@storybook/addon-links"),
getAbsolutePath("@storybook/addon-essentials"),
getAbsolutePath("@chromatic-com/storybook"),
getAbsolutePath("@storybook/addon-interactions"),
getAbsolutePath("@storybook/addon-mdx-gfm"),
getAbsolutePath("@storybook/addon-docs"),
],

framework: {
Expand Down
11 changes: 11 additions & 0 deletions packages/diracx-web-components/eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@ const compat = new FlatCompat({

// This config is only for typescript files
export default [
{
ignores: [
"dist/*",
"stories/*",
".tsup/*",
".storybook/*",
"*.config.js",
"*.config.ts",
"jest.setup.ts",
],
},
...fixupConfigRules(
compat.extends(
"next/core-web-vitals",
Expand Down
3 changes: 2 additions & 1 deletion packages/diracx-web-components/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ const config = {
"^@axa-fr/react-oidc$": "<rootDir>/stories/mocks/react-oidc.mock.tsx",
"^../../hooks/metadata$": "<rootDir>/stories/mocks/metadata.mock.tsx",
"^./jobDataService$": "<rootDir>/stories/mocks/jobDataService.mock.tsx",
"\\.css$": "<rootDir>/stories/mocks/style.mock.ts",
// To support css import
"\\.(css|less|scss)$": "<rootDir>/stories/mocks/style.mock.ts",
},

// To support ESM modules in Jest
Expand Down
36 changes: 16 additions & 20 deletions packages/diracx-web-components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,24 @@
"dependencies": {
"@atlaskit/pragmatic-drag-and-drop": "^1.3.0",
"@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.0.3",
"@atlaskit/pragmatic-drag-and-drop-react-drop-indicator": "^1.1.0",
"@atlaskit/pragmatic-drag-and-drop-react-drop-indicator": "^3.2.5",
"@axa-fr/react-oidc": "^7.24.0",
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@mui/icons-material": "^6.4.2",
"@mui/material": "^6.1.6",
"@mui/utils": "^6.1.6",
"@mui/x-date-pickers": "^7.28.3",
"@mui/icons-material": "^7.3.1",
"@mui/material": "^7.3.1",
"@mui/utils": "^7.3.1",
"@mui/x-date-pickers": "^8.10.2",
"@tanstack/react-table": "^8.20.5",
"@types/d3": "^7.4.3",
"@types/node": "^20.17.6",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react": "^19.1.10",
"@types/react-dom": "^19.1.7",
"d3": "^7.9.0",
"d3-hierarchy": "^3.1.2",
"dayjs": "^1.11.13",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react": "^19.1.1",
"react-dom": "^19.1.1",
"react-virtuoso": "^4.12.3",
"swr": "^2.2.5"
},
Expand All @@ -48,19 +48,15 @@
"@babel/preset-env": "^7.28.0",
"@babel/preset-react": "^7.24.7",
"@babel/preset-typescript": "^7.24.7",
"@chromatic-com/storybook": "^3.2.4",
"@chromatic-com/storybook": "^4.1.1",
"@eslint/compat": "^1.2.2",
"@eslint/eslintrc": "^3.1.0",
"@eslint/js": "^9.14.0",
"@microsoft/api-extractor": "^7.43.7",
"@storybook/addon-essentials": "^8.6.11",
"@storybook/addon-interactions": "^8.6.11",
"@storybook/addon-links": "^8.5.3",
"@storybook/addon-mdx-gfm": "^8.5.3",
"@storybook/blocks": "^8.5.3",
"@storybook/nextjs": "^8.5.3",
"@storybook/react": "^8.5.3",
"@storybook/test": "^8.5.3",
"@storybook/addon-docs": "^9.1.3",
"@storybook/addon-links": "^9.1.3",
"@storybook/nextjs": "^9.1.3",
"@storybook/react": "^9.1.3",
"@testing-library/jest-dom": "^6.1.4",
"@testing-library/react": "^16.3.0",
"@testing-library/user-event": "^14.5.1",
Expand All @@ -79,8 +75,8 @@
"jest-environment-jsdom": "^29.7.0",
"lint-staged": "^15.2.2",
"prettier": "^3.2.5",
"react-test-renderer": "^18.3.1",
"storybook": "^8.6.12",
"react-test-renderer": "^19.1.1",
"storybook": "^9.1.3",
"ts-jest": "^29.1.2",
"tsup": "^8.0.2",
"typescript": "^5.6.3"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
DialogContent,
DialogContentText,
Button,
Grid2 as Grid,
Grid,
Icon,
IconButton,
} from "@mui/material";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ export function ProfileButton() {
onClose={handleClose}
slotProps={{
paper: {
elevation: 0,
sx: {
overflow: "visible",
filter: "drop-shadow(0px 2px 8px rgba(0,0,0,0.32))",
Expand Down
18 changes: 10 additions & 8 deletions packages/diracx-web-components/src/components/Login/LoginForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -168,14 +168,16 @@ export function LoginForm({
<Autocomplete
options={Object.keys(metadata.virtual_organizations)}
getOptionLabel={(option) => option}
renderInput={(params) => (
<TextField
{...params}
label="Select a Virtual Organization"
variant="outlined"
data-testid="autocomplete-vo-select"
/>
)}
renderInput={(params) => {
return (
<TextField
{...params}
label="Select a Virtual Organization"
variant="outlined"
data-testid="autocomplete-vo-select"
/>
);
}}
value={selectedVO}
onChange={handleVOChange}
sx={{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use client";
import { useContext, useMemo, useEffect } from "react";
import { Typography } from "@mui/material";
import { ApplicationsContext } from "../../contexts";
import { ApplicationsContext } from "../../contexts/ApplicationsProvider";

/**
* ApplicationSelector component renders the currently selected application
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import "dayjs/locale/en-gb"; // Import the locale for dayjs
import { TextField, TextFieldProps } from "@mui/material";

interface CustomDateTimePickerProps
extends Omit<DateTimePickerProps<Dayjs>, "value" | "onChange"> {
extends Omit<DateTimePickerProps, "value" | "onChange"> {
value: string | null;
onDateAccepted: (value: string | null) => void;
handleArrowKeyDown: (event: KeyboardEvent<HTMLInputElement>) => void;
Expand Down Expand Up @@ -64,7 +64,7 @@ export function MyDateTimePicker({
return (
<LocalizationProvider dateAdapter={AdapterDayjs} adapterLocale={"en-gb"}>
<div onClick={(e) => e.stopPropagation()}>
<DateTimePicker<Dayjs>
<DateTimePicker
value={dateValue}
onChange={(val) => setDateValue(val)}
views={["year", "month", "day", "hours", "minutes", "seconds"]}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useState, useRef, useEffect } from "react";

import { Autocomplete, TextField } from "@mui/material";
import { Autocomplete, InputBase } from "@mui/material";

import {
SearchBarTokenEquation,
Expand Down Expand Up @@ -30,7 +30,7 @@ interface SearchFieldProps {
setInputValue: React.Dispatch<React.SetStateAction<string>>;

/** Reference to the input element */
inputRef: React.RefObject<HTMLInputElement>;
inputRef: React.RefObject<HTMLInputElement | null>;

/** The current token equations */
tokenEquations: SearchBarTokenEquation[];
Expand Down Expand Up @@ -262,6 +262,9 @@ export default function SearchField({
}, 0);
}

// Calculate the width of the input field based on the input value length
const width = Math.min(Math.max(inputValue.length * 8 + 50, 150), 800);

const handleDateAccepted = (newValue: string | null) => {
if (newValue) {
handleTokenCreation(
Expand Down Expand Up @@ -300,64 +303,73 @@ export default function SearchField({
minWidth: "180px",
flexGrow: 1,
}}
loading={suggestionsLoading}
disableClearable={true}
options={suggestions.items}
value={inputValue}
onHighlightChange={(_e, option) => {
optionSelectedRef.current = option !== null;
}}
loading={suggestionsLoading}
renderInput={(params) => (
<TextField
{...params}
data-testid="search-field"
variant="standard"
placeholder={placeholder}
inputRef={inputRef}
slotProps={{
input: {
...params.InputProps,
disableUnderline: true,
},
}}
onKeyDown={(e: React.KeyboardEvent<HTMLDivElement>) => {
if (e.key === "Enter" && inputValue && inputValue.trim()) {
if (optionSelectedRef.current) {
optionSelectedRef.current = false;
return;
}
const { nature, type } = getTokenMetadata(
inputValue.trim(),
suggestions,
previousToken,
);
// Always create token on Enter press, regardless of operator type
handleTokenCreation(inputValue.trim(), nature, type);
}
if (e.key === "Backspace") {
handleBackspaceKeyDown();
}
onKeyDown={(e: React.KeyboardEvent<HTMLDivElement>) => {
if (e.key === "Enter" && inputValue && inputValue.trim()) {
if (optionSelectedRef.current) {
optionSelectedRef.current = false;
return;
}
const { nature, type } = getTokenMetadata(
inputValue.trim(),
suggestions,
previousToken,
);
// Always create token on Enter press, regardless of operator type
handleTokenCreation(inputValue.trim(), nature, type);
}
if (e.key === "Backspace") {
handleBackspaceKeyDown();
}

if (e.key === "ArrowLeft" || e.key === "ArrowRight") {
handleArrowKeyDown(e);
}
if (e.key === "ArrowLeft" || e.key === "ArrowRight") {
handleArrowKeyDown(e);
}

if (e.key === "Tab") {
e.preventDefault();
setInputValue((prev) => {
const options = suggestions.items.filter((val) => {
return val.toLowerCase().startsWith(prev.toLowerCase());
});
return options[0] || prev;
});
}
if (e.key === "Escape") {
setFocusedTokenIndex(null);
setInputValue("");
}
}}
/>
)}
if (e.key === "Tab") {
e.preventDefault();
setInputValue((prev) => {
const options = suggestions.items.filter((val) => {
return val.toLowerCase().startsWith(prev.toLowerCase());
});
return options[0] || prev;
});
}
if (e.key === "Escape") {
setFocusedTokenIndex(null);
setInputValue("");
}
}}
renderInput={(params) => {
const { InputProps: autoInputProps, inputProps } = params;

return (
<InputBase
placeholder={placeholder}
className={autoInputProps.className}
startAdornment={autoInputProps.startAdornment}
data-testid="search-field"
endAdornment={autoInputProps.endAdornment}
onMouseDown={autoInputProps.onMouseDown}
inputRef={(node) => {
const r = autoInputProps.ref;
if (typeof r === "function") r(node);
else if (r) r.current = node;
if (inputRef) inputRef.current = node;
}}
inputProps={{
...inputProps,
style: { width: `${width}px` },
}}
/>
);
}}
onChange={(_e, value: string | null) => {
if (value && value !== "") {
optionSelectedRef.current = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ export function Sunburst({
const finalColorScales = colorScales || defaultColorScale;

const svgRef = useRef(null);
const tooltipRef: React.RefObject<HTMLDivElement> =
useRef<HTMLDivElement>(null);
const tooltipRef: React.RefObject<HTMLDivElement | null> =
useRef<HTMLDivElement | null>(null);

const theme = useTheme();

Expand Down
Loading
Loading