Gantt Gantt Gantt Timeline Schedule Calendar [ javascript gantt, js gantt, projects gantt, timeline, scheduler, gantt timeline, reservation timeline, react gantt, angular gantt, vue gantt, svelte gantt, booking manager ]

Overview

gantt-schedule-timeline-calendar

Gantt, schedule, timeline and calendar components all in one!

gantt-schedule-timeline-calendar

gantt-schedule-timeline-calendar is all-in-one component that you can use in different scenarios.

Keywords: [ gantt, javascript gantt, typescript gantt, project manager, js gantt, js scheduler, js timeline, javascript timeline, javascript schedule, js scheduler, javascript calendar ]




And always remember, to leave a star


FEATURES

  • elastic - you can change almost everything from DOM tree to logic (without any compilation, without modifying original code - with config, state or plugin)
  • super fast! even with large dataset
  • multiple items in one row - suitable for various applications like booking, reservation, resource manager, multimedia editor etc.
  • tree like structures - collapsible / expandable groups
  • moveable / resizable items with ability to configure which items can move at the moment and how
  • secure html templates
  • snap to specified time when resizing / moving
  • templates & slots support to easily change html content of each component
  • background grid on which you can place your html content
  • selectable cells and items with a choice of what can be selected at the moment
  • gradual time zoom up to seconds
  • resizable list columns (in realtime)
  • sortable and searchable list columns
  • BEM based CSS rules (easy to change appearance)
  • you can easily add third party libraries
  • highly configurable
  • plugins support
  • attractive visually
  • written in typescript
  • offline license key

You can use it in react, vue, angular, svelte or any other projects.

You can use it as schedule for reservation system. You can use it for organizing events. You can use it as gantt chart. You can use it as calendar for different purposes. You can even use it as a multimedia timeline editor!

gantt-schedule-timeline-calendar is very extensible and elastic. You can make your own plugins or modify configuration in couple of ways to achieve your goals. You can control almost everything. You can change html structure, stylize every html element and even override original components without any compilation stage!

EXAMPLES

Online examples

To run examples on your machine type

git clone https://github.com/neuronetio/gantt-schedule-timeline-calendar.git
cd gantt-schedule-timeline-calendar
npm i
npm run examples

You can checkout examples folder too.

REACT, ANGULAR AND VUE EXAMPLES

SCREENSHOTS

gantt-schedule-timeline-calendar item types
gantt-schedule-timeline-calendar item types
gantt-schedule-timeline-calendar item types
gantt-schedule-timeline-calendar select cells
gantt-schedule-timeline-calendar linked items
gantt-schedule-timeline-calendar select items
gantt-schedule-timeline-calendar linked-items 2


INSTALL

npm i gantt-schedule-timeline-calendar

or

DOCUMENTATION

Documentation can be found here

NEED HELP?

Let us know (we don't bite) [email protected]

LICENSE

NEURONET Free License

You can generate free license key here. You can use this software for free in non-commercial projects that are under the MIT / ISC license and whose full source code is available on the Internet (backend and frontend). In commercial or closed source projects, you can use it for free for two months only. If you need a full commercial license with all plugins included, please visit pricing page.

Comments
  • custom font in bookmarks

    custom font in bookmarks

    Your question and description of the problem goes here is there any way i can put a custom word color as the background, i tried to use className but it is not working for me

    Code

    
    .warning{
    	font-size:40px;
    	color:black;
    }
    
    
    let keyName = "event-" + selectedEventId;
    			let bookmark = {};
    			bookmark[keyName] = {
    				time: GSTC.api.date(events[selectedEventId].dateTime).valueOf(),
    				label: `${selectedEventId} • ${self.bookmarkLabel}`,
    				color,
    				className: "warning"				
    			};
    			temp[keyName] = bookmark[keyName];
    			state.update("config.plugin.TimeBookmarks.bookmarks", temp);		
    

    Screenshots or movies / GIF's image

    🐛 Bug 
    opened by Khaplann 24
  • utcMode does not work properly

    utcMode does not work properly

    I have the following problem: when setting the day on "11/07/2021" and error occurs, and from my testing that occurs because of the change from EST to EDT in the USA, I don't have that problem when setting another day.

    I tested with the example that is in the Docs Example, I just changed the following:

     function updateTime() {
        if (loading) return;
        const startTime = api.time
          .date("11/07/2021") // changed line
          .startOf('day')
          .valueOf();
        const endTime = api.time
          .date("11/07/2021") // changed line
          .endOf('day')
          .valueOf();
        loading = 'LOADING... You can load items from backend now.';
        overlay = 'overlay';
        setTimeout(() => {
          // if you have items you can change view
          state.update('config.chart.time', (time) => {
            time.from = startTime;
            time.to = endTime;
            console.log(`${year}-${month + 1}-01`, `${year}-${month + 1}-01`);
            return time;
          });
          loading = '';
          overlay = '';
        }, 250);
      }
    

    Video running the example

    https://user-images.githubusercontent.com/70602890/143452367-c67ebe00-a4f1-4f97-b49c-a81884389190.mp4

    Video running my app

    https://user-images.githubusercontent.com/70602890/143453286-111911e7-4cee-4eab-b6f4-b46d447b36b1.mp4

    In my example, when I go backward, e.g. from 11/08/2021 to 11/07/2021 the error occurs, and when I go from 11/06/2021 to 11/07/2021 it works fine

    🐛 Bug 
    opened by francofgp 21
  • How to clean memory

    How to clean memory

    Is there a way to clean the memory when updating the rows and items? Because right now, when I update my rows and items like this:

    state.update("config.list.rows", myRows);
    state.update("config.chart.items",myItems);
    

    When I do that often my JS Heap starts to grow, and I don't know if there is a way to clean the memory manually, because sometimes the library (I think) release memory, but I don't know when that occurs.

    Image description of the problem: image

    You can see the video as well:

    https://user-images.githubusercontent.com/70602890/139685434-000caf3d-1314-4972-a0d2-d3460deadef0.mp4

    Another example: image

    https://user-images.githubusercontent.com/70602890/139688003-883c8a39-fe2b-49db-ae71-393305b45c9d.mp4

    👨‍🏫 Help wanted ❓ Question 
    opened by francofgp 21
  • Errors when sorting

    Errors when sorting

    Describe the bug when I order a column, the tooltip stops showing the information, and an error is generated like, I attach images

    And when I set a new set of rows the scroll does not work correctly, unless I sort it

    What version are you using? gantt-schedule-timeline-calendar version 3.8.3

    Screenshots or movies image

    image

    ezgif com-gif-maker_3

    opened by Khaplann 17
  • The horizontal scroll bar moves too far to the left

    The horizontal scroll bar moves too far to the left

    Describe the bug in the version 3.14.* the horizontal bar dont show correctly, it start with -40 left, i used the last css, but its work fine in 3.13.* https://github.com/neuronetio/gantt-schedule-timeline-calendar/blob/master/dist/style.css

    gantt-schedule-timeline-calendar version What version are you using? 3.14.16

    Screenshots or movies image

    opened by Khaplann 16
  • Problems deleting or changing columns

    Problems deleting or changing columns

    Describe the bug I am having the following problem, when with the state method I pass the information of new columns, if within the new set of columns there is a less columns or a column name change, an error occurs, underfined, I attach images. But if the new dataset has the same columns (even if the order changes) plus new ones, this error does not occur. I am trying to create a functionality to hide and show columns with the radio button or similar.

    gantt-schedule-timeline-calendar version gantt-schedule-timeline-calendar 3.7.14

    Screenshots or movies image

    🐛 Bug 
    opened by Khaplann 16
  • Display bug (glitch) when scrolling vertically

    Display bug (glitch) when scrolling vertically

    Describe the bug When there are few lines on the plugin, when scrolling vertically, the display of the plugin glitch a lot. And the user can't scroll in the page because the plugin captures the scroll.

    To Reproduce Steps to reproduce the behavior:

    1. Go to https://github.com/neuronetio/vue-gantt-schedule-timeline-calendar
    2. Scroll down on the schedule
    3. See multiple glitch

    Expected behavior

    • Scroll the page (if the page containing the plugin is of course big enough to scroll).
    • If all the lines of the plugin can be displayed without scrolling inside the plugin. The plugin should not capture the scroll event, to allow normal scrolling on the page.
    • Nothing should happen if the page is like in the Vue.js example (https://github.com/neuronetio/vue-gantt-schedule-timeline-calendar)

    Screenshots (I scroll) ezgif com-video-to-gif

    Desktop (please complete the following information):

    • OS: Mac OS,
    • Browser: Chrome
    • Version: Latest

    Additional context Thanks you a lot for all your work !

    opened by XStarlink 14
  • Issue in updating/resetting items in v3 - Help needed

    Issue in updating/resetting items in v3 - Help needed

    Tried to load the chart initially with 1 rows and 1 items. After button click, trying to update the chart with 100 rows and 100 items. (this.generateConfig(100) method) Chart renders 100 rows, whereas the items are not showing up. version - 3.6.5

    Sample snippet

      generateConfig(iterations) {
        let rows = {};
        for (let i = 0; i < iterations; i++) {
          const withParent = i > 0 && i % 2 === 0;
          const id = GSTC.api.GSTCID(i.toString());
          rows[id] = {
            id,
            label: 'Room ' + i,
            parentId: withParent ? GSTC.api.GSTCID((i - 1).toString()) : undefined,
            expanded: false,
          };
        }
        let start = GSTC.api.date().startOf('day').subtract(30, 'day');
        let items = {};
        for (let i = 0; i < iterations; i++) {
          const id = GSTC.api.GSTCID(i.toString());
          start = start.add(1, 'day');
          items[id] = {
            id,
            label: 'User id ' + i,
            time: {
              start: start.valueOf(),
              end: start.add(1, 'day').valueOf(),
            },
            rowId: id,
          };
        }
        let columns = {
          percent: 100,
          resizer: {
            inRealTime: true,
          },
          data: {
            [GSTC.api.GSTCID('label')]: {
              id: GSTC.api.GSTCID('label'),
              data: 'label',
              expander: true,
              isHtml: true,
              width: 230,
              minWidth: 100,
              header: {
                content: 'Room',
              },
            },
          },
        };
        return ({ rows, columns, items });
      }
      updateConfig(rows, columns, items): Config {
        return {
          licenseKey: '',
          list: {
            rows,
            columns,
          },
          chart: {
            items,
          },
          plugins: [TimelinePointer(), Selection()],
        };
      }  
      ngOnInit(): void {
        let elements = this.generateConfig(1);
        this.gstc = GSTC({
          element: this.gstcElement.nativeElement,
          state: GSTC.api.stateFromConfig(this.updateConfig(elements.rows, elements.columns, elements.items)),
        });
      }
      updateChart(): void {
        let elements = this.generateConfig(100);
        // this.gstc.state.update('config.chart.items', {});
        // this.gstc.state.update('config.chart.rows', {});
        // this.gstc.state.update('config.list.rows', this.rows);
        // this.gstc.state.update('config.list.items', this.items);
        this.gstc.state.update('config', (config) => {
          config.list.rows = elements.rows;
          config.list.items = elements.items;
          return config;
        });
      }
    

    Initial load image After button press image

    opened by rajeshtechnospurs 13
  • items disappear when changing the zoom

    items disappear when changing the zoom

    Describe the bug when I set a new zoom value some items disappear. en the photo with 6 hour i see 10 elements but with 8 hours i see 8 elements.

    Code Paste your code here with example data.

    const minutes = [
    	{
    		zoomTo: 12,
    		period: "minute",
    		periodIncrement: 5,
    		main: true,
    		format({ timeStart, vido }) {
    			return formatDate(timeStart, vido);
    		},
    	},
    	{
    		zoomTo: 13,
    		period: "minute",
    		periodIncrement: 10,
    		main: true,
    		format({ timeStart, vido }) {
    			return formatDate(timeStart, vido);
    		},
    	},
    	{
    		zoomTo: 13.9,
    		period: "minute",
    		periodIncrement: 15,
    		main: true,
    		format({ timeStart, vido }) {
    			return formatDate(timeStart, vido);
    		},
    	},
    	{
    		zoomTo: 14,
    		period: "minute",
    		periodIncrement: 20,
    		main: true,
    		format({ timeStart, vido }) {
    			return formatDate(timeStart, vido);
    		},
    	},
    	{
    		zoomTo: 14.5,
    		period: "minute",
    		periodIncrement: 30,
    		main: true,
    		format({ timeStart, vido }) {
    			return formatDate(timeStart, vido);
    		},
    	},
    	{
    		zoomTo: 15.5,
    		period: "minute",
    		periodIncrement: 60,
    		main: true,
    		format({ timeStart, vido }) {
    			return formatDate(timeStart, vido);
    		},
    	},
    	{
    		zoomTo: 16.5,
    		period: "minute",
    		periodIncrement: 120,
    		main: true,
    		format({ timeStart, vido }) {
    			return formatDate(timeStart, vido);
    		},
    	},
    	{
    		zoomTo: 17.5,
    		period: "minute",
    		periodIncrement: 240,
    		main: true,
    		format({ timeStart, vido }) {
    			return formatDate(timeStart, vido);
    		},
    	},
    	{
    		zoomTo: 18,
    		period: "minute",
    		periodIncrement: 360,
    		main: true,
    		format({ timeStart, vido }) {
    			return formatDate(timeStart, vido);
    		},
    	},
    	{
    		zoomTo: 18.5,
    		period: "minute",
    		periodIncrement: 480,
    		main: true,
    		format({ timeStart, vido }) {
    			return formatDate(timeStart, vido);
    		},
    	},
    	{
    		zoomTo: 19,
    		period: "minute",
    		periodIncrement: 720,
    		main: true,
    		format({ timeStart, vido }) {
    			return formatDate(timeStart, vido);
    		},
    	},	
    	},
    

    gantt-schedule-timeline-calendar version What version are you using? 3.11.2

    Screenshots or movies image image

    opened by Khaplann 12
  • innerHeight to the bottom

    innerHeight to the bottom

    Is there a way to put this property in something like "auto", without having to put the height in pixels? That way it will be helpful for different screen sizes

    🔧 Enhancement 
    opened by francofgp 12
  • How do I use

    How do I use "tippy" in a react project

    When I use in the project:

    if (!tippyInstance) tippyInstance = tippy(element);

    it will report an error:

    Line 916:43:'tippy' is not defined

    How to introduce "https://unpkg.com/tippy.js@6" in the react project

    opened by 1144075799 12
  • Example of how to select an item programmatically

    Example of how to select an item programmatically

    Your question and description of the problem goes here Could you please provide an example of how we could tell the calendar to select a calendar item with code? We are wanting another component to allow a user to select a row of data, and for that item to be selected in the calendar to trigger other events.

    We experimented with selectItems on the Selection plugin, but were not able to properly trigger a selection.

    Thank you!

    👨‍🏫 Help wanted ❓ Question 
    opened by ivanmayes 0
  • [Angular] How to give a component variable the value of a clicked item

    [Angular] How to give a component variable the value of a clicked item

    Your question and description of the problem goes here How can give my variable the value of an item I clicked on? I can't use classwide varibales with this. inside of the action function. I want to display an item's properties, e.g. label, color, time, inside of another html element. In my case I want to set the variable selectedTimeslot to the item that has been clicked on.

    Code You can paste your code and data examples here if it will help to answer the question.

    // the timeslot the user clicked one; the interface TimeSlot looks like this:
    // https://gantt-schedule-timeline-calendar.neuronet.io/documentation/configuration/chart/items
    public selectedTimeslot: TimeSlot = {} as TimeSlot;
    
    public clickAction(element: any, data: any) {
        function onClick(event: any) {
          console.log(data.item); 
          console.log(GSTC.api.sourceID(data.item.id));
        }
    
        element.addEventListener('click', onClick);
    
        return {
          update(element: any, newData: any) {
            data = newData;
          },
    
          destroy(element: any, data: any) {
            element.removeEventListener("click", onClick);
          },
        };
      }
      
      // somewhere in the config
      const config = {
      /* ... */
      actions: {
        'chart-timeline-items-row-item': [this.clickAction],
      },
      /* ... */
    };
    

    Now I want public selectedTimeslot to be data.item - how can I achieve that?

    Thanks a lot in advance!

    👨‍🏫 Help wanted ❓ Question 
    opened by Dako390 3
  • How to get variable height on multiple GSTCs depending on filled rows

    How to get variable height on multiple GSTCs depending on filled rows

    Your question and description of the problem goes here Is there a way to adapt the total height of the calendar depending on the rows used?

    Currently I am using 4 gstcs below each other. Some have 3 rows, others only have 2 rows. Some have multiple entries in a single row, some only have a single entry per row. Depending on the amount of rows and overlapping items per row, each of those gstcs needs to have a different height. If I am adding a new entry to a specific gstc, its height needs to increase.

    How am I able to automatically adapt the height of each gstc and not set a fixed height in a wrapper?

    Code Second question is if I am using the correct way to display all calendars in Angular.

    ngOnInit(): void {
        const state1: DeepState<Config> = GSTC.api.stateFromConfig(this.generateConfig1());
        this.gstc = GSTC({
          element: (this.gsctFirstRow?.nativeElement as HTMLElement),
          state: state1,
        });
        const state2: DeepState<Config> = GSTC.api.stateFromConfig(this.generateConfig2());
        this.gstc = GSTC({
          element: (this.gsctSecondRow?.nativeElement as HTMLElement),
          state: state2,
        });
        const state3: DeepState<Config> = GSTC.api.stateFromConfig(this.generateConfig3());
        this.gstc = GSTC({
          element: (this.gsctThirdRow?.nativeElement as HTMLElement),
          state: state3,
        });
        const state4: DeepState<Config> = GSTC.api.stateFromConfig(this.generateConfig4());
        this.gstc = GSTC({
          element: (this.gsctFourthRow?.nativeElement as HTMLElement),
          state: state4,
        });
      }
    

    Thank you very much in advance.

    👨‍🏫 Help wanted ❓ Question 
    opened by Dako390 3
  • How to clear selected items (delete selected items)

    How to clear selected items (delete selected items)

    I'm using the selection plugin to allow the user to select multiple items and then delete them. Deletion works fine by removing them from the state, but then I interact with the chart in some way (pan, zoom etc) and the selection plugin code throws an error. I suspect this is because I have not cleared the selection state and it's trying to link to items that are no longer there.

    Code

    Uncaught TypeError: Cannot read properties of undefined (reading 'linkedWith')
        at a.collectLinkedItems (selection.esm.min.js?e25d:13:1)
        at a.getSelectedItem (selection.esm.min.js?e25d:13:1)
        at a.selectItemsIndividually (selection.esm.min.js?e25d:13:1)
        at a.onPointerData (selection.esm.min.js?e25d:13:1)
        at a.onTimelinePointerUp (selection.esm.min.js?e25d:13:1)
        at eval (timeline-pointer.esm.min.js?845d:13:1)
        at Set.forEach (<anonymous>)
        at s.apiTriggerPointerListener (timeline-pointer.esm.min.js?845d:13:1)
        at s.pointerUp (timeline-pointer.esm.min.js?845d:13:1)
    
    function deleteAssignments(){
          if(selectedAssignments) {
            selectedAssignments.forEach(assignment => {
              state.update(`config.chart.items`, (items) => { delete items[assignment.id]; return items } )
            })
            state.update("config.plugin.selection.selected.chart-timeline-items-row-item", [])
            selectedAssignments = null
          }
        }
    

    selectedAssignments is populated with selected["chart-timeline-items-row-item"], so the logic is to loop over the selections and remove each one from the state - then clear all selections from the state.

    🐛 Bug 
    opened by markdturner 3
  • Is possible to create a context menu in a task?

    Is possible to create a context menu in a task?

    Your question and description of the problem goes here When right clicking on a task, I need to open a context menu. I'm having a little trouble getting this to work, I tried adding the itemSlot but it didn't work. Firstly, is it possible to do this? If yes how?

    Code

    Screenshots or movies / GIF's

    👨‍🏫 Help wanted ❓ Question 
    opened by fspaulo 3
Obsidian Full Calendar Plugin

Obsidian Full Calendar Plugin Keep your calendar in your vault! This plugin integrates the FullCalendar library into your Obsidian Vault so that you c

Davis Haupt 343 Dec 30, 2022
A refreshing JavaScript Datepicker — lightweight, no dependencies, modular CSS

Pikaday A refreshing JavaScript Datepicker Lightweight (less than 5kb minified and gzipped) No dependencies (but plays well with Moment.js) Modular CS

null 7.9k Jan 4, 2023
JavaScript Date Range, Date and Time Picker Component

Date Range Picker This date range picker component creates a dropdown menu from which a user can select a range of dates. I created it while building

Dan Grossman 10.6k Dec 29, 2022
A Tempermonky / Greasemonkey plugin which can help you export your class schedule to the calendar on your phone / pad / PC / Mac.

WHU Class Schedule Export as iCS Languages: English | 簡體中文 | 繁體中文 Changelog v0.90.1 - Sep 18, 2022 Fix bugs: Fix an error when a class have multiple s

Ostrich_B 6 Sep 7, 2022
Hi there! This is a react native starter which used to build a awesome Event Booking App based on the Figma design. You can download or clone it to speed up your projects.

mcrn-event-booking-app-starter Hi there! This is a react native starter which used to build a awesome Event Booking App based on the Figma design. You

Roy Chen 43 Dec 19, 2022
NativeScript empowers you to access native api's from JavaScript directly. Angular, Vue, Svelte, React and you name it compatible.

NativeScript empowers you to access native APIs from JavaScript directly. The framework currently provides iOS and Android runtimes for rich mobile de

NativeScript 22k Jan 4, 2023
NativeScript empowers you to access native api's from JavaScript directly. Angular, Vue, Svelte, React and you name it compatible.

NativeScript empowers you to access native APIs from JavaScript directly. The framework currently provides iOS and Android runtimes for rich mobile de

NativeScript 22k Jan 4, 2023
Matteo Bruni 4.7k Jan 4, 2023
📓 The UI component explorer. Develop, document, & test React, Vue, Angular, Web Components, Ember, Svelte & more!

Build bulletproof UI components faster Storybook is a development environment for UI components. It allows you to browse a component library, view the

Storybook 75.8k Jan 4, 2023
Matteo Bruni 4.7k Jan 4, 2023
📓 The UI component explorer. Develop, document, & test React, Vue, Angular, Web Components, Ember, Svelte & more!

Build bulletproof UI components faster Storybook is a development environment for UI components. It allows you to browse a component library, view the

Storybook 75.9k Jan 9, 2023
Matteo Bruni 4.7k Jan 4, 2023
📓 The UI component explorer. Develop, document, & test React, Vue, Angular, Web Components, Ember, Svelte & more!

Build bulletproof UI components faster Storybook is a development environment for UI components. It allows you to browse a component library, view the

Storybook 75.9k Jan 9, 2023
Write components once, run everywhere. Compiles to Vue, React, Solid, Angular, Svelte, and more.

Write components once, run everywhere. Compiles to: At a glance Mitosis is inspired by many modern frameworks. You'll see components look like React c

Builder.io 7.7k Jan 1, 2023
基于vue3.0-ts-Element集成的简洁/实用后台模板!《带预览地址》vue-admin;vue+admin;vue-element;vue+element;vue后台管理;vue3.0-admin;vue3.0-element。

一、基于vue3.0+ts+Element通用后台admin模板 二、在线预览地址:http://admin.yknba.cn/ 三、下载使用: 1、克隆代码 通过git将代码克隆到本地;或者使用下载安装包模式进行下载。 2、进入目录 进入项目的根目录:vue3.0-ts-admin 3、安装依

null 64 Dec 16, 2022
Sync your personal calendar to your work calendar, privately 🐒

Callibella ?? It is considered unusual among Callibella in that it gives birth to only a single baby instead of twins, the norm for Callibella. Wikiep

Yo'av Moshe 19 Oct 12, 2022
TimelineJS v3: A Storytelling Timeline built in JavaScript. http://timeline.knightlab.com

TimelineJS3 TimelineJS v3: A Storytelling Timeline built in JavaScript. https://timeline.knightlab.com Overview TimelineJS 3 is a rewrite of the popul

null 2.6k Dec 24, 2022
Final Project 3 - Mobile App Hotel Reservation

Hotel Reservation Mobile App Instruksi Pada Final Project kali ini, kamu diminta untuk membuat cloning dari aplikasi Airbnb, khusus untuk fitur-fitur

Akhsan Bayu 2 Jan 3, 2022
A Restaurant (Table) Reservation API built with Node, TypeScript, Express, TypeORM, a MySQL DB, all running on Docker containers

Restaurant (Table) Reservation API A simple API for reserving tables at a restaurant. The API is based on the REST architectural style and uses Node.j

null 14 Oct 5, 2022
A Restaurant (Table) Reservation API built with Node, TypeScript, Express, TypeORM, a MySQL DB, all running on Docker containers

Restaurant (Table) Reservation API A simple API for reserving tables at a restaurant. The API is based on the REST architectural style and uses Node.j

null 14 Oct 5, 2022