Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
@bitnoi.se/react-scheduler
Advanced tools
✨ https://scheduler.bitnoise.pl/ ✨ Open sourced, typescript orien
✨ https://scheduler.bitnoise.pl/ ✨
Open sourced, typescript oriented, light-weight, and ultra fast React Component for creating gantt charts.
We're thrilled that our component has caught your interest! We'd love to see how you're using it in your projects.
Share descriptions and screenshots of your projects that feature Scheduler, and you could be one of 5 lucky winners to receive our limited edition hoodies!
This promotion runs until September 25, 2024. For more information, click here: Scheduler in your projects 🎉
Can't wait to see your amazing work! Good luck!
If you want to stay updated with Scheduler updates and news from the technical world, sign up for our newsletter. We don't spam (we send emails once a month), we don't run a sales newsletter, and we respect your time.
See for yourself: NEWSLETTER
# yarn
yarn add '@bitnoi.se/react-scheduler'
# npm
npm install '@bitnoi.se/react-scheduler'
import "@bitnoi.se/react-scheduler/dist/style.css";
import { Scheduler, SchedulerData } from "@bitnoi.se/react-scheduler";
import dayjs from "dayjs";
default export function Component() {
const [filterButtonState, setFilterButtonState] = useState(0);
const [range, setRange] = useState({
startDate: new Date(),
endDate: new Date()
});
const handleRangeChange = useCallback((range) => {
setRange(range);
}, []);
// Filtering events that are included in current date range
// Example can be also found on video https://youtu.be/9oy4rTVEfBQ?t=118&si=52BGKSIYz6bTZ7fx
// and in the react-scheduler repo App.tsx file https://github.com/Bitnoise/react-scheduler/blob/master/src/App.tsx
const filteredMockedSchedulerData = mockedSchedulerData.map((person) => ({
...person,
data: person.data.filter(
(project) =>
// we use "dayjs" for date calculations, but feel free to use library of your choice
dayjs(project.startDate).isBetween(range.startDate, range.endDate) ||
dayjs(project.endDate).isBetween(range.startDate, range.endDate) ||
(dayjs(project.startDate).isBefore(range.startDate, "day") &&
dayjs(project.endDate).isAfter(range.endDate, "day"))
)
}))
return (
<section>
<Scheduler
data={filteredMockedSchedulerData}
isLoading={isLoading}
onRangeChange={handleRangeChange}
onTileClick={(clickedResource) => console.log(clickedResource)}
onItemClick={(item) => console.log(item)}
onFilterData={() => {
// Some filtering logic...
setFilterButtonState(1);
}}
onClearFilterData={() => {
// Some clearing filters logic...
setFilterButtonState(0)
}}
config={{
zoom: 0,
filterButtonState,
}}
/>
</section>
);
}
const mockedSchedulerData: SchedulerData = [
{
id: "070ac5b5-8369-4cd2-8ba2-0a209130cc60",
label: {
icon: "https://picsum.photos/24",
title: "Joe Doe",
subtitle: "Frontend Developer"
},
data: [
{
id: "8b71a8a5-33dd-4fc8-9caa-b4a584ba3762",
startDate: new Date("2023-04-13T15:31:24.272Z"),
endDate: new Date("2023-08-28T10:28:22.649Z"),
occupancy: 3600,
title: "Project A",
subtitle: "Subtitle A",
description: "array indexing Salad West Account",
bgColor: "rgb(254,165,177)"
},
{
id: "22fbe237-6344-4c8e-affb-64a1750f33bd",
startDate: new Date("2023-10-07T08:16:31.123Z"),
endDate: new Date("2023-11-15T21:55:23.582Z"),
occupancy: 2852,
title: "Project B",
subtitle: "Subtitle B",
description: "Tuna Home pascal IP drive",
bgColor: "rgb(254,165,177)"
},
{
id: "3601c1cd-f4b5-46bc-8564-8c983919e3f5",
startDate: new Date("2023-03-30T22:25:14.377Z"),
endDate: new Date("2023-09-01T07:20:50.526Z"),
occupancy: 1800,
title: "Project C",
subtitle: "Subtitle C",
bgColor: "rgb(254,165,177)"
},
{
id: "b088e4ac-9911-426f-aef3-843d75e714c2",
startDate: new Date("2023-10-28T10:08:22.986Z"),
endDate: new Date("2023-10-30T12:30:30.150Z"),
occupancy: 11111,
title: "Project D",
subtitle: "Subtitle D",
description: "Garden heavy an software Metal",
bgColor: "rgb(254,165,177)"
}
]
}
];
Property Name | Type | Arguments | Description |
---|---|---|---|
isLoading | boolean | - | shows loading indicators on scheduler |
onRangeChange | function | updated startDate and endDate | runs whenever user reaches end of currently rendered canvas |
onTileClick | function | clicked resource data | detects resource click |
onItemClick | function | clicked left column item data | detects item click on left column |
onFilterData | function | - | callback firing when filter button was clicked |
onClearFilterData | function | - | callback firing when clear filters button was clicked (clearing button is visible only when filterButtonState is set to >0 ) |
config | Config | - | object with scheduler config properties |
Property Name | Type | Default | Description |
---|---|---|---|
zoom | 0 or 1 or 2 | 0 | 0 - display grid divided into weeks 1 - display grid divided into days 2 - display grid divided into hours |
filterButtonState | number | 0 | < 0 - hides filter button, 0 - state for when filters were not set, > 0 - state for when some filters were set (allows to also handle onClearFilterData event) |
maxRecordsPerPage | number | 50 | number of items from SchedulerData visible per page |
lang | en , lt or pl | en | scheduler's language |
includeTakenHoursOnWeekendsInDayView | boolean | false | show weekends as taken when given resource is longer than a week |
showTooltip | boolean | true | show tooltip when hovering over tiles |
translations | LocaleType[] | undefined | option to add specific langs translations |
showThemeToggle | boolean | false | show toggle button to switch between light/dark mode |
defaultTheme | light or dark | light | scheduler's default theme |
import enDayjsTranslations from "dayjs/locale/en";
const langs: LocaleType[] = [
{
id: "en",
lang: {
feelingEmpty: "I feel so empty...",
free: "Free",
loadNext: "Next",
loadPrevious: "Previous",
over: "over",
taken: "Taken",
topbar: {
filters: "Filters",
next: "next",
prev: "prev",
today: "Today",
view: "View"
},
search: "search",
week: "week"
},
translateCode: "en-EN",
dayjsTranslations: enDayjsTranslations
}
];
<Scheduler
// ... //
config={{
lang: "en",
translations: langs
}}
/>;
Property Name | Type | Description |
---|---|---|
id | string | key is needed for selecting lang |
lang | Translation | object with translations |
translateCode | string | code that is saved in localStorage |
dayjsTranslations | string ILocale undefined | object with translation from dayjs |
Property Name | Type |
---|---|
feelingEmpty | string |
free | string |
loadNext | string |
loadPrevious | string |
over | string |
taken | string |
search | string |
week | string |
topbar | Topbar |
Property Name | Type |
---|---|
filters | string |
next | string |
prev | string |
today | string |
view | string |
array of chart rows with shape of
Property Name | Type | Description |
---|---|---|
id | string | unique row id |
label | SchedulerRowLabel | row's label, e.g person's name, surname, icon |
data | Array<ResourceItem> | array of resources |
data that is accessible as argument of onItemClick
callback
Property Name | Type | Description |
---|---|---|
id | string | unique row id |
label | SchedulerRowLabel | row's label, e.g person's name, surname, icon |
item that will be visible on the grid as tile and that will be accessible as argument of onTileClick
event
Property Name | Type | Description |
---|---|---|
id | string | unique resource id |
title | string | resource title that will be displayed on resource tile |
subtitle | string (optional) | resource subtitle that will be displayed on resource tile |
description | string (optional) | resource description that will be displayed on resource tile |
startDate | Date | date for calculating start position for resource |
endDate | Date | date for calculating end position for resource |
occupancy | number | number of seconds resource takes up for given row that will be visible on resource tooltip when hovered |
bgColor | string (optional) | tile color |
@bitnoi.se/react-scheduler
to serverDependenciesToBundle
in remix.config.js
like so:// remix.config.js
/** @type {import('@remix-run/dev').AppConfig} */
module.exports = {
// ...
serverDependenciesToBundle: [..., "@bitnoi.se/react-scheduler"],
};
use client
"use client"
import { Scheduler, SchedulerProps } from "@bitnoi.se/react-scheduler";
default export function SchedulerClient(props: SchedulerProps) {
return <Scheduler {...props} />;
}
dynamic
:import dynamic from "next/dynamic";
const Scheduler = dynamic(() => import("@bitnoi.se/react-scheduler").then((mod) => mod.Scheduler), {
ssr: false
});
Scheduler is position absolutely to take all available space. If you want to have fixed dimensions wrap Scheduler inside a div with position set to relative.
Example using styled components:
export const StyledSchedulerFrame = styled.div`
position: relative;
height: 40vh;
width: 40vw;
`;
<StyledSchedulerFrame>
<Scheduler {...}/>
</StyledSchedulerFrame>
git checkout -b feat/your-branch-name
.master
branch.
If you have any questions or need further assistance, feel free to reach out to us at scheduler@bitnoi.se. We appreciate your contributions and thank you for helping us improve this project!
MIT Licensed. Copyright (c) Bitnoise 2023.
FAQs
✨ https://scheduler.bitnoise.pl/ ✨ Open sourced, typescript orien
The npm package @bitnoi.se/react-scheduler receives a total of 1,244 weekly downloads. As such, @bitnoi.se/react-scheduler popularity was classified as popular.
We found that @bitnoi.se/react-scheduler demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.