[#106] added prettier check to jenkins and prettified files (#109)

Co-authored-by: Camille Moussu <cmoussu@linagora.com>
This commit is contained in:
Camille Moussu
2025-09-12 11:05:52 +02:00
committed by GitHub
parent 3b87965bed
commit d76775c7d2
16 changed files with 108 additions and 84 deletions
Vendored
+5
View File
@@ -26,6 +26,11 @@ pipeline {
sh 'npm run test'
}
}
stage('Check Formatting') {
steps {
sh 'npx prettier --check .'
}
}
stage('Deploy docker images') {
when {
anyOf {
+16 -3
View File
@@ -8,11 +8,20 @@ This project aims at service a Single Page Application allowing a user to intera
This frontend-only application will interact with:
- [esn-sabre](https://github.com/linagora/esn-sabre/) CalDAV + CardDAV server, tailor made for LINAGORA needs.
- [Twake Calendar side service](https://github.com/linagora/twake-calendar-side-service) that delivers additional backend features for Sabre.
- [esn-sabre](https://github.com/linagora/esn-sabre/) CalDAV + CardDAV server, tailor made for LINAGORA needs.
- [Twake Calendar side service](https://github.com/linagora/twake-calendar-side-service) that delivers additional backend features for Sabre.
It is meant as a drop in replacement of [esn-frontend-calendar](https://github.com/linagora/esn-frontend-calendar).
## Contributing
### Formating
We use [Prettier](https://prettier.io/) to keep code style consistent.
A `.prettierrc` file is already included in the repo, so formatting rules are predefined.
Before committing, make sure you format your files either using your IDE Prettier extension or Prettier CLI.
## Running it
Requirement: node 24+
@@ -89,7 +98,11 @@ Example:
```js
var appList = [
{ name: "My App", icon: "https://myapp.com/myapp.png", link: "https://myapp.com" },
{
name: "My App",
icon: "https://myapp.com/myapp.png",
link: "https://myapp.com",
},
];
```
@@ -111,7 +111,7 @@ describe("CalendarApp integration", () => {
openpaasId: "667037022b752d0026472254",
},
tokens: {
accessToken: "token"
accessToken: "token",
},
},
calendars: {
@@ -133,14 +133,16 @@ describe("CalendarApp integration", () => {
cn: "Alice",
cal_address: "alice@example.com",
},
attendee: [{
cn: "Alice",
partstat: "ACCEPTED",
rsvp: "TRUE",
role: "REQ-PARTICIPANT",
cutype: "INDIVIDUAL",
cal_address: "alice@example.com",
}, ],
attendee: [
{
cn: "Alice",
partstat: "ACCEPTED",
rsvp: "TRUE",
role: "REQ-PARTICIPANT",
cutype: "INDIVIDUAL",
cal_address: "alice@example.com",
},
],
...eventProps,
},
},
+20 -19
View File
@@ -57,33 +57,34 @@ describe("MiniCalendar", () => {
});
it.each([
{ today: new Date(2025, 8, 1), label: "Monday 1 Sept 2025" },
{ today: new Date(2025, 8, 3), label: "Wednesday 3 Sept 2025" },
{ today: new Date(2025, 8, 7), label: "Sunday 7 Sept 2025" },
{ today: new Date(2025, 8, 1), label: "Monday 1 Sept 2025" },
{ today: new Date(2025, 8, 3), label: "Wednesday 3 Sept 2025" },
{ today: new Date(2025, 8, 7), label: "Sunday 7 Sept 2025" },
])(
"renders mini calendar with the week in gray (except for today) when today is $label",
({ today }) => {
jest.useFakeTimers();
jest.setSystemTime(today);
"renders mini calendar with the week in gray (except for today) when today is $label",
({ today }) => {
jest.useFakeTimers();
jest.setSystemTime(today);
renderCalendar();
renderCalendar();
const monday = new Date(2025, 8, 1); // Monday Sept 1
const monday = new Date(2025, 8, 1); // Monday Sept 1
for (let i = 0; i < 7; i++) {
const date = new Date(monday);
date.setDate(monday.getDate() + i);
const dateTestId = `date-${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`;
for (let i = 0; i < 7; i++) {
const date = new Date(monday);
date.setDate(monday.getDate() + i);
const dateTestId = `date-${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`;
const tile = screen.getByTestId(dateTestId);
const tile = screen.getByTestId(dateTestId);
if (date.getTime() !== today.setHours(0, 0, 0, 0)) {
expect(tile?.parentElement).toHaveClass("selectedWeek");
if (date.getTime() !== today.setHours(0, 0, 0, 0)) {
expect(tile?.parentElement).toHaveClass("selectedWeek");
}
}
}
jest.useRealTimers();
});
jest.useRealTimers();
}
);
it("renders mini calendar with the day in gray (except for today) when full calendar in day view", async () => {
renderCalendar();
@@ -95,15 +95,13 @@ describe("Event Preview Display", () => {
};
it("renders correctly event data", () => {
jest
.spyOn(Date.prototype, "toLocaleString")
.mockImplementation(function (
this: Date,
locales?: Intl.LocalesArgument,
options?: Intl.DateTimeFormatOptions | undefined
): string {
return RealDateToLocaleString.call(this, "en-UK", options);
});
jest.spyOn(Date.prototype, "toLocaleString").mockImplementation(function (
this: Date,
locales?: Intl.LocalesArgument,
options?: Intl.DateTimeFormatOptions | undefined
): string {
return RealDateToLocaleString.call(this, "en-UK", options);
});
renderWithProviders(
<EventPreviewModal
anchorPosition={{ top: 0, left: 0 }}
+2 -2
View File
@@ -1,6 +1,6 @@
module.exports = {
presets: [
['@babel/preset-env', { targets: { node: 'current' } }],
['@babel/preset-react', { runtime: 'automatic', importSource: 'preact' }],
["@babel/preset-env", { targets: { node: "current" } }],
["@babel/preset-react", { runtime: "automatic", importSource: "preact" }],
],
};
+1 -1
View File
@@ -6,4 +6,4 @@ var SSO_RESPONSE_TYPE = "code";
var SSO_CODE_CHALLENGE_METHOD = "S256";
var SSO_POST_LOGOUT_REDIRECT = "http://example.com?logout=1";
var CALENDAR_BASE_URL = "https://calendar.example.com";
var MAIL_SPA_URL = "https://mail.example.com"
var MAIL_SPA_URL = "https://mail.example.com";
+1 -1
View File
@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
+7 -1
View File
@@ -1,5 +1,11 @@
declare namespace Intl {
type Key = 'calendar' | 'collation' | 'currency' | 'numberingSystem' | 'timeZone' | 'unit';
type Key =
| "calendar"
| "collation"
| "currency"
| "numberingSystem"
| "timeZone"
| "unit";
function supportedValuesOf(input: Key): string[];
}
+4 -4
View File
@@ -1,5 +1,5 @@
import { useDispatch, useSelector } from 'react-redux'
import type { RootState, AppDispatch } from './store'
import { useDispatch, useSelector } from "react-redux";
import type { RootState, AppDispatch } from "./store";
export const useAppDispatch = useDispatch.withTypes<AppDispatch>()
export const useAppSelector = useSelector.withTypes<RootState>()
export const useAppDispatch = useDispatch.withTypes<AppDispatch>();
export const useAppSelector = useSelector.withTypes<RootState>();
+3 -1
View File
@@ -133,7 +133,9 @@ main {
/* selected day hover */
.react-calendar__tile {
transition: background-color 0.3s ease, color 0.3s ease;
transition:
background-color 0.3s ease,
color 0.3s ease;
border: none;
background-color: white;
width: 12px;
+15 -6
View File
@@ -31,7 +31,7 @@ import { createSelector } from "@reduxjs/toolkit";
import HelpOutlineIcon from "@mui/icons-material/HelpOutline";
import ClearIcon from "@mui/icons-material/Clear";
import AccessTimeIcon from "@mui/icons-material/AccessTime";
import LockIcon from '@mui/icons-material/Lock';
import LockIcon from "@mui/icons-material/Lock";
import { userAttendee } from "../../features/User/userDataTypes";
const computeStartOfTheWeek = (date: Date): Date => {
@@ -204,7 +204,6 @@ export default function CalendarApp() {
calendarRef.current?.view.type === "timeGridWeek" ||
calendarRef.current?.view.type === undefined
) {
const startOfWeek = computeStartOfTheWeek(selected);
const endOfWeek = new Date(startOfWeek);
@@ -430,7 +429,9 @@ export default function CalendarApp() {
if (!calendars[arg.event._def.extendedProps.calId]) return;
const attendees = event._def.extendedProps.attendee || [];
const isPrivate = event._def.extendedProps.class === "PRIVATE" || event._def.extendedProps.class === "CONFIDENTIAL";
const isPrivate =
event._def.extendedProps.class === "PRIVATE" ||
event._def.extendedProps.class === "CONFIDENTIAL";
let Icon = null;
let titleStyle: React.CSSProperties = {};
const ownerEmails = new Set(
@@ -461,9 +462,17 @@ export default function CalendarApp() {
}
return (
<div style={{ display: 'flex', alignItems: 'center' }}>
{isPrivate && <LockIcon data-testid="lock-icon" fontSize="small" style={{ marginRight: '4px' }} />}
{Icon && <Icon fontSize="small" style={{ marginRight: '4px' }}/>}
<div style={{ display: "flex", alignItems: "center" }}>
{isPrivate && (
<LockIcon
data-testid="lock-icon"
fontSize="small"
style={{ marginRight: "4px" }}
/>
)}
{Icon && (
<Icon fontSize="small" style={{ marginRight: "4px" }} />
)}
<span style={titleStyle}>{event.title}</span>
</div>
);
+5 -2
View File
@@ -28,7 +28,6 @@ function CalendarPopover({
const [timeZone, setTimeZone] = useState("");
const timezones = Intl.supportedValuesOf?.("timeZone") ?? [];
const handleSave = () => {
dispatch(createCalendar({ name, description, color }));
onClose({}, "backdropClick");
@@ -64,7 +63,11 @@ function CalendarPopover({
}}
>
<Box p={2}>
<Typography variant="h6" gutterBottom style={{backgroundColor:color}}>
<Typography
variant="h6"
gutterBottom
style={{ backgroundColor: color }}
>
Create a Calendar
</Typography>
<TextField
+1 -1
View File
@@ -58,7 +58,7 @@ export function parseCalendarEvent(
case "organizer":
event.organizer = {
cn: params?.cn ?? "",
cal_address: value.replace(/^mailto:/, ""),
cal_address: value?.replace(/^mailto:/, ""),
};
break;
case "attendee":
+5 -5
View File
@@ -1,13 +1,13 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
font-family:
-apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu",
"Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
font-family:
source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace;
}
-15
View File
@@ -1,15 +0,0 @@
import { ReportHandler } from 'web-vitals';
const reportWebVitals = (onPerfEntry?: ReportHandler) => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
getLCP(onPerfEntry);
getTTFB(onPerfEntry);
});
}
};
export default reportWebVitals;