Gantt and Calendar view of tasks
chavu opened this issue · 7 comments
I'm working on project task management tool. I'm currently displaying the tasks in tabulator table. I now want to add Gantt and Calendar views. Does Kvision have any component that can do this? If not, how can I use extrernal JS libraries like these two below:
Google Charts (https://developers.google.com/chart/interactive/docs/gallery/ganttchart)
https://dlhsoft.com/GanttChartHyperLibrary/
I haven't done that, but you can try using scatter chart with chart.js module. See this SO example: https://stackoverflow.com/questions/41259441/how-to-draw-gantt-chart-using-chart-js-or-other-libraries
Thanks. I will try it out and give feedback
Instead of using the Chart module, I desided to try integrating this full-fledged react scheduler component https://github.com/Bitnoise/react-scheduler
The scduler is no display and see the following error message:
"TypeError: e.reduce is not a function or its return value is not iterable"
Below are my code .
Data clasess define in CommonMain module
import io.kvision.types.LocalDateTime
import kotlinx.serialization.Contextual
import kotlinx.serialization.Serializable
@Serializable
data class ScheduleData(
val id: String,
val label: ScheduleRowLabel,
val data: List<ScheduleResourceItem>? = null
)
@Serializable
data class ScheduleRowLabel(
val icon: String? = null,
val title: String,
val subTitle: String? = null,
)
@Serializable
data class ScheduleResourceItem(
val id: String, //unique resource id
val title: String, //resource title that will be displayed on resource tile
val subTitle: String? = null, //resource subtitle that will be displayed on resource tile
val description: String? = null, //resource description that will be displayed on resource tile
@Contextual val startDate: LocalDateTime, //date for calculating start position for resource
@Contextual val endDate: LocalDateTime, //date for calculating end position for resource
@Contextual val occupancy: Number = 30, //number of seconds resource takes up for given row that will be visible on resource tooltip when hovered
val bgColor: String, //tile color
)
data class ScheduleConfig(
val zoom: Number = 1, // 0 - weeks, 1 - Days
val filterButtonState: Number,
val maxRecordsPerPage: Number,
val lang: String = "en",
val includeTakenHoursOnWeekendsInDayView: Boolean
)
View to display the scheduler
import com.digitres.pmis.models.scheduling.ScheduleConfig
import com.digitres.pmis.models.scheduling.ScheduleData
import com.digitres.pmis.models.scheduling.ScheduleResourceItem
import io.kvision.core.Container
import io.kvision.react.react
import react.ComponentClass
import react.PropsWithChildren
import react.PropsWithRef
external interface ReactSchedulerProps : PropsWithRef<dynamic>, PropsWithChildren {
var data: List<ScheduleData>
var isLoading: Boolean
var onRangeChange: (String) -> Unit
var onTileClick: (String) -> Unit
var onItemClick: (ScheduleResourceItem) -> Unit
var onFilterData: () -> Unit
var onClearData: () -> Unit
var config: ScheduleConfig
}
val Scheduler: ComponentClass<ReactSchedulerProps> = io.kvision.require("@bitnoi.se/react-scheduler").Scheduler
fun Container.scheduleView() {
react {
Scheduler {
data = SampleSchedule.data
isLoading = false
config = ScheduleConfig(
zoom = 1,
filterButtonState = 0,
maxRecordsPerPage = 10,
lang = "en",
includeTakenHoursOnWeekendsInDayView = true
)
}
}
}
Sample Data to display
import com.digitres.pmis.models.scheduling.ScheduleData
import com.digitres.pmis.models.scheduling.ScheduleResourceItem
import com.digitres.pmis.models.scheduling.ScheduleRowLabel
import kotlin.js.Date
object SampleSchedule {
val data = listOf(
ScheduleData(
id = "1",
label = ScheduleRowLabel(
icon = null,
title = "Facility 1",
subTitle = null
),
data = listOf(
ScheduleResourceItem(
id = "1.1",
title = "Team 1",
subTitle = null,
description = null,
startDate = Date("2024-09-02T08:00"),
endDate = Date("2024-09-11T08:00"),
occupancy = 20,
bgColor = "rgb(254,165,177)"
)
)
),
ScheduleData(
id = "2",
label = ScheduleRowLabel(
icon = null,
title = "Facility 2",
subTitle = null
),
data = listOf(
ScheduleResourceItem(
id = "2.1",
title = "Team 2",
subTitle = null,
description = null,
startDate = Date("2024-09-13T08:00"),
endDate = Date("2024-09-20T08:00"),
occupancy = 20,
bgColor = "rgb(254,165,177)"
)
)
)
)
}
build.gradle dependencies addedd
val jsMain by getting {
resources.srcDir(webDir)
dependencies {
implementation(npm("react-is", "18.3.1"))
implementation(npm("@babel/core", "7.24.7"))
implementation(npm("@babel/plugin-syntax-jsx", "7.24.7"))
implementation(npm("@bitnoi.se/react-scheduler", "0.2.0"))
implementation("io.kvision:kvision-react:$kvisionVersion")
...
}
kotlin.srcDir("build/generated-src/frontend")
}
Error Stack
index.umd.cjs:114 Uncaught TypeError: e.reduce is not a function or its return value is not iterable
at Bo (index.umd.cjs:114:4169)
at eval (index.umd.cjs:114:4591)
at mountMemo (react-dom.development.js:17225:19)
at Object.useMemo (react-dom.development.js:17670:16)
at Object.useMemo (react.development.js:1651:21)
at Ro (index.umd.cjs:114:4579)
at as (index.umd.cjs:138:544)
at renderWithHooks (react-dom.development.js:16305:18)
at mountIndeterminateComponent (react-dom.development.js:20069:13)
at beginWork (react-dom.development.js:21582:16)
I'm almost sure you can't use Kotlin types (lists or data classes), even serializable, as a data model for React components. So it's very unlikely List<ScheduleData>
will work. In my opinion you need to use Array<dynamic>
or other external types.
Thanks. Using Arrary worked. I then converted the Kotlin List as below.
data = JSON.parse(Json.encodeToString(SampleSchedule.data))
I am now able to display the scheduler. However it is displaying fullscreen and yet it's supposed to be within the content area under the header. I am also not sure if its style I added to App.kt is being utilised.
class App : Application() {
init {
require("./css/custom.css")
require("@bitnoi.se/react-scheduler/dist/style.css")
}
...
}
Have you checked this: Bitnoise/react-scheduler#60 ?
Thanks, wrapping the scheduler in div and setting Relative position worked.