Initial commit

This commit is contained in:
2025-07-11 13:21:49 +00:00
commit 8a7ab3ac24
262 changed files with 28219 additions and 0 deletions
@@ -0,0 +1,62 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { ccGraphShapeProps, getDefaultCCAcademicDayNodeProps } from './cc-graph-props'
import { CCAcademicDayNodeProps } from './cc-graph-types'
import { NodeProperty } from './cc-graph-shared'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
import { CCBaseShape } from '../cc-types'
export interface CCAcademicDayNodeShape extends CCBaseShape {
type: 'cc-academic-day-node'
props: CCAcademicDayNodeProps
}
export class CCAcademicDayNodeShapeUtil extends CCBaseShapeUtil<CCAcademicDayNodeShape> {
static type = 'cc-academic-day-node' as const
static props = ccGraphShapeProps['cc-academic-day-node']
getDefaultProps(): CCAcademicDayNodeShape['props'] {
const defaultProps = getDefaultCCAcademicDayNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCAcademicDayNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCAcademicDayNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Academic Day"
value={shape.props.academic_day}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Date"
value={shape.props.date}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Day of Week"
value={shape.props.day_of_week}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Day Type"
value={shape.props.day_type}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,68 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCAcademicPeriodNodeProps } from './cc-graph-props'
import { CCAcademicPeriodNodeProps } from './cc-graph-types'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
export interface CCAcademicPeriodNodeShape extends CCBaseShape {
type: 'cc-academic-period-node'
props: CCAcademicPeriodNodeProps
}
export class CCAcademicPeriodNodeShapeUtil extends CCBaseShapeUtil<CCAcademicPeriodNodeShape> {
static type = 'cc-academic-period-node' as const
static props = ccGraphShapeProps['cc-academic-period-node']
getDefaultProps(): CCAcademicPeriodNodeShape['props'] {
const defaultProps = getDefaultCCAcademicPeriodNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCAcademicPeriodNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCAcademicPeriodNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Name"
value={shape.props.name}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Date"
value={shape.props.date}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Start Time"
value={shape.props.start_time}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="End Time"
value={shape.props.end_time}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Period Code"
value={shape.props.period_code}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,62 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCAcademicTermNodeProps } from './cc-graph-props'
import { CCAcademicTermNodeProps } from './cc-graph-types'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
export interface CCAcademicTermNodeShape extends CCBaseShape {
type: 'cc-academic-term-node'
props: CCAcademicTermNodeProps
}
export class CCAcademicTermNodeShapeUtil extends CCBaseShapeUtil<CCAcademicTermNodeShape> {
static type = 'cc-academic-term-node' as const
static props = ccGraphShapeProps['cc-academic-term-node']
getDefaultProps(): CCAcademicTermNodeShape['props'] {
const defaultProps = getDefaultCCAcademicTermNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCAcademicTermNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCAcademicTermNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Term Name"
value={shape.props.term_name}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Term Number"
value={shape.props.term_number}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Start Date"
value={shape.props.start_date}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="End Date"
value={shape.props.end_date}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,56 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCAcademicWeekNodeProps } from './cc-graph-props'
import { CCAcademicWeekNodeProps } from './cc-graph-types'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
export interface CCAcademicWeekNodeShape extends CCBaseShape {
type: 'cc-academic-week-node'
props: CCAcademicWeekNodeProps
}
export class CCAcademicWeekNodeShapeUtil extends CCBaseShapeUtil<CCAcademicWeekNodeShape> {
static type = 'cc-academic-week-node' as const
static props = ccGraphShapeProps['cc-academic-week-node']
getDefaultProps(): CCAcademicWeekNodeShape['props'] {
const defaultProps = getDefaultCCAcademicWeekNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCAcademicWeekNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCAcademicWeekNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Academic Week Number"
value={shape.props.academic_week_number}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Start Date"
value={shape.props.start_date}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Week Type"
value={shape.props.week_type}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,44 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCAcademicYearNodeProps } from './cc-graph-props'
import { CCAcademicYearNodeProps } from './cc-graph-types'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
export interface CCAcademicYearNodeShape extends CCBaseShape {
type: 'cc-academic-year-node'
props: CCAcademicYearNodeProps
}
export class CCAcademicYearNodeShapeUtil extends CCBaseShapeUtil<CCAcademicYearNodeShape> {
static type = 'cc-academic-year-node' as const
static props = ccGraphShapeProps['cc-academic-year-node']
getDefaultProps(): CCAcademicYearNodeShape['props'] {
const defaultProps = getDefaultCCAcademicYearNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCAcademicYearNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCAcademicYearNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Academic Year"
value={shape.props.year}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,56 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty, formatDate } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCCalendarDayNodeProps } from './cc-graph-props'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
import { CCCalendarDayNodeProps } from './cc-graph-types'
export interface CCCalendarDayNodeShape extends CCBaseShape {
type: 'cc-calendar-day-node'
props: CCCalendarDayNodeProps
}
export class CCCalendarDayNodeShapeUtil extends CCBaseShapeUtil<CCCalendarDayNodeShape> {
static type = 'cc-calendar-day-node' as const
static props = ccGraphShapeProps['cc-calendar-day-node']
getDefaultProps(): CCCalendarDayNodeShape['props'] {
const defaultProps = getDefaultCCCalendarDayNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCCalendarDayNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCCalendarDayNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Date"
value={formatDate(shape.props.date)}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Day of Week"
value={shape.props.day_of_week}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="ISO Day"
value={shape.props.iso_day}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,56 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCCalendarMonthNodeProps } from './cc-graph-props'
import { CCCalendarMonthNodeProps } from './cc-graph-types'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
export interface CCCalendarMonthNodeShape extends CCBaseShape {
type: 'cc-calendar-month-node'
props: CCCalendarMonthNodeProps
}
export class CCCalendarMonthNodeShapeUtil extends CCBaseShapeUtil<CCCalendarMonthNodeShape> {
static type = 'cc-calendar-month-node' as const
static props = ccGraphShapeProps['cc-calendar-month-node']
getDefaultProps(): CCCalendarMonthNodeShape['props'] {
const defaultProps = getDefaultCCCalendarMonthNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCCalendarMonthNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCCalendarMonthNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Year"
value={shape.props.year}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Month"
value={shape.props.month}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Month Name"
value={shape.props.month_name}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,62 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty, formatDate } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCCalendarNodeProps } from './cc-graph-props'
import { CCCalendarNodeProps } from './cc-graph-types'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
export interface CCCalendarNodeShape extends CCBaseShape {
type: 'cc-calendar-node'
props: CCCalendarNodeProps
}
export class CCCalendarNodeShapeUtil extends CCBaseShapeUtil<CCCalendarNodeShape> {
static type = 'cc-calendar-node' as const
static props = ccGraphShapeProps['cc-calendar-node']
getDefaultProps(): CCCalendarNodeShape['props'] {
const defaultProps = getDefaultCCCalendarNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCCalendarNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCCalendarNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Calendar Name"
value={shape.props.calendar_name}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Calendar Type"
value={shape.props.calendar_type}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Start Date"
value={formatDate(shape.props.start_date)}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="End Date"
value={formatDate(shape.props.end_date)}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,50 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCCalendarTimeChunkNodeProps } from './cc-graph-props'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
import { CCCalendarTimeChunkNodeProps } from './cc-graph-types'
export interface CCCalendarTimeChunkNodeShape extends CCBaseShape {
type: 'cc-calendar-time-chunk-node'
props: CCCalendarTimeChunkNodeProps
}
export class CCCalendarTimeChunkNodeShapeUtil extends CCBaseShapeUtil<CCCalendarTimeChunkNodeShape> {
static type = 'cc-calendar-time-chunk-node' as const
static props = ccGraphShapeProps['cc-calendar-time-chunk-node']
getDefaultProps(): CCCalendarTimeChunkNodeShape['props'] {
const defaultProps = getDefaultCCCalendarTimeChunkNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCCalendarTimeChunkNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCCalendarTimeChunkNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Start Time"
value={shape.props.start_time}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="End Time"
value={shape.props.end_time}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,56 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty, formatDate, DateValue } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCCalendarWeekNodeProps } from './cc-graph-props'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
import { CCCalendarWeekNodeProps } from './cc-graph-types'
export interface CCCalendarWeekNodeShape extends CCBaseShape {
type: 'cc-calendar-week-node'
props: CCCalendarWeekNodeProps
}
export class CCCalendarWeekNodeShapeUtil extends CCBaseShapeUtil<CCCalendarWeekNodeShape> {
static type = 'cc-calendar-week-node' as const
static props = ccGraphShapeProps['cc-calendar-week-node']
getDefaultProps(): CCCalendarWeekNodeShape['props'] {
const defaultProps = getDefaultCCCalendarWeekNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCCalendarWeekNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCCalendarWeekNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Start Date"
value={formatDate(shape.props.start_date as DateValue)}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Week Number"
value={shape.props.week_number}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="ISO Week"
value={shape.props.iso_week}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,44 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCCalendarYearNodeProps } from './cc-graph-props'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
import { CCCalendarYearNodeProps } from './cc-graph-types'
export interface CCCalendarYearNodeShape extends CCBaseShape {
type: 'cc-calendar-year-node'
props: CCCalendarYearNodeProps
}
export class CCCalendarYearNodeShapeUtil extends CCBaseShapeUtil<CCCalendarYearNodeShape> {
static type = 'cc-calendar-year-node' as const
static props = ccGraphShapeProps['cc-calendar-year-node']
getDefaultProps(): CCCalendarYearNodeShape['props'] {
const defaultProps = getDefaultCCCalendarYearNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCCalendarYearNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCCalendarYearNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Year"
value={shape.props.year}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,44 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCCurriculumStructureNodeProps } from './cc-graph-props'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
import { CCCurriculumStructureNodeProps } from './cc-graph-types'
export interface CCCurriculumStructureNodeShape extends CCBaseShape {
type: 'cc-curriculum-structure-node'
props: CCCurriculumStructureNodeProps
}
export class CCCurriculumStructureNodeShapeUtil extends CCBaseShapeUtil<CCCurriculumStructureNodeShape> {
static type = 'cc-curriculum-structure-node' as const
static props = ccGraphShapeProps['cc-curriculum-structure-node']
getDefaultProps(): CCCurriculumStructureNodeShape['props'] {
const defaultProps = getDefaultCCCurriculumStructureNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCCurriculumStructureNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCCurriculumStructureNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Structure Type"
value="Curriculum"
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,44 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCDepartmentNodeProps } from './cc-graph-props'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
import { CCDepartmentNodeProps } from './cc-graph-types'
export interface CCDepartmentNodeShape extends CCBaseShape {
type: 'cc-department-node'
props: CCDepartmentNodeProps
}
export class CCDepartmentNodeShapeUtil extends CCBaseShapeUtil<CCDepartmentNodeShape> {
static type = 'cc-department-node' as const
static props = ccGraphShapeProps['cc-department-node']
getDefaultProps(): CCDepartmentNodeShape['props'] {
const defaultProps = getDefaultCCDepartmentNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCDepartmentNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCDepartmentNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Department Name"
value={shape.props.department_name}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,44 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCDepartmentStructureNodeProps } from './cc-graph-props'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
import { CCDepartmentStructureNodeProps } from './cc-graph-types'
export interface CCDepartmentStructureNodeShape extends CCBaseShape {
type: 'cc-department-structure-node'
props: CCDepartmentStructureNodeProps
}
export class CCDepartmentStructureNodeShapeUtil extends CCBaseShapeUtil<CCDepartmentStructureNodeShape> {
static type = 'cc-department-structure-node' as const
static props = ccGraphShapeProps['cc-department-structure-node']
getDefaultProps(): CCDepartmentStructureNodeShape['props'] {
const defaultProps = getDefaultCCDepartmentStructureNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCDepartmentStructureNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCDepartmentStructureNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Structure Type"
value={shape.props.department_structure_type || "Department"}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,50 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCKeyStageNodeProps } from './cc-graph-props'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
import { CCKeyStageNodeProps } from './cc-graph-types'
export interface CCKeyStageNodeShape extends CCBaseShape {
type: 'cc-key-stage-node'
props: CCKeyStageNodeProps
}
export class CCKeyStageNodeShapeUtil extends CCBaseShapeUtil<CCKeyStageNodeShape> {
static type = 'cc-key-stage-node' as const
static props = ccGraphShapeProps['cc-key-stage-node']
getDefaultProps(): CCKeyStageNodeShape['props'] {
const defaultProps = getDefaultCCKeyStageNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCKeyStageNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCKeyStageNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Key Stage"
value={shape.props.key_stage}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Name"
value={shape.props.key_stage_name}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,62 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCKeyStageSyllabusNodeProps } from './cc-graph-props'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
import { CCKeyStageSyllabusNodeProps } from './cc-graph-types'
export interface CCKeyStageSyllabusNodeShape extends CCBaseShape {
type: 'cc-key-stage-syllabus-node'
props: CCKeyStageSyllabusNodeProps
}
export class CCKeyStageSyllabusNodeShapeUtil extends CCBaseShapeUtil<CCKeyStageSyllabusNodeShape> {
static type = 'cc-key-stage-syllabus-node' as const
static props = ccGraphShapeProps['cc-key-stage-syllabus-node']
getDefaultProps(): CCKeyStageSyllabusNodeShape['props'] {
const defaultProps = getDefaultCCKeyStageSyllabusNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCKeyStageSyllabusNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCKeyStageSyllabusNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Syllabus Name"
value={shape.props.ks_syllabus_name}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Key Stage"
value={shape.props.ks_syllabus_key_stage}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Subject"
value={shape.props.ks_syllabus_subject}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Subject Code"
value={shape.props.ks_syllabus_subject_code}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,56 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCLearningStatementNodeProps } from './cc-graph-props'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
import { CCLearningStatementNodeProps } from './cc-graph-types'
export interface CCLearningStatementNodeShape extends CCBaseShape {
type: 'cc-learning-statement-node'
props: CCLearningStatementNodeProps
}
export class CCLearningStatementNodeShapeUtil extends CCBaseShapeUtil<CCLearningStatementNodeShape> {
static type = 'cc-learning-statement-node' as const
static props = ccGraphShapeProps['cc-learning-statement-node']
getDefaultProps(): CCLearningStatementNodeShape['props'] {
const defaultProps = getDefaultCCLearningStatementNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCLearningStatementNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCLearningStatementNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Learning Statement"
value={shape.props.lesson_learning_statement}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Statement Type"
value={shape.props.lesson_learning_statement_type}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Statement ID"
value={shape.props.lesson_learning_statement_id}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,45 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCPastoralStructureNodeProps } from './cc-graph-props'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
import { CCPastoralStructureNodeProps } from './cc-graph-types'
export interface CCPastoralStructureNodeShape extends CCBaseShape {
type: 'cc-pastoral-structure-node'
props: CCPastoralStructureNodeProps
}
export class CCPastoralStructureNodeShapeUtil extends CCBaseShapeUtil<CCPastoralStructureNodeShape> {
static type = 'cc-pastoral-structure-node' as const
static props = ccGraphShapeProps['cc-pastoral-structure-node']
getDefaultProps(): CCPastoralStructureNodeShape['props'] {
const defaultProps = getDefaultCCPastoralStructureNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCPastoralStructureNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCPastoralStructureNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Structure Type"
value="Pastoral"
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,140 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCPlannedLessonNodeProps } from './cc-graph-props'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
import { CCPlannedLessonNodeProps } from './cc-graph-types'
export interface CCPlannedLessonNodeShape extends CCBaseShape {
type: 'cc-planned-lesson-node'
props: CCPlannedLessonNodeProps
}
export class CCPlannedLessonNodeShapeUtil extends CCBaseShapeUtil<CCPlannedLessonNodeShape> {
static type = 'cc-planned-lesson-node' as const
static props = ccGraphShapeProps['cc-planned-lesson-node']
getDefaultProps(): CCPlannedLessonNodeShape['props'] {
const defaultProps = getDefaultCCPlannedLessonNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCPlannedLessonNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCPlannedLessonNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Subject Class"
value={shape.props.subject_class}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Date"
value={shape.props.date}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Start Time"
value={shape.props.start_time}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="End Time"
value={shape.props.end_time}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Period Code"
value={shape.props.period_code}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Year Group"
value={shape.props.year_group}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Subject"
value={shape.props.subject}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Teacher Code"
value={shape.props.teacher_code}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Planning Status"
value={shape.props.planning_status}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Topic Code"
value={shape.props.topic_code}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Topic Name"
value={shape.props.topic_name}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Lesson Code"
value={shape.props.lesson_code}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Lesson Name"
value={shape.props.lesson_name}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Learning Statement Codes"
value={shape.props.learning_statement_codes}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Learning Statements"
value={shape.props.learning_statements}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Learning Resource Codes"
value={shape.props.learning_resource_codes}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Learning Resources"
value={shape.props.learning_resources}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,68 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCRegistrationPeriodNodeProps } from './cc-graph-props'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
import { CCRegistrationPeriodNodeProps } from './cc-graph-types'
export interface CCRegistrationPeriodNodeShape extends CCBaseShape {
type: 'cc-registration-period-node'
props: CCRegistrationPeriodNodeProps
}
export class CCRegistrationPeriodNodeShapeUtil extends CCBaseShapeUtil<CCRegistrationPeriodNodeShape> {
static type = 'cc-registration-period-node' as const
static props = ccGraphShapeProps['cc-registration-period-node']
getDefaultProps(): CCRegistrationPeriodNodeShape['props'] {
const defaultProps = getDefaultCCRegistrationPeriodNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCRegistrationPeriodNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCRegistrationPeriodNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Name"
value={shape.props.name}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Date"
value={shape.props.date}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Start Time"
value={shape.props.start_time}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="End Time"
value={shape.props.end_time}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Period Code"
value={shape.props.period_code}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,50 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCRoomNodeProps } from './cc-graph-props'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
import { CCRoomNodeProps } from './cc-graph-types'
export interface CCRoomNodeShape extends CCBaseShape {
type: 'cc-room-node'
props: CCRoomNodeProps
}
export class CCRoomNodeShapeUtil extends CCBaseShapeUtil<CCRoomNodeShape> {
static type = 'cc-room-node' as const
static props = ccGraphShapeProps['cc-room-node']
getDefaultProps(): CCRoomNodeShape['props'] {
const defaultProps = getDefaultCCRoomNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCRoomNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCRoomNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Room Name"
value={shape.props.room_name}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Room Code"
value={shape.props.room_code}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,54 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil';
import { CCBaseShape } from '../cc-types';
import { NodeProperty } from './cc-graph-shared';
import { ccGraphShapeProps, getDefaultCCSchoolNodeProps } from './cc-graph-props';
import { getNodeStyles } from './cc-graph-styles';
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles';
import { CCSchoolNodeProps } from './cc-graph-types';
export interface CCSchoolNodeShape extends CCBaseShape {
type: 'cc-school-node';
props: CCSchoolNodeProps;
}
export class CCSchoolNodeShapeUtil extends CCBaseShapeUtil<CCSchoolNodeShape> {
static type = 'cc-school-node' as const;
static props = ccGraphShapeProps['cc-school-node'];
getDefaultProps(): CCSchoolNodeShape['props'] {
const defaultProps = getDefaultCCSchoolNodeProps();
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCSchoolNodeShapeUtil.type]];
return {
...defaultProps,
headerColor: theme.headerColor,
};
}
DefaultComponent = () => null;
renderContent = (shape: CCSchoolNodeShape) => {
const styles = getNodeStyles(shape.type);
return (
<div style={styles.container}>
<NodeProperty
label="School Name"
value={shape.props.school_name}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="School Website"
value={shape.props.school_website}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="School UUID"
value={shape.props.school_uuid}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
);
};
}
@@ -0,0 +1,50 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCSchoolTimetableNodeProps } from './cc-graph-props'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
import { CCSchoolTimetableNodeProps } from './cc-graph-types'
export interface CCSchoolTimetableNodeShape extends CCBaseShape {
type: 'cc-school-timetable-node'
props: CCSchoolTimetableNodeProps
}
export class CCSchoolTimetableNodeShapeUtil extends CCBaseShapeUtil<CCSchoolTimetableNodeShape> {
static type = 'cc-school-timetable-node' as const
static props = ccGraphShapeProps['cc-school-timetable-node']
getDefaultProps(): CCSchoolTimetableNodeShape['props'] {
const defaultProps = getDefaultCCSchoolTimetableNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCSchoolTimetableNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCSchoolTimetableNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Start Date"
value={shape.props.start_date}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="End Date"
value={shape.props.end_date}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,80 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCScienceLabNodeProps } from './cc-graph-props'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
import { CCScienceLabNodeProps } from './cc-graph-types'
export interface CCScienceLabNodeShape extends CCBaseShape {
type: 'cc-science-lab-node'
props: CCScienceLabNodeProps
}
export class CCScienceLabNodeShapeUtil extends CCBaseShapeUtil<CCScienceLabNodeShape> {
static type = 'cc-science-lab-node' as const
static props = ccGraphShapeProps['cc-science-lab-node']
getDefaultProps(): CCScienceLabNodeShape['props'] {
const defaultProps = getDefaultCCScienceLabNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCScienceLabNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCScienceLabNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Lab Title"
value={shape.props.science_lab_title}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Summary"
value={shape.props.science_lab_summary}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Requirements"
value={shape.props.science_lab_requirements}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Procedure"
value={shape.props.science_lab_procedure}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Safety"
value={shape.props.science_lab_safety}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Web Links"
value={shape.props.science_lab_weblinks}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Lab ID"
value={shape.props.science_lab_id}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,56 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil';
import { CCBaseShape } from '../cc-types';
import { NodeProperty } from './cc-graph-shared';
import { ccGraphShapeProps, getDefaultCCStudentNodeProps } from './cc-graph-props';
import { getNodeStyles } from './cc-graph-styles';
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles';
import { CCStudentNodeProps } from './cc-graph-types';
export interface CCStudentNodeShape extends CCBaseShape {
type: 'cc-student-node';
props: CCStudentNodeProps;
}
export class CCStudentNodeShapeUtil extends CCBaseShapeUtil<CCStudentNodeShape> {
static type = 'cc-student-node' as const;
static props = ccGraphShapeProps['cc-student-node'];
getDefaultProps(): CCStudentNodeShape['props'] {
const defaultProps = getDefaultCCStudentNodeProps();
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCStudentNodeShapeUtil.type]];
return {
...defaultProps,
headerColor: theme.headerColor,
};
}
// Override to nullify the default node component
DefaultComponent = () => null;
renderContent = (shape: CCStudentNodeShape) => {
const styles = getNodeStyles(shape.type);
return (
<div style={styles.container}>
<NodeProperty
label="Student Name"
value={shape.props.student_name_formal}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Student Code"
value={shape.props.student_code}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Email"
value={shape.props.student_email}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
);
};
}
@@ -0,0 +1,62 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCSubjectClassNodeProps } from './cc-graph-props'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
import { CCSubjectClassNodeProps } from './cc-graph-types'
export interface CCSubjectClassNodeShape extends CCBaseShape {
type: 'cc-subject-class-node'
props: CCSubjectClassNodeProps
}
export class CCSubjectClassNodeShapeUtil extends CCBaseShapeUtil<CCSubjectClassNodeShape> {
static type = 'cc-subject-class-node' as const
static props = ccGraphShapeProps['cc-subject-class-node']
getDefaultProps(): CCSubjectClassNodeShape['props'] {
const defaultProps = getDefaultCCSubjectClassNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCSubjectClassNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCSubjectClassNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Class Code"
value={shape.props.subject_class_code}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Year Group"
value={shape.props.year_group}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Subject"
value={shape.props.subject}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Subject Code"
value={shape.props.subject_code}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,50 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCSubjectNodeProps } from './cc-graph-props'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
import { CCSubjectNodeProps } from './cc-graph-types'
export interface CCSubjectNodeShape extends CCBaseShape {
type: 'cc-subject-node'
props: CCSubjectNodeProps
}
export class CCSubjectNodeShapeUtil extends CCBaseShapeUtil<CCSubjectNodeShape> {
static type = 'cc-subject-node' as const
static props = ccGraphShapeProps['cc-subject-node']
getDefaultProps(): CCSubjectNodeShape['props'] {
const defaultProps = getDefaultCCSubjectNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCSubjectNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCSubjectNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Subject Name"
value={shape.props.subject_name}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Subject Code"
value={shape.props.subject_code}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,80 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import {
DefaultNodeComponent,
NodeErrorDisplay,
checkShapeState,
checkDefaultComponent
} from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCTeacherNodeProps } from './cc-graph-props'
import { getNodeStyles, NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
import { CCTeacherNodeProps } from './cc-graph-types'
export interface CCTeacherNodeShape extends CCBaseShape {
type: 'cc-teacher-node'
props: CCTeacherNodeProps
}
export class CCTeacherNodeShapeUtil extends CCBaseShapeUtil<CCTeacherNodeShape> {
static type = 'cc-teacher-node' as const
static props = ccGraphShapeProps['cc-teacher-node']
getDefaultProps(): CCTeacherNodeShape['props'] {
const defaultProps = getDefaultCCTeacherNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCTeacherNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor
}
}
renderContent = (shape: CCTeacherNodeShape) => {
const { props } = shape
const { state, defaultComponent } = props
const styles = getNodeStyles(shape.type)
const isPageChild = state?.isPageChild ?? true
// Check state and default component
const stateError = checkShapeState(state)
if (stateError.hasError) {
return <NodeErrorDisplay message={stateError.error.message} details={stateError.error.details} />
}
const defaultComponentError = checkDefaultComponent(defaultComponent)
if (defaultComponentError.hasError) {
return <NodeErrorDisplay message={defaultComponentError.error.message} details={defaultComponentError.error.details} />
}
if (isPageChild) {
// Define properties to show for page-level view
const properties = [
{ label: 'Teacher Name', value: props.teacher_name_formal },
{ label: 'Teacher Code', value: props.teacher_code },
{ label: 'Email', value: props.teacher_email },
{ label: 'Node Snapshot', value: props.tldraw_snapshot }
]
return (
<div style={styles.container}>
{defaultComponent && <DefaultNodeComponent tldraw_snapshot={props.tldraw_snapshot} />}
{properties.map((prop, index) => (
<div key={index} style={styles.property.wrapper}>
<span style={styles.property.label}>{prop.label}:</span>
<span style={styles.property.value}>{prop.value}</span>
</div>
))}
</div>
)
}
// Simplified view when child of another shape
return (
<div style={styles.container}>
<div style={styles.property.wrapper}>
<span style={styles.property.label}>Code:</span>
<span style={styles.property.value}>{props.teacher_code}</span>
</div>
</div>
)
}
}
@@ -0,0 +1,55 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCTeacherTimetableNodeProps } from './cc-graph-props'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
import { CCTeacherTimetableNodeProps } from './cc-graph-types'
export interface CCTeacherTimetableNodeShape extends CCBaseShape {
type: 'cc-teacher-timetable-node'
props: CCTeacherTimetableNodeProps
}
export class CCTeacherTimetableNodeShapeUtil extends CCBaseShapeUtil<CCTeacherTimetableNodeShape> {
static type = 'cc-teacher-timetable-node' as const
static props = ccGraphShapeProps['cc-teacher-timetable-node']
getDefaultProps(): CCTeacherTimetableNodeShape['props'] {
const defaultProps = getDefaultCCTeacherTimetableNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCTeacherTimetableNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCTeacherTimetableNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Teacher ID"
value={shape.props.teacher_id}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Start Date"
value={shape.props.start_date}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="End Date"
value={shape.props.end_date}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,68 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCTimetableLessonNodeProps } from './cc-graph-props'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
import { CCTimetableLessonNodeProps } from './cc-graph-types'
export interface CCTimetableLessonNodeShape extends CCBaseShape {
type: 'cc-timetable-lesson-node'
props: CCTimetableLessonNodeProps
}
export class CCTimetableLessonNodeShapeUtil extends CCBaseShapeUtil<CCTimetableLessonNodeShape> {
static type = 'cc-timetable-lesson-node' as const
static props = ccGraphShapeProps['cc-timetable-lesson-node']
getDefaultProps(): CCTimetableLessonNodeShape['props'] {
const defaultProps = getDefaultCCTimetableLessonNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCTimetableLessonNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCTimetableLessonNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Subject Class"
value={shape.props.subject_class}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Date"
value={shape.props.date}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Start Time"
value={shape.props.start_time}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="End Time"
value={shape.props.end_time}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Period Code"
value={shape.props.period_code}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,80 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCTopicLessonNodeProps } from './cc-graph-props'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
import { CCTopicLessonNodeProps } from './cc-graph-types'
export interface CCTopicLessonNodeShape extends CCBaseShape {
type: 'cc-topic-lesson-node'
props: CCTopicLessonNodeProps
}
export class CCTopicLessonNodeShapeUtil extends CCBaseShapeUtil<CCTopicLessonNodeShape> {
static type = 'cc-topic-lesson-node' as const
static props = ccGraphShapeProps['cc-topic-lesson-node']
getDefaultProps(): CCTopicLessonNodeShape['props'] {
const defaultProps = getDefaultCCTopicLessonNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCTopicLessonNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCTopicLessonNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Lesson Title"
value={shape.props.topic_lesson_title}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Lesson Type"
value={shape.props.topic_lesson_type}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Length"
value={shape.props.topic_lesson_length}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Skills Learned"
value={shape.props.topic_lesson_skills_learned}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Suggested Activities"
value={shape.props.topic_lesson_suggested_activities}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Web Links"
value={shape.props.topic_lesson_weblinks}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Lesson ID"
value={shape.props.topic_lesson_id}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,68 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCTopicNodeProps } from './cc-graph-props'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
import { CCTopicNodeProps } from './cc-graph-types'
export interface CCTopicNodeShape extends CCBaseShape {
type: 'cc-topic-node'
props: CCTopicNodeProps
}
export class CCTopicNodeShapeUtil extends CCBaseShapeUtil<CCTopicNodeShape> {
static type = 'cc-topic-node' as const
static props = ccGraphShapeProps['cc-topic-node']
getDefaultProps(): CCTopicNodeShape['props'] {
const defaultProps = getDefaultCCTopicNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCTopicNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCTopicNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Topic Title"
value={shape.props.topic_title}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Total Lessons"
value={shape.props.total_number_of_lessons_for_topic}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Topic Type"
value={shape.props.topic_type}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Assessment Type"
value={shape.props.topic_assessment_type}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Topic ID"
value={shape.props.topic_id}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,73 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import {
DefaultNodeComponent,
NodeErrorDisplay,
checkShapeState,
checkDefaultComponent
} from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCUserNodeProps } from './cc-graph-props'
import { CCUserNodeProps } from './cc-graph-types'
import { getNodeStyles, NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
export interface CCUserNodeShape extends CCBaseShape {
type: 'cc-user-node'
props: CCUserNodeProps
}
export class CCUserNodeShapeUtil extends CCBaseShapeUtil<CCUserNodeShape> {
static type = 'cc-user-node' as const
static props = ccGraphShapeProps['cc-user-node']
getDefaultProps(): CCUserNodeProps {
const defaultProps = getDefaultCCUserNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCUserNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
backgroundColor: theme.backgroundColor,
}
}
renderContent = (shape: CCUserNodeShape) => {
const { props } = shape
const { state, defaultComponent } = props
const styles = getNodeStyles(shape.type)
// Check state and default component
const stateError = checkShapeState(state)
if (stateError.hasError) {
return <NodeErrorDisplay message={stateError.error.message} details={stateError.error.details} />
}
const defaultComponentError = checkDefaultComponent(defaultComponent)
if (defaultComponentError.hasError) {
return <NodeErrorDisplay message={defaultComponentError.error.message} details={defaultComponentError.error.details} />
}
// Define properties to show based on view type
const properties = defaultComponent ? [
{ label: 'User Name', value: props.user_name },
{ label: 'User Email', value: props.user_email },
{ label: 'User Type', value: props.user_type },
{ label: 'User ID', value: props.user_id },
{ label: 'Node Snapshot', value: props.tldraw_snapshot },
{ label: 'Worker Node Data', value: props.worker_node_data }
] : [
{ label: 'User Name', value: props.user_name },
{ label: 'User Email', value: props.user_email }
]
return (
<div style={styles.container}>
{defaultComponent && <DefaultNodeComponent tldraw_snapshot={props.tldraw_snapshot} />}
{properties.map((prop, index) => (
<div key={index} style={styles.property.wrapper}>
<span style={styles.property.label}>{prop.label}:</span>
<span style={styles.property.value}>{prop.value}</span>
</div>
))}
</div>
)
}
}
@@ -0,0 +1,50 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCUserTeacherTimetableNodeProps } from './cc-graph-props'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
import { CCUserTeacherTimetableNodeProps } from './cc-graph-types'
export interface CCUserTeacherTimetableNodeShape extends CCBaseShape {
type: 'cc-user-teacher-timetable-node'
props: CCUserTeacherTimetableNodeProps
}
export class CCUserTeacherTimetableNodeShapeUtil extends CCBaseShapeUtil<CCUserTeacherTimetableNodeShape> {
static type = 'cc-user-teacher-timetable-node' as const
static props = ccGraphShapeProps['cc-user-teacher-timetable-node']
getDefaultProps(): CCUserTeacherTimetableNodeShape['props'] {
const defaultProps = getDefaultCCUserTeacherTimetableNodeProps() as CCUserTeacherTimetableNodeShape['props']
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCUserTeacherTimetableNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCUserTeacherTimetableNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="School DB"
value={shape.props.school_db_name}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="School Timetable ID"
value={shape.props.school_timetable_id}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,80 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty, formatDate } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCUserTimetableLessonNodeProps } from './cc-graph-props'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
import { CCUserTimetableLessonNodeProps } from './cc-graph-types'
export interface CCUserTimetableLessonNodeShape extends CCBaseShape {
type: 'cc-user-timetable-lesson-node'
props: CCUserTimetableLessonNodeProps
}
export class CCUserTimetableLessonNodeShapeUtil extends CCBaseShapeUtil<CCUserTimetableLessonNodeShape> {
static type = 'cc-user-timetable-lesson-node' as const
static props = ccGraphShapeProps['cc-user-timetable-lesson-node']
getDefaultProps(): CCUserTimetableLessonNodeShape['props'] {
const defaultProps = getDefaultCCUserTimetableLessonNodeProps() as CCUserTimetableLessonNodeShape['props']
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCUserTimetableLessonNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCUserTimetableLessonNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Subject Class"
value={shape.props.subject_class}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Date"
value={formatDate(shape.props.date)}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Start Time"
value={formatDate(shape.props.start_time)}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="End Time"
value={formatDate(shape.props.end_time)}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Period Code"
value={shape.props.period_code}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="School DB"
value={shape.props.school_db_name}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="School Period ID"
value={shape.props.school_period_id}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,50 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCYearGroupNodeProps } from './cc-graph-props'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
import { CCYearGroupNodeProps } from './cc-graph-types'
export interface CCYearGroupNodeShape extends CCBaseShape {
type: 'cc-year-group-node'
props: CCYearGroupNodeProps
}
export class CCYearGroupNodeShapeUtil extends CCBaseShapeUtil<CCYearGroupNodeShape> {
static type = 'cc-year-group-node' as const
static props = ccGraphShapeProps['cc-year-group-node']
getDefaultProps(): CCYearGroupNodeShape['props'] {
const defaultProps = getDefaultCCYearGroupNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCYearGroupNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCYearGroupNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Year Group"
value={shape.props.year_group}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Year Group Name"
value={shape.props.year_group_name}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,68 @@
import { CCBaseShapeUtil } from '../CCBaseShapeUtil'
import { CCBaseShape } from '../cc-types'
import { NodeProperty } from './cc-graph-shared'
import { ccGraphShapeProps, getDefaultCCYearGroupSyllabusNodeProps } from './cc-graph-props'
import { getNodeStyles } from './cc-graph-styles'
import { NODE_THEMES, NODE_TYPE_THEMES } from './cc-graph-styles'
import { CCYearGroupSyllabusNodeProps } from './cc-graph-types'
export interface CCYearGroupSyllabusNodeShape extends CCBaseShape {
type: 'cc-year-group-syllabus-node'
props: CCYearGroupSyllabusNodeProps
}
export class CCYearGroupSyllabusNodeShapeUtil extends CCBaseShapeUtil<CCYearGroupSyllabusNodeShape> {
static type = 'cc-year-group-syllabus-node' as const
static props = ccGraphShapeProps['cc-year-group-syllabus-node']
getDefaultProps(): CCYearGroupSyllabusNodeShape['props'] {
const defaultProps = getDefaultCCYearGroupSyllabusNodeProps()
const theme = NODE_THEMES[NODE_TYPE_THEMES[CCYearGroupSyllabusNodeShapeUtil.type]]
return {
...defaultProps,
headerColor: theme.headerColor,
}
}
// Override to nullify the default node component
DefaultComponent = () => null
renderContent = (shape: CCYearGroupSyllabusNodeShape) => {
const styles = getNodeStyles(shape.type)
return (
<div style={styles.container}>
<NodeProperty
label="Syllabus Name"
value={shape.props.yr_syllabus_name}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Year Group"
value={shape.props.yr_syllabus_year_group}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Subject"
value={shape.props.yr_syllabus_subject}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Subject Code"
value={shape.props.yr_syllabus_subject_code}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
<NodeProperty
label="Syllabus ID"
value={shape.props.yr_syllabus_id}
labelStyle={styles.property.label}
valueStyle={styles.property.value}
/>
</div>
)
}
}
@@ -0,0 +1,32 @@
import { ccGraphShapeProps } from './cc-graph-props'
import { createShapePropsMigrationIds, createShapePropsMigrationSequence } from '@tldraw/tldraw'
import { CCGraphShape, GraphShapeType } from './cc-graph-types'
// Helper function to create version IDs for a shape type
const createVersions = (shapeType: GraphShapeType) => {
return createShapePropsMigrationIds(shapeType, {
Initial: 1 // All shapes start at version 1 as required by TLDraw
})
}
// Helper function to create a migration sequence for a shape
const createMigrationSequence = (shapeType: GraphShapeType) => {
const versions = createVersions(shapeType)
return createShapePropsMigrationSequence({
sequence: [
{
id: versions.Initial,
up: (props: CCGraphShape['props']) => {
// Initial version - no changes needed
return props
},
},
],
})
}
// Create migrations for all graph shapes
export const ccGraphMigrations = Object.keys(ccGraphShapeProps).reduce((acc, shapeType) => ({
...acc,
[shapeType]: createMigrationSequence(shapeType as GraphShapeType)
}), {} as Record<GraphShapeType, ReturnType<typeof createShapePropsMigrationSequence>>)
@@ -0,0 +1,657 @@
import { T, TLBinding, TLShapeId } from '@tldraw/tldraw'
import { baseShapeProps } from '../cc-props'
import { ShapeState } from './cc-graph-types'
// State props validation
const stateProps = T.object({
parentId: T.optional(T.string.nullable()),
isPageChild: T.optional(T.boolean.nullable()),
hasChildren: T.optional(T.boolean.nullable()),
bindings: T.optional(T.arrayOf(T.object({})).nullable())
})
// Base props for all nodes
const graphBaseProps = {
...baseShapeProps,
__primarylabel__: T.string,
unique_id: T.string,
tldraw_snapshot: T.string,
created: T.string,
merged: T.string,
state: T.optional(stateProps.nullable()),
defaultComponent: T.optional(T.boolean.nullable())
}
// Props for specific node types
export const ccGraphShapeProps = {
'cc-user-node': {
...graphBaseProps,
user_name: T.string,
user_email: T.string,
user_type: T.string,
user_id: T.string,
worker_node_data: T.string,
},
'cc-teacher-node': {
...graphBaseProps,
teacher_code: T.string,
teacher_name_formal: T.string,
teacher_email: T.string,
user_db_name: T.string,
worker_db_name: T.string,
},
'cc-student-node': {
...graphBaseProps,
student_code: T.string,
student_name_formal: T.string,
student_email: T.string,
worker_db_name: T.string,
},
'cc-calendar-node': {
...graphBaseProps,
name: T.string,
calendar_type: T.string,
calendar_name: T.string,
start_date: T.string,
end_date: T.string,
},
'cc-calendar-year-node': {
...graphBaseProps,
year: T.string,
},
'cc-calendar-month-node': {
...graphBaseProps,
year: T.string,
month: T.string,
month_name: T.string,
},
'cc-calendar-week-node': {
...graphBaseProps,
start_date: T.string,
week_number: T.string,
iso_week: T.string,
},
'cc-calendar-day-node': {
...graphBaseProps,
date: T.string,
day_of_week: T.string,
iso_day: T.string,
},
'cc-calendar-time-chunk-node': {
...graphBaseProps,
start_time: T.string,
end_time: T.string,
},
'cc-school-node': {
...graphBaseProps,
school_uuid: T.string,
school_name: T.string,
school_website: T.string,
},
'cc-department-node': {
...graphBaseProps,
department_name: T.string,
},
'cc-room-node': {
...graphBaseProps,
room_code: T.string,
room_name: T.string,
},
'cc-subject-class-node': {
...graphBaseProps,
subject_class_code: T.string,
year_group: T.string,
subject: T.string,
subject_code: T.string,
},
'cc-pastoral-structure-node': {
...graphBaseProps,
},
'cc-year-group-node': {
...graphBaseProps,
year_group: T.string,
year_group_name: T.string,
},
'cc-curriculum-structure-node': {
...graphBaseProps,
},
'cc-key-stage-node': {
...graphBaseProps,
key_stage_name: T.string,
key_stage: T.string,
},
'cc-key-stage-syllabus-node': {
...graphBaseProps,
ks_syllabus_id: T.string,
ks_syllabus_name: T.string,
ks_syllabus_key_stage: T.string,
ks_syllabus_subject: T.string,
ks_syllabus_subject_code: T.string,
},
'cc-year-group-syllabus-node': {
...graphBaseProps,
yr_syllabus_id: T.string,
yr_syllabus_name: T.string,
yr_syllabus_year_group: T.string,
yr_syllabus_subject: T.string,
yr_syllabus_subject_code: T.string,
},
'cc-subject-node': {
...graphBaseProps,
subject_code: T.string,
subject_name: T.string,
},
'cc-topic-node': {
...graphBaseProps,
topic_id: T.string,
topic_title: T.string,
total_number_of_lessons_for_topic: T.string,
topic_type: T.string,
topic_assessment_type: T.string,
},
'cc-topic-lesson-node': {
...graphBaseProps,
topic_lesson_id: T.string,
topic_lesson_title: T.string,
topic_lesson_type: T.string,
topic_lesson_length: T.string,
topic_lesson_skills_learned: T.string,
topic_lesson_suggested_activities: T.string,
topic_lesson_weblinks: T.string,
},
'cc-learning-statement-node': {
...graphBaseProps,
lesson_learning_statement_id: T.string,
lesson_learning_statement: T.string,
lesson_learning_statement_type: T.string,
},
'cc-science-lab-node': {
...graphBaseProps,
science_lab_id: T.string,
science_lab_title: T.string,
science_lab_summary: T.string,
science_lab_requirements: T.string,
science_lab_procedure: T.string,
science_lab_safety: T.string,
science_lab_weblinks: T.string,
},
'cc-teacher-timetable-node': {
...graphBaseProps,
teacher_id: T.string,
start_date: T.string,
end_date: T.string,
},
'cc-timetable-lesson-node': {
...graphBaseProps,
subject_class: T.string,
date: T.string,
start_time: T.string,
end_time: T.string,
period_code: T.string,
},
'cc-planned-lesson-node': {
...graphBaseProps,
date: T.string,
start_time: T.string,
end_time: T.string,
period_code: T.string,
subject_class: T.string,
year_group: T.string,
subject: T.string,
teacher_code: T.string,
planning_status: T.string,
topic_code: T.string,
topic_name: T.string,
lesson_code: T.string,
lesson_name: T.string,
learning_statement_codes: T.string,
learning_statements: T.string,
learning_resource_codes: T.string,
learning_resources: T.string,
},
'cc-school-timetable-node': {
...graphBaseProps,
start_date: T.string,
end_date: T.string,
},
'cc-academic-year-node': {
...graphBaseProps,
year: T.string,
},
'cc-academic-term-node': {
...graphBaseProps,
term_name: T.string,
term_number: T.string,
start_date: T.string,
end_date: T.string,
},
'cc-academic-week-node': {
...graphBaseProps,
academic_week_number: T.string,
start_date: T.string,
week_type: T.string,
},
'cc-academic-day-node': {
...graphBaseProps,
academic_day: T.string,
date: T.string,
day_of_week: T.string,
day_type: T.string,
},
'cc-academic-period-node': {
...graphBaseProps,
name: T.string,
date: T.string,
start_time: T.string,
end_time: T.string,
period_code: T.string,
},
'cc-registration-period-node': {
...graphBaseProps,
name: T.string,
date: T.string,
start_time: T.string,
end_time: T.string,
period_code: T.string,
},
'cc-department-structure-node': {
...graphBaseProps,
department_structure_type: T.string,
},
'cc-user-teacher-timetable-node': {
...graphBaseProps,
school_db_name: T.string,
school_timetable_id: T.string,
},
'cc-user-timetable-lesson-node': {
...graphBaseProps,
subject_class: T.string,
date: T.string,
start_time: T.string,
end_time: T.string,
period_code: T.string,
school_db_name: T.string,
school_period_id: T.string,
},
} as const
// Default props getters
export const getDefaultBaseProps = () => ({
w: 200 as number,
h: 200 as number,
headerColor: '#3e6589' as string,
backgroundColor: '#f0f0f0' as string,
title: 'Untitled' as string,
isLocked: false as boolean,
unique_id: '' as string,
tldraw_snapshot: '' as string,
created: '' as string,
merged: '' as string,
state: {
parentId: null as TLShapeId | null,
isPageChild: true as boolean | null,
hasChildren: null as boolean | null,
bindings: null as TLBinding[] | null
} as ShapeState | null,
defaultComponent: true as boolean | null
})
export const getDefaultCCUserNodeProps = () => ({
...getDefaultBaseProps(),
__primarylabel__: 'User',
user_name: '',
user_email: '',
user_type: '',
user_id: '',
worker_node_data: ''
})
export const getDefaultCCTeacherNodeProps = () => ({
...getDefaultBaseProps(),
__primarylabel__: 'Teacher',
teacher_code: '',
teacher_name_formal: '',
teacher_email: '',
user_db_name: '',
school_db_name: '',
})
export const getDefaultCCStudentNodeProps = () => ({
...getDefaultBaseProps(),
__primarylabel__: 'Student',
student_code: '',
student_name_formal: '',
student_email: '',
school_db_name: '',
user_db_name: '',
})
export const getDefaultCCCalendarNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Calendar',
__primarylabel__: 'Calendar',
name: '',
calendar_type: '',
calendar_name: '',
start_date: '',
end_date: '',
})
export const getDefaultCCCalendarYearNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Calendar Year',
__primarylabel__: 'Calendar Year',
year: '',
})
export const getDefaultCCCalendarMonthNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Calendar Month',
__primarylabel__: 'Calendar Month',
year: '',
month: '',
month_name: '',
})
export const getDefaultCCCalendarWeekNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Calendar Week',
__primarylabel__: 'Calendar Week',
start_date: '',
week_number: '',
iso_week: '',
})
export const getDefaultCCCalendarDayNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Calendar Day',
__primarylabel__: 'Calendar Day',
date: '',
day_of_week: '',
iso_day: '',
})
export const getDefaultCCCalendarTimeChunkNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Calendar Time Chunk',
__primarylabel__: 'Calendar Time Chunk',
start_time: '',
end_time: '',
})
export const getDefaultCCSchoolNodeProps = () => ({
...getDefaultBaseProps(),
title: 'School',
__primarylabel__: 'School',
school_uuid: '',
school_name: '',
school_website: '',
})
export const getDefaultCCDepartmentNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Department',
__primarylabel__: 'Department',
department_name: '',
})
export const getDefaultCCRoomNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Room',
__primarylabel__: 'Room',
room_code: '',
room_name: '',
})
export const getDefaultCCSubjectClassNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Subject Class',
__primarylabel__: 'Subject Class',
subject_class_code: '',
year_group: '',
subject: '',
subject_code: '',
})
export const getDefaultCCPastoralStructureNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Pastoral Structure',
__primarylabel__: 'Pastoral Structure',
pastoral_structure_type: '',
})
export const getDefaultCCYearGroupNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Year Group',
__primarylabel__: 'Year Group',
year_group: '',
year_group_name: '',
})
export const getDefaultCCCurriculumStructureNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Curriculum Structure',
__primarylabel__: 'Curriculum Structure',
curriculum_structure_type: '',
})
export const getDefaultCCKeyStageNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Key Stage',
__primarylabel__: 'Key Stage',
key_stage_name: '',
key_stage: '',
})
export const getDefaultCCKeyStageSyllabusNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Key Stage Syllabus',
__primarylabel__: 'Key Stage Syllabus',
ks_syllabus_id: '',
ks_syllabus_name: '',
ks_syllabus_key_stage: '',
ks_syllabus_subject: '',
ks_syllabus_subject_code: '',
})
export const getDefaultCCYearGroupSyllabusNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Year Group Syllabus',
__primarylabel__: 'Year Group Syllabus',
yr_syllabus_id: '',
yr_syllabus_name: '',
yr_syllabus_year_group: '',
yr_syllabus_subject: '',
yr_syllabus_subject_code: '',
})
export const getDefaultCCSubjectNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Subject',
__primarylabel__: 'Subject',
subject_code: '',
subject_name: '',
})
export const getDefaultCCTopicNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Topic',
__primarylabel__: 'Topic',
topic_id: '',
topic_title: '',
total_number_of_lessons_for_topic: '',
topic_type: '',
topic_assessment_type: '',
})
export const getDefaultCCTopicLessonNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Topic Lesson',
__primarylabel__: 'Topic Lesson',
topic_lesson_id: '',
topic_lesson_title: '',
topic_lesson_type: '',
topic_lesson_length: '',
topic_lesson_skills_learned: '',
topic_lesson_suggested_activities: '',
topic_lesson_weblinks: '',
})
export const getDefaultCCLearningStatementNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Learning Statement',
__primarylabel__: 'Learning Statement',
lesson_learning_statement_id: '',
lesson_learning_statement: '',
lesson_learning_statement_type: '',
})
export const getDefaultCCScienceLabNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Science Lab',
__primarylabel__: 'Science Lab',
science_lab_id: '',
science_lab_title: '',
science_lab_summary: '',
science_lab_requirements: '',
science_lab_procedure: '',
science_lab_safety: '',
science_lab_weblinks: '',
})
export const getDefaultCCTeacherTimetableNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Teacher Timetable',
__primarylabel__: 'Teacher Timetable',
teacher_id: '',
start_date: '',
end_date: '',
})
export const getDefaultCCTimetableLessonNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Timetable Lesson',
__primarylabel__: 'Timetable Lesson',
subject_class: '',
date: '',
start_time: '',
end_time: '',
period_code: '',
})
export const getDefaultCCPlannedLessonNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Planned Lesson',
__primarylabel__: 'Planned Lesson',
date: '',
start_time: '',
end_time: '',
period_code: '',
subject_class: '',
year_group: '',
subject: '',
teacher_code: '',
planning_status: '',
topic_code: '',
topic_name: '',
lesson_code: '',
lesson_name: '',
learning_statement_codes: '',
learning_statements: '',
learning_resource_codes: '',
learning_resources: '',
})
export const getDefaultCCSchoolTimetableNodeProps = () => ({
...getDefaultBaseProps(),
title: 'School Timetable',
__primarylabel__: 'School Timetable',
start_date: '',
end_date: '',
})
export const getDefaultCCAcademicYearNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Academic Year',
__primarylabel__: 'Academic Year',
year: '',
})
export const getDefaultCCAcademicTermNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Academic Term',
__primarylabel__: 'Academic Term',
term_name: '',
term_number: '',
start_date: '',
end_date: '',
})
export const getDefaultCCAcademicWeekNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Academic Week',
__primarylabel__: 'Academic Week',
academic_week_number: '',
start_date: '',
week_type: '',
})
export const getDefaultCCAcademicDayNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Academic Day',
__primarylabel__: 'Academic Day',
academic_day: '',
date: '',
day_of_week: '',
day_type: '',
})
export const getDefaultCCAcademicPeriodNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Academic Period',
__primarylabel__: 'Academic Period',
name: '',
date: '',
start_time: '',
end_time: '',
period_code: '',
})
export const getDefaultCCRegistrationPeriodNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Registration Period',
__primarylabel__: 'Registration Period',
name: '',
date: '',
start_time: '',
end_time: '',
period_code: '',
})
export const getDefaultCCDepartmentStructureNodeProps = () => ({
...getDefaultBaseProps(),
title: 'Department Structure',
__primarylabel__: 'DepartmentStructure',
department_structure_type: '',
})
export const getDefaultCCUserTeacherTimetableNodeProps = () => ({
...getDefaultBaseProps(),
title: 'User Teacher Timetable',
__primarylabel__: 'UserTeacherTimetable',
school_db_name: '',
school_timetable_id: '',
})
export const getDefaultCCUserTimetableLessonNodeProps = () => ({
...getDefaultBaseProps(),
title: 'User Timetable Lesson',
__primarylabel__: 'UserTimetableLesson',
subject_class: '',
date: '',
start_time: '',
end_time: '',
period_code: '',
school_db_name: '',
school_period_id: '',
})
@@ -0,0 +1,175 @@
import { TLShape } from '@tldraw/tldraw'
import { CCUserNodeShape, CCUserNodeShapeUtil } from './CCUserNodeShapeUtil'
import { CCTeacherNodeShape, CCTeacherNodeShapeUtil } from './CCTeacherNodeShapeUtil'
import { CCStudentNodeShape, CCStudentNodeShapeUtil } from './CCStudentNodeShapeUtil'
import { CCCalendarNodeShape, CCCalendarNodeShapeUtil } from './CCCalendarNodeShapeUtil'
import { CCCalendarYearNodeShape, CCCalendarYearNodeShapeUtil } from './CCCalendarYearNodeShapeUtil'
import { CCCalendarMonthNodeShape, CCCalendarMonthNodeShapeUtil } from './CCCalendarMonthNodeShapeUtil'
import { CCCalendarWeekNodeShape, CCCalendarWeekNodeShapeUtil } from './CCCalendarWeekNodeShapeUtil'
import { CCCalendarDayNodeShape, CCCalendarDayNodeShapeUtil } from './CCCalendarDayNodeShapeUtil'
import { CCCalendarTimeChunkNodeShape, CCCalendarTimeChunkNodeShapeUtil } from './CCCalendarTimeChunkNodeShapeUtil'
import { CCSchoolNodeShape, CCSchoolNodeShapeUtil } from './CCSchoolNodeShapeUtil'
import { CCDepartmentNodeShape, CCDepartmentNodeShapeUtil } from './CCDepartmentNodeShapeUtil'
import { CCRoomNodeShape, CCRoomNodeShapeUtil } from './CCRoomNodeShapeUtil'
import { CCSubjectClassNodeShape, CCSubjectClassNodeShapeUtil } from './CCSubjectClassNodeShapeUtil'
import { CCPastoralStructureNodeShape, CCPastoralStructureNodeShapeUtil } from './CCPastoralStructureNodeShapeUtil'
import { CCYearGroupNodeShape, CCYearGroupNodeShapeUtil } from './CCYearGroupNodeShapeUtil'
import { CCCurriculumStructureNodeShape, CCCurriculumStructureNodeShapeUtil } from './CCCurriculumStructureNodeShapeUtil'
import { CCKeyStageNodeShape, CCKeyStageNodeShapeUtil } from './CCKeyStageNodeShapeUtil'
import { CCKeyStageSyllabusNodeShape, CCKeyStageSyllabusNodeShapeUtil } from './CCKeyStageSyllabusNodeShapeUtil'
import { CCYearGroupSyllabusNodeShape, CCYearGroupSyllabusNodeShapeUtil } from './CCYearGroupSyllabusNodeShapeUtil'
import { CCSubjectNodeShape, CCSubjectNodeShapeUtil } from './CCSubjectNodeShapeUtil'
import { CCTopicNodeShape, CCTopicNodeShapeUtil } from './CCTopicNodeShapeUtil'
import { CCTopicLessonNodeShape, CCTopicLessonNodeShapeUtil } from './CCTopicLessonNodeShapeUtil'
import { CCLearningStatementNodeShape, CCLearningStatementNodeShapeUtil } from './CCLearningStatementNodeShapeUtil'
import { CCScienceLabNodeShape, CCScienceLabNodeShapeUtil } from './CCScienceLabNodeShapeUtil'
import { CCSchoolTimetableNodeShape, CCSchoolTimetableNodeShapeUtil } from './CCSchoolTimetableNodeShapeUtil'
import { CCAcademicYearNodeShape, CCAcademicYearNodeShapeUtil } from './CCAcademicYearNodeShapeUtil'
import { CCAcademicTermNodeShape, CCAcademicTermNodeShapeUtil } from './CCAcademicTermNodeShapeUtil'
import { CCAcademicWeekNodeShape, CCAcademicWeekNodeShapeUtil } from './CCAcademicWeekNodeShapeUtil'
import { CCAcademicDayNodeShape, CCAcademicDayNodeShapeUtil } from './CCAcademicDayNodeShapeUtil'
import { CCAcademicPeriodNodeShape, CCAcademicPeriodNodeShapeUtil } from './CCAcademicPeriodNodeShapeUtil'
import { CCRegistrationPeriodNodeShape, CCRegistrationPeriodNodeShapeUtil } from './CCRegistrationPeriodNodeShapeUtil'
import { CCTeacherTimetableNodeShape, CCTeacherTimetableNodeShapeUtil } from './CCTeacherTimetableNodeShapeUtil'
import { CCTimetableLessonNodeShape, CCTimetableLessonNodeShapeUtil } from './CCTimetableLessonNodeShapeUtil'
import { CCPlannedLessonNodeShape, CCPlannedLessonNodeShapeUtil } from './CCPlannedLessonNodeShapeUtil'
import { CCDepartmentStructureNodeShape, CCDepartmentStructureNodeShapeUtil } from './CCDepartmentStructureNodeShapeUtil'
import { CCUserTeacherTimetableNodeShape, CCUserTeacherTimetableNodeShapeUtil } from './CCUserTeacherTimetableNodeShapeUtil'
import { CCUserTimetableLessonNodeShape, CCUserTimetableLessonNodeShapeUtil } from './CCUserTimetableLessonNodeShapeUtil'
// Create a const object with all node types
export const NODE_SHAPE_TYPES = {
USER: CCUserNodeShapeUtil.type,
TEACHER: CCTeacherNodeShapeUtil.type,
STUDENT: CCStudentNodeShapeUtil.type,
CALENDAR: CCCalendarNodeShapeUtil.type,
CALENDAR_YEAR: CCCalendarYearNodeShapeUtil.type,
CALENDAR_MONTH: CCCalendarMonthNodeShapeUtil.type,
CALENDAR_WEEK: CCCalendarWeekNodeShapeUtil.type,
CALENDAR_DAY: CCCalendarDayNodeShapeUtil.type,
CALENDAR_TIME_CHUNK: CCCalendarTimeChunkNodeShapeUtil.type,
SCHOOL: CCSchoolNodeShapeUtil.type,
DEPARTMENT: CCDepartmentNodeShapeUtil.type,
ROOM: CCRoomNodeShapeUtil.type,
SUBJECT_CLASS: CCSubjectClassNodeShapeUtil.type,
PASTORAL_STRUCTURE: CCPastoralStructureNodeShapeUtil.type,
YEAR_GROUP: CCYearGroupNodeShapeUtil.type,
CURRICULUM_STRUCTURE: CCCurriculumStructureNodeShapeUtil.type,
KEY_STAGE: CCKeyStageNodeShapeUtil.type,
KEY_STAGE_SYLLABUS: CCKeyStageSyllabusNodeShapeUtil.type,
YEAR_GROUP_SYLLABUS: CCYearGroupSyllabusNodeShapeUtil.type,
SUBJECT: CCSubjectNodeShapeUtil.type,
TOPIC: CCTopicNodeShapeUtil.type,
TOPIC_LESSON: CCTopicLessonNodeShapeUtil.type,
LEARNING_STATEMENT: CCLearningStatementNodeShapeUtil.type,
SCIENCE_LAB: CCScienceLabNodeShapeUtil.type,
SCHOOL_TIMETABLE: CCSchoolTimetableNodeShapeUtil.type,
ACADEMIC_YEAR: CCAcademicYearNodeShapeUtil.type,
ACADEMIC_TERM: CCAcademicTermNodeShapeUtil.type,
ACADEMIC_WEEK: CCAcademicWeekNodeShapeUtil.type,
ACADEMIC_DAY: CCAcademicDayNodeShapeUtil.type,
ACADEMIC_PERIOD: CCAcademicPeriodNodeShapeUtil.type,
REGISTRATION_PERIOD: CCRegistrationPeriodNodeShapeUtil.type,
TEACHER_TIMETABLE: CCTeacherTimetableNodeShapeUtil.type,
TIMETABLE_LESSON: CCTimetableLessonNodeShapeUtil.type,
PLANNED_LESSON: CCPlannedLessonNodeShapeUtil.type,
DEPARTMENT_STRUCTURE: CCDepartmentStructureNodeShapeUtil.type,
USER_TEACHER_TIMETABLE: CCUserTeacherTimetableNodeShapeUtil.type,
USER_TIMETABLE_LESSON: CCUserTimetableLessonNodeShapeUtil.type,
} as const;
// Create the type from the const object's values
export type NodeShapeType = typeof NODE_SHAPE_TYPES[keyof typeof NODE_SHAPE_TYPES];
// Define AllNodeShapes as a union type of all shape types
export type AllNodeShapes =
| CCUserNodeShape
| CCTeacherNodeShape
| CCStudentNodeShape
| CCCalendarNodeShape
| CCCalendarYearNodeShape
| CCCalendarMonthNodeShape
| CCCalendarWeekNodeShape
| CCCalendarDayNodeShape
| CCCalendarTimeChunkNodeShape
| CCSchoolNodeShape
| CCDepartmentNodeShape
| CCRoomNodeShape
| CCSubjectClassNodeShape
| CCPastoralStructureNodeShape
| CCYearGroupNodeShape
| CCCurriculumStructureNodeShape
| CCKeyStageNodeShape
| CCKeyStageSyllabusNodeShape
| CCYearGroupSyllabusNodeShape
| CCSubjectNodeShape
| CCTopicNodeShape
| CCTopicLessonNodeShape
| CCLearningStatementNodeShape
| CCScienceLabNodeShape
| CCSchoolTimetableNodeShape
| CCAcademicYearNodeShape
| CCAcademicTermNodeShape
| CCAcademicWeekNodeShape
| CCAcademicDayNodeShape
| CCAcademicPeriodNodeShape
| CCRegistrationPeriodNodeShape
| CCTeacherTimetableNodeShape
| CCTimetableLessonNodeShape
| CCPlannedLessonNodeShape
| CCDepartmentStructureNodeShape
| CCUserTeacherTimetableNodeShape
| CCUserTimetableLessonNodeShape;
// Export all shape utils in an object for easy access
export const ShapeUtils = {
[CCUserNodeShapeUtil.type]: CCUserNodeShapeUtil,
[CCTeacherNodeShapeUtil.type]: CCTeacherNodeShapeUtil,
[CCStudentNodeShapeUtil.type]: CCStudentNodeShapeUtil,
[CCCalendarNodeShapeUtil.type]: CCCalendarNodeShapeUtil,
[CCCalendarYearNodeShapeUtil.type]: CCCalendarYearNodeShapeUtil,
[CCCalendarMonthNodeShapeUtil.type]: CCCalendarMonthNodeShapeUtil,
[CCCalendarWeekNodeShapeUtil.type]: CCCalendarWeekNodeShapeUtil,
[CCCalendarDayNodeShapeUtil.type]: CCCalendarDayNodeShapeUtil,
[CCCalendarTimeChunkNodeShapeUtil.type]: CCCalendarTimeChunkNodeShapeUtil,
[CCSchoolNodeShapeUtil.type]: CCSchoolNodeShapeUtil,
[CCDepartmentNodeShapeUtil.type]: CCDepartmentNodeShapeUtil,
[CCRoomNodeShapeUtil.type]: CCRoomNodeShapeUtil,
[CCSubjectClassNodeShapeUtil.type]: CCSubjectClassNodeShapeUtil,
[CCPastoralStructureNodeShapeUtil.type]: CCPastoralStructureNodeShapeUtil,
[CCYearGroupNodeShapeUtil.type]: CCYearGroupNodeShapeUtil,
[CCCurriculumStructureNodeShapeUtil.type]: CCCurriculumStructureNodeShapeUtil,
[CCKeyStageNodeShapeUtil.type]: CCKeyStageNodeShapeUtil,
[CCKeyStageSyllabusNodeShapeUtil.type]: CCKeyStageSyllabusNodeShapeUtil,
[CCYearGroupSyllabusNodeShapeUtil.type]: CCYearGroupSyllabusNodeShapeUtil,
[CCSubjectNodeShapeUtil.type]: CCSubjectNodeShapeUtil,
[CCTopicNodeShapeUtil.type]: CCTopicNodeShapeUtil,
[CCTopicLessonNodeShapeUtil.type]: CCTopicLessonNodeShapeUtil,
[CCLearningStatementNodeShapeUtil.type]: CCLearningStatementNodeShapeUtil,
[CCScienceLabNodeShapeUtil.type]: CCScienceLabNodeShapeUtil,
[CCSchoolTimetableNodeShapeUtil.type]: CCSchoolTimetableNodeShapeUtil,
[CCAcademicYearNodeShapeUtil.type]: CCAcademicYearNodeShapeUtil,
[CCAcademicTermNodeShapeUtil.type]: CCAcademicTermNodeShapeUtil,
[CCAcademicWeekNodeShapeUtil.type]: CCAcademicWeekNodeShapeUtil,
[CCAcademicDayNodeShapeUtil.type]: CCAcademicDayNodeShapeUtil,
[CCAcademicPeriodNodeShapeUtil.type]: CCAcademicPeriodNodeShapeUtil,
[CCRegistrationPeriodNodeShapeUtil.type]: CCRegistrationPeriodNodeShapeUtil,
[CCTeacherTimetableNodeShapeUtil.type]: CCTeacherTimetableNodeShapeUtil,
[CCTimetableLessonNodeShapeUtil.type]: CCTimetableLessonNodeShapeUtil,
[CCPlannedLessonNodeShapeUtil.type]: CCPlannedLessonNodeShapeUtil,
[CCDepartmentStructureNodeShapeUtil.type]: CCDepartmentStructureNodeShapeUtil,
[CCUserTeacherTimetableNodeShapeUtil.type]: CCUserTeacherTimetableNodeShapeUtil,
[CCUserTimetableLessonNodeShapeUtil.type]: CCUserTimetableLessonNodeShapeUtil,
} as const;
// Add a type guard to check if a shape is a valid node shape
export const isValidNodeShape = (shape: TLShape): shape is AllNodeShapes => {
return shape &&
typeof shape.type === 'string' &&
Object.values(NODE_SHAPE_TYPES).includes(shape.type as NodeShapeType);
};
// Add a type guard to check if a type string is a valid node type
export const isValidNodeType = (type: string): type is NodeShapeType => {
return Object.values(NODE_SHAPE_TYPES).includes(type as NodeShapeType);
};
@@ -0,0 +1,236 @@
import React, { CSSProperties } from 'react';
import { ShapeState } from './cc-graph-types'
import { SHARED_NODE_STYLES } from './cc-graph-styles'
import { logger } from '../../../../debugConfig'
interface Neo4jDate {
_Date__year: number;
_Date__month: number;
_Date__day: number;
_Date__ordinal?: number;
}
interface Neo4jTime {
_Time__hour: number;
_Time__minute: number;
_Time__second: number;
_Time__nanosecond: number;
_Time__ticks: number;
_Time__tzinfo: null;
}
interface Neo4jDateTime {
_DateTime__date: Neo4jDate;
_DateTime__time: Neo4jTime;
}
export type DateValue = string | Date | Neo4jDate | Neo4jDateTime | null | undefined;
const isValidDate = (year: number | undefined, month: number | undefined, day: number | undefined): boolean => {
if (typeof year !== 'number' || typeof month !== 'number' || typeof day !== 'number') return false;
if (month < 1 || month > 12 || day < -31 || day > 31) return false;
// Handle special case for end of month markers
if (day < 0) return true;
const date = new Date(year, month - 1, day);
return date.getMonth() === month - 1 && date.getDate() === day;
};
// Date formatting utility for Neo4j date objects and other formats
export const formatDate = (dateValue: DateValue): string => {
if (!dateValue) return '';
// Handle string dates
if (typeof dateValue === 'string') return dateValue;
// Handle standard Date objects
if (dateValue instanceof Date) {
return dateValue.toISOString().split('T')[0];
}
// Handle Neo4j DateTime objects
if (typeof dateValue === 'object' && '_DateTime__date' in dateValue) {
const nestedDate = dateValue._DateTime__date as Neo4jDate;
return formatDate(nestedDate);
}
// Handle Neo4j Date objects and raw date objects
if (typeof dateValue === 'object' && '_Date__year' in dateValue) {
const year = dateValue._Date__year;
const month = dateValue._Date__month;
const day = dateValue._Date__day;
if (isValidDate(year, month, day)) {
try {
// Handle negative days (end of month markers)
if (typeof day === 'number' && day < 0 && typeof year === 'number' && typeof month === 'number') {
const nextMonth = new Date(year, month, 1);
nextMonth.setDate(nextMonth.getDate() - 1);
return nextMonth.toISOString().split('T')[0];
}
if (typeof year === 'number' && typeof month === 'number' && typeof day === 'number') {
const date = new Date(year, month - 1, day);
return date.toISOString().split('T')[0];
}
} catch {
logger.warn('graph-shape-shared', '⚠️ Failed to format Neo4j date', { dateValue });
}
}
return 'Invalid Date';
}
// For any other object, try to convert it
try {
const date = new Date(String(dateValue));
if (!isNaN(date.getTime())) {
return date.toISOString().split('T')[0];
}
} catch {
logger.warn('graph-shape-shared', '⚠️ Failed to format unknown date type', { dateValue });
}
return 'Invalid Date';
}
// Error display component for nodes
interface NodeErrorDisplayProps {
message: string;
details?: string;
style?: CSSProperties;
}
interface ErrorResult {
hasError: true;
error: {
message: string;
details: string;
};
}
interface SuccessResult {
hasError: false;
}
type ValidationResult = ErrorResult | SuccessResult;
export const NodeErrorDisplay: React.FC<NodeErrorDisplayProps> = ({
message,
details,
style
}) => (
<div style={{ ...SHARED_NODE_STYLES.error.container, ...style }}>
<div style={SHARED_NODE_STYLES.error.message}>{message}</div>
{details && <div style={SHARED_NODE_STYLES.error.details}>{details}</div>}
</div>
);
// Error checking utilities
export const checkShapeState = (state: ShapeState | undefined | null): ValidationResult => {
if (!state) {
logger.warn('graph-shape-shared', '⚠️ Missing shape state', { state })
return {
hasError: true,
error: {
message: "Invalid Shape State",
details: "Shape state is missing or undefined"
}
}
}
if (state.isPageChild === null) {
logger.warn('graph-shape-shared', '⚠️ Invalid page child state', { state })
return {
hasError: true,
error: {
message: "Invalid Page State",
details: "Unable to determine if node is a page child"
}
}
}
if (state.isPageChild === false && state.parentId === null) {
logger.warn('graph-shape-shared', '⚠️ Shape child with no parent', { state })
return {
hasError: true,
error: {
message: "Invalid Shape Child State",
details: "Shape child with no parent"
}
}
}
return { hasError: false }
}
export const checkDefaultComponent = (defaultComponent: boolean | { action: { label: string; handler: () => void } } | undefined | null): ValidationResult => {
if (defaultComponent === null) {
logger.warn('graph-shape-shared', '⚠️ Invalid default component', { defaultComponent })
return {
hasError: true,
error: {
message: "Invalid Default Component",
details: "Default component is not set"
}
}
}
return { hasError: false }
}
// Base component for all graph nodes
interface DefaultNodeComponentProps {
tldraw_snapshot: string
onInspect?: (tldraw_snapshot: string) => void
customAction?: {
label: string
handler: () => void
}
}
export const DefaultNodeComponent: React.FC<DefaultNodeComponentProps> = ({
tldraw_snapshot,
onInspect = () => console.log(`Inspecting node at path: ${tldraw_snapshot}`),
customAction
}) => {
return (
<div style={SHARED_NODE_STYLES.defaultComponent.container}>
<button style={SHARED_NODE_STYLES.defaultComponent.button} onClick={() => onInspect(tldraw_snapshot)}>
Inspect
</button>
{customAction && (
<button style={SHARED_NODE_STYLES.defaultComponent.button} onClick={customAction.handler}>
{customAction.label}
</button>
)}
</div>
)
}
// Helper function to create a node content wrapper
export const NodeContentWrapper = ({
children,
style
}: {
children: React.ReactNode;
style: CSSProperties;
}) => (
<div style={{ ...SHARED_NODE_STYLES.container, ...style }}>
{children}
</div>
);
// Helper function to create a node property display
export const NodeProperty = ({
label,
value,
labelStyle,
valueStyle
}: {
label: string;
value: string;
labelStyle: CSSProperties;
valueStyle: CSSProperties;
}) => (
<div style={SHARED_NODE_STYLES.property.wrapper}>
<span style={{ ...SHARED_NODE_STYLES.property.label, ...labelStyle }}>{label}:</span>
<span style={{ ...SHARED_NODE_STYLES.property.value, ...valueStyle }}>{value}</span>
</div>
);
@@ -0,0 +1,176 @@
// Shared styles for all nodes
export const SHARED_NODE_STYLES = {
container: {
display: 'flex',
flexDirection: 'column' as const,
padding: '8px',
gap: '4px',
backgroundColor: 'var(--color-muted)',
color: 'var(--color-text)',
borderRadius: '4px',
minWidth: '150px',
},
header: {
fontSize: '14px',
fontWeight: 'bold' as const,
marginBottom: '4px',
color: 'var(--color-text)',
},
property: {
label: {
fontSize: '12px',
color: 'var(--color-text-2)',
marginRight: '4px',
fontWeight: '500' as const,
},
value: {
fontSize: '12px',
color: 'var(--color-text)',
fontWeight: '200' as const,
},
wrapper: {
display: 'flex',
alignItems: 'center',
gap: '4px',
},
},
error: {
container: {
padding: '8px',
backgroundColor: 'var(--color-error)',
color: 'white',
borderRadius: '4px',
fontSize: '12px',
},
message: {
fontWeight: 'bold' as const,
},
details: {
marginTop: '4px',
opacity: 0.8,
}
},
defaultComponent: {
container: {
display: 'flex',
gap: '8px',
marginBottom: '8px',
},
button: {
padding: '4px 8px',
fontSize: '12px',
borderRadius: '4px',
backgroundColor: 'var(--color-muted-2)',
color: 'var(--color-text)',
border: 'none',
cursor: 'pointer',
'&:hover': {
backgroundColor: 'var(--color-muted-3)',
}
}
}
} as const
// Color themes for different node types
export const NODE_THEMES = {
calendar: {
headerColor: '#0066cc',
backgroundColor: '#e6f0ff',
},
academic: {
headerColor: '#008000',
backgroundColor: '#e6ffe6',
},
curriculum: {
headerColor: '#ff8c00',
backgroundColor: '#fff3e6',
},
pastoral: {
headerColor: '#8a2be2',
backgroundColor: '#f5e6ff',
},
people: {
headerColor: '#cc0000',
backgroundColor: '#ffe6e6',
},
resource: {
headerColor: '#cccc00',
backgroundColor: '#fffff0',
},
} as const
// Node type to theme mapping
export const NODE_TYPE_THEMES: Record<string, keyof typeof NODE_THEMES> = {
// Calendar nodes
'cc-calendar-node': 'calendar',
'cc-calendar-year-node': 'calendar',
'cc-calendar-month-node': 'calendar',
'cc-calendar-week-node': 'calendar',
'cc-calendar-day-node': 'calendar',
'cc-calendar-time-chunk-node': 'calendar',
// Academic nodes
'cc-academic-year-node': 'academic',
'cc-academic-term-node': 'academic',
'cc-academic-week-node': 'academic',
'cc-academic-day-node': 'academic',
'cc-academic-period-node': 'academic',
'cc-registration-period-node': 'academic',
'cc-timetable-lesson-node': 'academic',
'cc-planned-lesson-node': 'academic',
'cc-school-timetable-node': 'academic',
'cc-user-teacher-timetable-node': 'academic',
'cc-user-timetable-lesson-node': 'academic',
// Curriculum nodes
'cc-curriculum-structure-node': 'curriculum',
'cc-key-stage-node': 'curriculum',
'cc-key-stage-syllabus-node': 'curriculum',
'cc-year-group-syllabus-node': 'curriculum',
'cc-subject-node': 'curriculum',
'cc-topic-node': 'curriculum',
'cc-topic-lesson-node': 'curriculum',
'cc-learning-statement-node': 'curriculum',
'cc-science-lab-node': 'curriculum',
// Pastoral nodes
'cc-pastoral-structure-node': 'pastoral',
'cc-year-group-node': 'pastoral',
// People nodes
'cc-user-node': 'people',
'cc-teacher-node': 'people',
'cc-student-node': 'people',
// Resource nodes
'cc-school-node': 'resource',
'cc-department-node': 'resource',
'cc-room-node': 'resource',
'cc-subject-class-node': 'resource',
} as const
// Helper function to get theme for a node type
export const getNodeTheme = (nodeType: string) => {
const themeKey = NODE_TYPE_THEMES[nodeType]
return themeKey ? NODE_THEMES[themeKey] : NODE_THEMES.resource // Default to resource theme
}
// Helper function to get theme from primary label
export const getThemeFromLabel = (primaryLabel: string) => {
// Convert primary label to node type format (e.g., 'User' -> 'cc-user-node')
const nodeType = `cc-${primaryLabel.toLowerCase()}-node`;
return getNodeTheme(nodeType);
}
// Helper function to get styles for a specific node type
export const getNodeStyles = (nodeType: string) => {
const theme = getNodeTheme(nodeType)
return {
...SHARED_NODE_STYLES,
container: {
...SHARED_NODE_STYLES.container,
backgroundColor: theme.backgroundColor,
},
}
}
@@ -0,0 +1,389 @@
import { TLBinding, TLBaseShape, TLShapeId } from '@tldraw/tldraw'
import { CCBaseShape } from '../cc-types'
import { CCBaseProps } from '../cc-props'
import { ccGraphShapeProps } from './cc-graph-props'
// Export type for graph shape types
export type GraphShapeType = keyof typeof ccGraphShapeProps
export interface ShapeState {
parentId: TLShapeId | null
isPageChild: boolean | null
hasChildren: boolean | null
bindings: TLBinding[] | null
}
export type CCGraphShapeProps = CCBaseProps & {
__primarylabel__: string
unique_id: string
tldraw_snapshot: string
created: string
merged: string
state: ShapeState | null | undefined
defaultComponent: boolean | null
}
// Define the base shape type for graph shapes
export type CCGraphShape = CCBaseShape & TLBaseShape<GraphShapeType, {
__primarylabel__: CCGraphShapeProps['__primarylabel__']
unique_id: CCGraphShapeProps['unique_id']
tldraw_snapshot: CCGraphShapeProps['tldraw_snapshot']
created: CCGraphShapeProps['created']
merged: CCGraphShapeProps['merged']
state: CCGraphShapeProps['state']
defaultComponent: CCGraphShapeProps['defaultComponent']
}>
export type CCUserNodeProps = CCGraphShapeProps & {
user_name: string
user_email: string
user_type: string
user_id: string
worker_node_data: string
}
export type CCTeacherNodeProps = CCGraphShapeProps & {
teacher_code: string
teacher_name_formal: string
teacher_email: string
user_db_name: string
school_db_name: string
}
export type CCStudentNodeProps = CCGraphShapeProps & {
student_name_formal: string
student_code: string
student_email: string
user_db_name: string
school_db_name: string
}
export type CCCalendarNodeProps = CCGraphShapeProps & {
title: string
name: string
calendar_type: string
calendar_name: string
start_date: string
end_date: string
}
export type CCCalendarYearNodeProps = CCGraphShapeProps & {
year: string
}
export type CCCalendarMonthNodeProps = CCGraphShapeProps & {
year: string
month: string
month_name: string
}
export type CCCalendarWeekNodeProps = CCGraphShapeProps & {
start_date: string
week_number: string
iso_week: string
}
export type CCCalendarDayNodeProps = CCGraphShapeProps & {
date: string
day_of_week: string
iso_day: string
}
export type CCCalendarTimeChunkNodeProps = CCGraphShapeProps & {
start_time: string
end_time: string
}
export type CCSchoolNodeProps = CCGraphShapeProps & {
school_uuid: string
school_name: string
school_website: string
}
export type CCDepartmentNodeProps = CCGraphShapeProps & {
department_name: string
}
export type CCRoomNodeProps = CCGraphShapeProps & {
room_code: string
room_name: string
}
export type CCSubjectClassNodeProps = CCGraphShapeProps & {
subject_class_code: string
year_group: string
subject: string
subject_code: string
}
export type CCPastoralStructureNodeProps = CCGraphShapeProps & {
pastoral_structure_type: string
}
export type CCYearGroupNodeProps = CCGraphShapeProps & {
year_group: string
year_group_name: string
}
export type CCCurriculumStructureNodeProps = CCGraphShapeProps & {
curriculum_structure_type: string
}
export type CCKeyStageNodeProps = CCGraphShapeProps & {
key_stage_name: string
key_stage: string
}
export type CCKeyStageSyllabusNodeProps = CCGraphShapeProps & {
ks_syllabus_id: string
ks_syllabus_name: string
ks_syllabus_key_stage: string
ks_syllabus_subject: string
ks_syllabus_subject_code: string
}
export type CCYearGroupSyllabusNodeProps = CCGraphShapeProps & {
yr_syllabus_id: string
yr_syllabus_name: string
yr_syllabus_year_group: string
yr_syllabus_subject: string
yr_syllabus_subject_code: string
}
export type CCSubjectNodeProps = CCGraphShapeProps & {
subject_code: string
subject_name: string
}
export type CCTopicNodeProps = CCGraphShapeProps & {
topic_id: string
topic_title: string
total_number_of_lessons_for_topic: string
topic_type: string
topic_assessment_type: string
}
export type CCTopicLessonNodeProps = CCGraphShapeProps & {
topic_lesson_id: string
topic_lesson_title: string
topic_lesson_type: string
topic_lesson_length: string
topic_lesson_skills_learned: string
topic_lesson_suggested_activities: string
topic_lesson_weblinks: string
}
export type CCLearningStatementNodeProps = CCGraphShapeProps & {
lesson_learning_statement_id: string
lesson_learning_statement: string
lesson_learning_statement_type: string
}
export type CCScienceLabNodeProps = CCGraphShapeProps & {
science_lab_id: string
science_lab_title: string
science_lab_summary: string
science_lab_requirements: string
science_lab_procedure: string
science_lab_safety: string
science_lab_weblinks: string
}
export type CCTeacherTimetableNodeProps = CCGraphShapeProps & {
teacher_id: string
start_date: string
end_date: string
}
export type CCTimetableLessonNodeProps = CCGraphShapeProps & {
subject_class: string
date: string
start_time: string
end_time: string
period_code: string
}
export type CCPlannedLessonNodeProps = CCGraphShapeProps & {
date: string
start_time: string
end_time: string
period_code: string
subject_class: string
year_group: string
subject: string
teacher_code: string
planning_status: string
topic_code: string
topic_name: string
lesson_code: string
lesson_name: string
learning_statement_codes: string
learning_statements: string
learning_resource_codes: string
learning_resources: string
}
export type CCSchoolTimetableNodeProps = CCGraphShapeProps & {
start_date: string
end_date: string
}
export type CCAcademicYearNodeProps = CCGraphShapeProps & {
year: string
}
export type CCAcademicTermNodeProps = CCGraphShapeProps & {
term_name: string
term_number: string
start_date: string
end_date: string
}
export type CCAcademicWeekNodeProps = CCGraphShapeProps & {
academic_week_number: string
start_date: string
week_type: string
}
export type CCAcademicDayNodeProps = CCGraphShapeProps & {
academic_day: string
date: string
day_of_week: string
day_type: string
}
export type CCAcademicPeriodNodeProps = CCGraphShapeProps & {
name: string
date: string
start_time: string
end_time: string
period_code: string
}
export type CCRegistrationPeriodNodeProps = CCGraphShapeProps & {
name: string
date: string
start_time: string
end_time: string
period_code: string
}
export type CCDepartmentStructureNodeProps = CCGraphShapeProps & {
department_structure_type: string
}
export type CCUserTeacherTimetableNodeProps = CCGraphShapeProps & {
school_db_name: string
school_timetable_id: string
}
export type CCUserTimetableLessonNodeProps = CCGraphShapeProps & {
subject_class: string
date: string
start_time: string
end_time: string
period_code: string
school_db_name: string
school_period_id: string
}
// Define a type-safe mapping of node types to their configurations
export type CCNodeTypes = {
User: { props: CCUserNodeProps }
Developer: { props: CCUserNodeProps }
Teacher: { props: CCTeacherNodeProps }
Student: { props: CCStudentNodeProps }
Calendar: { props: CCCalendarNodeProps }
TeacherTimetable: { props: CCTeacherTimetableNodeProps }
TimetableLesson: { props: CCTimetableLessonNodeProps }
PlannedLesson: { props: CCPlannedLessonNodeProps }
School: { props: CCSchoolNodeProps }
CalendarYear: { props: CCCalendarYearNodeProps }
CalendarMonth: { props: CCCalendarMonthNodeProps }
CalendarWeek: { props: CCCalendarWeekNodeProps }
CalendarDay: { props: CCCalendarDayNodeProps }
CalendarTimeChunk: { props: CCCalendarTimeChunkNodeProps }
ScienceLab: { props: CCScienceLabNodeProps }
KeyStageSyllabus: { props: CCKeyStageSyllabusNodeProps }
YearGroupSyllabus: { props: CCYearGroupSyllabusNodeProps }
CurriculumStructure: { props: CCCurriculumStructureNodeProps }
Topic: { props: CCTopicNodeProps }
TopicLesson: { props: CCTopicLessonNodeProps }
LearningStatement: { props: CCLearningStatementNodeProps }
SchoolTimetable: { props: CCSchoolTimetableNodeProps }
AcademicYear: { props: CCAcademicYearNodeProps }
AcademicTerm: { props: CCAcademicTermNodeProps }
AcademicWeek: { props: CCAcademicWeekNodeProps }
AcademicDay: { props: CCAcademicDayNodeProps }
AcademicPeriod: { props: CCAcademicPeriodNodeProps }
RegistrationPeriod: { props: CCRegistrationPeriodNodeProps }
PastoralStructure: { props: CCPastoralStructureNodeProps }
KeyStage: { props: CCKeyStageNodeProps }
Department: { props: CCDepartmentNodeProps }
Room: { props: CCRoomNodeProps }
SubjectClass: { props: CCSubjectClassNodeProps }
DepartmentStructure: { props: CCDepartmentStructureNodeProps }
UserTeacherTimetable: { props: CCUserTeacherTimetableNodeProps }
UserTimetableLesson: { props: CCUserTimetableLessonNodeProps }
}
// Helper function to get shape type from node type
export const getShapeType = (nodeType: keyof CCNodeTypes): string => {
return `cc-${nodeType.replace(/([A-Z])/g, '-$1').toLowerCase().substring(1)}-node`;
}
// Helper function to get allowed props from node type
export const getAllowedProps = (): string[] => {
return ['__primarylabel__', 'unique_id'];
}
// Helper function to get node configuration
export const getNodeConfig = <T extends keyof CCNodeTypes>(nodeType: T) => {
const shapeType = getShapeType(nodeType);
return {
shapeType,
allowedProps: getAllowedProps()
};
}
// Helper function to check if a string is a valid node type
export const isValidNodeType = (type: string): type is keyof CCNodeTypes => {
return type in {
User: true,
Developer: true,
Teacher: true,
Student: true,
Calendar: true,
TeacherTimetable: true,
TimetableLesson: true,
PlannedLesson: true,
School: true,
CalendarYear: true,
CalendarMonth: true,
CalendarWeek: true,
CalendarDay: true,
CalendarTimeChunk: true,
ScienceLab: true,
KeyStageSyllabus: true,
YearGroupSyllabus: true,
CurriculumStructure: true,
Topic: true,
TopicLesson: true,
LearningStatement: true,
SchoolTimetable: true,
AcademicYear: true,
AcademicTerm: true,
AcademicWeek: true,
AcademicDay: true,
AcademicPeriod: true,
RegistrationPeriod: true,
PastoralStructure: true,
KeyStage: true,
Department: true,
Room: true,
SubjectClass: true,
DepartmentStructure: true,
UserTeacherTimetable: true,
UserTimetableLesson: true,
};
}
@@ -0,0 +1,218 @@
import { Editor, createShapeId } from '@tldraw/tldraw';
import { getShapeType, isValidNodeType } from './cc-graph-types';
import { AllNodeShapes, NodeShapeType } from './cc-graph-shapes';
import { logger } from '../../../../debugConfig';
export const GRID_CELL_SIZE = 250;
export const GRID_PADDING = 50;
export const GRID_MAX_COLUMNS = 8;
export const graphState = {
nodeData: new Map<string, AllNodeShapes>(),
shapeIds: new Set<string>(),
editor: null as Editor | null,
arrangeNodesInGrid: () => {
if (!graphState.editor) {
logger.error('graphStateUtil', '❌ Editor not initialized');
return;
}
const nodes = Array.from(graphState.nodeData.values());
if (nodes.length === 0) return;
logger.debug('graphStateUtil', '📊 Arranging nodes in grid', {
nodeCount: nodes.length,
currentNodes: nodes
});
// Get viewport bounds
const viewportBounds = graphState.editor.getViewportPageBounds();
// Calculate available space
const availableWidth = viewportBounds.width;
// Calculate number of columns based on available space
const columnsFromSpace = Math.floor(availableWidth / (GRID_CELL_SIZE + GRID_PADDING));
const gridColumns = Math.min(
Math.max(1, Math.min(columnsFromSpace, GRID_MAX_COLUMNS)),
Math.ceil(Math.sqrt(nodes.length * 2)) // Allow grid to grow with more nodes
);
// Calculate total grid dimensions
const rowCount = Math.ceil(nodes.length / gridColumns);
const totalWidth = gridColumns * (GRID_CELL_SIZE + GRID_PADDING);
const totalHeight = rowCount * (GRID_CELL_SIZE + GRID_PADDING);
// Calculate starting position to center the grid
const startX = viewportBounds.minX + (viewportBounds.width - totalWidth) / 2;
const startY = viewportBounds.minY + (viewportBounds.height - totalHeight) / 2;
// Track created/updated shapes for viewport adjustment
const updatedShapeIds: string[] = [];
nodes.forEach((node, index) => {
if (!node.props?.unique_id) return;
const row = Math.floor(index / gridColumns);
const col = index % gridColumns;
const x = startX + (col * (GRID_CELL_SIZE + GRID_PADDING));
const y = startY + (row * (GRID_CELL_SIZE + GRID_PADDING));
const shapeId = createShapeId(node.props.unique_id);
updatedShapeIds.push(shapeId.toString());
// Update both our internal state and the editor
node.x = x;
node.y = y;
graphState.nodeData.set(node.props.unique_id, node);
// Only create if the shape doesn't exist in our tracking
if (!graphState.shapeIds.has(shapeId.toString())) {
graphState.editor!.createShape({
id: shapeId,
type: node.type,
x: x,
y: y,
props: node.props
});
graphState.shapeIds.add(shapeId.toString());
logger.debug('graphStateUtil', ' Created new shape', {
id: shapeId.toString(),
position: { x, y }
});
} else {
graphState.editor!.updateShape({
id: shapeId,
type: node.type,
x: x,
y: y,
});
logger.debug('graphStateUtil', '🔄 Updated existing shape', {
id: shapeId.toString(),
position: { x, y }
});
}
});
// Only attempt to adjust view if we have shapes
if (updatedShapeIds.length > 0) {
const shapeIds = updatedShapeIds.map(id => createShapeId(id));
graphState.editor.select(...shapeIds);
graphState.editor.zoomToSelection();
graphState.editor.deselect();
logger.debug('graphStateUtil', '🔍 Adjusted viewport for shapes', {
shapeCount: updatedShapeIds.length
});
}
},
updateShapesWithDagre: () => {
if (!graphState.editor) {
logger.error('graphStateUtil', '❌ Editor not initialized');
return;
}
graphState.arrangeNodesInGrid();
},
addNode: (shape: AllNodeShapes) => {
logger.debug('graphStateUtil', '🔍 Adding shape to graphState:', { shape });
if (!shape.props?.unique_id || !shape.type) {
logger.error('graphStateUtil', '❌ Invalid shape data', { shape });
return;
}
const id = shape.props.unique_id;
const shapeId = createShapeId(id).toString();
// Track the shape ID
graphState.shapeIds.add(shapeId);
const nodeType = shape.props.__primarylabel__;
if (!isValidNodeType(nodeType)) {
logger.error('graphStateUtil', '❌ Unknown node type', {
type: nodeType,
shape
});
return;
}
const shapeType = getShapeType(nodeType) as NodeShapeType;
graphState.nodeData.set(id, {
...shape,
type: shapeType
} as AllNodeShapes);
// Only rearrange if we have an editor
if (graphState.editor) {
graphState.arrangeNodesInGrid();
}
},
getNode: (id: string) => {
return graphState.nodeData.get(id);
},
getAllNodes: () => {
return Array.from(graphState.nodeData.values()).filter(item => {
// Check if the item has a type property and it's not an edge type
logger.debug('graphStateUtil', '🔍 Checking if item has a type property and it\'s not an edge type:', { item });
return item.type && !item.type.includes('relationship');
});
},
setEditor: (editor: Editor) => {
graphState.editor = editor;
graphState.shapeIds.clear();
},
updateNodePosition: (nodeId: string, newPos: { x: number, y: number }) => {
const node = graphState.nodeData.get(nodeId);
if (node) {
node.x = newPos.x;
node.y = newPos.y;
graphState.nodeData.set(nodeId, node);
// If we have an editor reference, update the shape
if (graphState.editor) {
const shapeId = createShapeId(nodeId);
logger.debug('graphStateUtil', '🎯 Updating shape position', {
id: shapeId,
position: { x: newPos.x, y: newPos.y }
});
graphState.editor.updateShape({
id: shapeId,
type: node.type,
x: newPos.x,
y: newPos.y,
});
}
logger.debug('graphStateUtil', '📍 Updated node position', {
nodeId,
newPos,
node
});
}
},
hasNode: (uniqueId: string): boolean => {
return graphState.nodeData.has(uniqueId);
},
getShapeByUniqueId: (uniqueId: string) => {
return Array.from(graphState.nodeData.values()).find(
shape => shape.props?.unique_id === uniqueId
);
},
hasShape: (shapeId: string): boolean => {
return graphState.shapeIds.has(shapeId);
},
};