35 KiB
Types Module
Overview
The types module provides TypeScript type definitions used throughout the frontend application. These types ensure type safety, enable IDE autocompletion, and document the data structures used across components, hooks, stores, and API interactions.
Location: frontend/src/types/
Statistics:
- 19 files (~2,110 LOC total)
- 6 categories: Domain Entities, Runtime/Presentation, Infrastructure, Forms/Filters, Specialized, Module Declarations
- Central export via
index.ts
Architecture Diagram
frontend/src/types/
├── index.ts # Central re-export (14 LOC)
│
├── Domain Entities
│ ├── entities.ts # Database entity types (307 LOC)
│ ├── constructor.ts # Canvas element types (418 LOC)
│ └── permissions.ts # RBAC permission enum (122 LOC)
│
├── Runtime & Presentation
│ ├── runtime.ts # Runtime page/project types (92 LOC)
│ ├── presentation.ts # Navigation/transition types (107 LOC)
│ ├── uiControls.ts # Global UI-control cascade/settings types
│ └── preload.ts # Preload infrastructure types (57 LOC)
│
├── Infrastructure
│ ├── offline.ts # PWA/offline storage types (194 LOC)
│ ├── api.ts # API request/response types (62 LOC)
│ └── redux.ts # Redux state types (60 LOC)
│
├── Forms & Filters
│ ├── forms.ts # Form configuration types (76 LOC)
│ └── filters.ts # Table filter types (74 LOC)
│
├── Specialized
│ ├── charts.ts # Chart/dashboard data types (42 LOC)
│ ├── components.ts # UI component prop types (30 LOC)
│ ├── menu.ts # Navigation menu types (25 LOC)
│ └── ui.ts # Generic UI element types (35 LOC)
│
└── Module Declarations
└── css.d.ts # CSS module type declarations (10 LOC)
Type Categories
1. Domain Entities (entities.ts)
Core database entity types that mirror backend Sequelize models.
BaseEntity
export interface BaseEntity {
id: string;
createdAt?: string;
updatedAt?: string;
}
User Entity
export interface User extends BaseEntity {
firstName?: string;
lastName?: string;
phoneNumber?: string;
email: string;
disabled?: boolean;
avatar?: ImageFile[];
app_role?: Role | null;
custom_permissions?: PermissionEntity[];
password?: string;
}
Project Entity
export interface Project extends BaseEntity {
name: string;
slug?: string;
description?: string;
logo_url?: string;
favicon_url?: string;
og_image_url?: string;
design_width?: number; // Design canvas width (default 1920)
design_height?: number; // Design canvas height (default 1080)
is_deleted?: boolean;
deleted_at_time?: string | Date | null;
}
Asset Entity
export interface Asset extends BaseEntity {
project?: Project | string | null;
name: string;
asset_type: 'image' | 'video' | 'audio' | 'file';
type?: 'general' | 'icon' | 'background_image' | 'audio' | 'video'
| 'transition' | 'logo' | 'favicon' | 'document';
cdn_url?: string;
storage_key?: string;
mime_type?: string;
size_mb?: number;
width_px?: number;
height_px?: number;
duration_sec?: number;
checksum?: string;
is_public?: boolean;
is_deleted?: boolean;
deleted_at_time?: string | Date;
}
TourPage Entity
export interface TourPage extends BaseEntity {
project?: Project | string | null;
name?: string;
title?: string;
slug?: string;
background_asset?: Asset | string | null;
audio_asset?: Asset | string | null;
is_start_page?: boolean;
sort_order?: number;
environment?: 'dev' | 'stage' | 'production';
source_key?: string;
requires_auth?: boolean;
ui_schema_json?: string;
// Background URL fields (direct storage paths)
background_image_url?: string;
background_video_url?: string;
background_audio_url?: string;
background_loop?: boolean;
// Background video playback settings
background_video_autoplay?: boolean;
background_video_loop?: boolean;
background_video_muted?: boolean;
background_video_start_time?: number | null;
background_video_end_time?: number | null;
// Background audio playback settings
background_audio_autoplay?: boolean;
background_audio_loop?: boolean;
background_audio_start_time?: number | null;
background_audio_end_time?: number | null;
// Design canvas dimensions (copied from project on save)
design_width?: number | null;
design_height?: number | null;
}
Complete Entity List
| Entity | Description |
|---|---|
User |
User accounts with roles and permissions |
Role |
Role definitions with permission sets |
PermissionEntity |
Individual permission records |
Project |
Tour projects with configuration |
Asset |
Media assets (images, videos, audio) |
AssetVariant |
Variant versions (thumbnails, previews) |
TourPage |
Tour pages with backgrounds |
PageElement |
UI elements on pages |
PageLink |
Navigation links between pages |
Transition |
Video transitions |
ProjectAudioTrack |
Background audio tracks |
ProjectMembership |
User-project access |
PublishEvent |
Publishing history |
PwaCache |
PWA cache tracking |
PresignedUrlRequest |
File upload/download requests |
AccessLog |
Audit trail entries |
UIElement |
Generic UI element |
Entity Type Map
// Type-safe entity name to type mapping
export type EntityName =
| 'users' | 'roles' | 'permissions' | 'projects'
| 'project_memberships' | 'assets' | 'asset_variants'
| 'tour_pages' | 'project_audio_tracks' | 'publish_events'
| 'pwa_caches' | 'presigned_url_requests' | 'access_logs'
| 'element_type_defaults';
export interface EntityTypeMap {
users: User;
roles: Role;
permissions: PermissionEntity;
projects: Project;
// ... all entities mapped
}
2. Constructor Types (constructor.ts)
Types for the tour builder (constructor) page and UI elements.
Canvas Element Types
// 11 available element types
export type CanvasElementType =
| 'navigation_next' // Forward navigation button
| 'navigation_prev' // Back navigation button
| 'spot' // Hotspot/clickable area
| 'description' // Text description block
| 'tooltip' // Hover tooltip
| 'gallery' // Image gallery
| 'carousel' // Image carousel
| 'logo' // Logo element
| 'video_player' // Video player
| 'audio_player' // Audio player
| 'popup'; // Popup/modal
CanvasElement Interface
export interface CanvasElement extends BaseCanvasElement {
type: CanvasElementType;
label: string;
xPercent: number;
yPercent: number;
// Icon
iconUrl?: string;
// Media
mediaUrl?: string;
mediaAutoplay?: boolean;
mediaLoop?: boolean;
mediaMuted?: boolean;
// Background
backgroundImageUrl?: string;
videoUrl?: string;
audioUrl?: string;
// Gallery/Carousel
galleryCards?: GalleryCard[];
galleryHeaderImageUrl?: string;
galleryTitle?: string;
galleryInfoSpans?: GalleryInfoSpan[];
galleryColumns?: number;
galleryTitleFontFamily?: string;
galleryCardFontFamily?: string;
carouselSlides?: CarouselSlide[];
carouselCaptionFontFamily?: string;
carouselPrevIconUrl?: string;
carouselNextIconUrl?: string;
// Gallery Carousel Settings (button icons, positions, dimensions)
galleryCarouselPrevIconUrl?: string;
galleryCarouselNextIconUrl?: string;
galleryCarouselBackIconUrl?: string;
galleryCarouselBackLabel?: string;
galleryCarouselPrevX?: number;
galleryCarouselPrevY?: number;
galleryCarouselNextX?: number;
galleryCarouselNextY?: number;
galleryCarouselBackX?: number;
galleryCarouselBackY?: number;
galleryCarouselPrevWidth?: string;
galleryCarouselPrevHeight?: string;
galleryCarouselNextWidth?: string;
galleryCarouselNextHeight?: string;
galleryCarouselBackWidth?: string;
galleryCarouselBackHeight?: string;
// Info Panel trigger/default behavior
infoPanelTriggerLabel?: string;
infoPanelTriggerFontFamily?: string;
infoPanelDisabled?: boolean;
infoPanelOpenByDefault?: boolean;
// Tooltip
tooltipTitle?: string;
tooltipText?: string;
tooltipTitleFontFamily?: string;
tooltipTextFontFamily?: string;
// Description
descriptionTitle?: string;
descriptionText?: string;
descriptionTitleFontSize?: string;
descriptionTextFontSize?: string;
descriptionTitleFontFamily?: string;
descriptionTextFontFamily?: string;
descriptionTitleColor?: string;
descriptionTextColor?: string;
descriptionBackgroundColor?: string;
// Navigation
navLabel?: string;
navType?: NavigationButtonKind;
navDisabled?: boolean;
/** @deprecated Use targetPageSlug instead */
targetPageId?: string;
targetPageSlug?: string;
transitionVideoUrl?: string;
transitionReverseMode?: 'auto_reverse' | 'separate_video';
reverseVideoUrl?: string;
transitionDurationSec?: number;
}
Gallery & Carousel Items
export interface GalleryCard {
id: string;
imageUrl: string;
title: string;
description: string;
}
export interface GalleryInfoSpan {
id: string;
text: string;
}
export interface CarouselSlide {
id: string;
imageUrl: string;
caption: string;
}
Constructor Schema & Asset Types
export interface ConstructorSchema {
elements?: CanvasElement[];
}
export interface ConstructorAsset {
id: string;
name?: string;
asset_type?: 'image' | 'video' | 'audio' | 'file';
type?: 'icon' | 'background_image' | 'audio' | 'video'
| 'transition' | 'logo' | 'favicon' | 'document' | 'general';
cdn_url?: string | null;
storage_key?: string | null;
}
export interface AssetOption {
value: string;
label: string;
}
Type Guards
// Type guard for canvas element types
export function isCanvasElementType(value: string): value is CanvasElementType {
return CANVAS_ELEMENT_TYPES.includes(value as CanvasElementType);
}
Element Default Normalization
// Normalize API response to consistent format
export function normalizeElementDefault(
row: Record<string, unknown>,
): NormalizedElementDefault | null;
// Build lookup map from defaults array
export function buildElementDefaultsMap(
defaults: NormalizedElementDefault[],
): Partial<Record<CanvasElementType, Partial<CanvasElement>>>;
Page Background State Types
// Video playback settings
export interface PageBackgroundVideoSettings {
autoplay: boolean;
loop: boolean;
muted: boolean;
startTime: number | null;
endTime: number | null;
}
// Audio playback settings
export interface PageBackgroundAudioSettings {
autoplay: boolean;
loop: boolean;
startTime: number | null;
endTime: number | null;
}
// Consolidated background state (replaces 8 useState hooks)
export interface PageBackgroundState {
imageUrl: string;
videoUrl: string;
audioUrl: string;
videoSettings: PageBackgroundVideoSettings;
audioSettings: PageBackgroundAudioSettings;
}
// Default constants
export const DEFAULT_VIDEO_SETTINGS: PageBackgroundVideoSettings;
export const DEFAULT_AUDIO_SETTINGS: PageBackgroundAudioSettings;
export const DEFAULT_PAGE_BACKGROUND: PageBackgroundState;
// Factory function
export function createPageBackgroundFromPage(
page: TourPage | null
): PageBackgroundState;
Editor Panel Props
The constructor types also define grouped props interfaces for the ElementEditorPanel:
| Interface | Purpose |
|---|---|
EditorLayoutProps |
Panel position and collapse state |
EditorStateProps |
Tabs and title |
EditorElementProps |
Selected element and callbacks |
EditorBackgroundProps |
Background image/video/audio URLs |
EditorTransitionProps |
Transition creation state |
EditorDurationNotesProps |
Duration display notes |
EditorAssetOptionsProps |
Asset dropdown options |
EditorNavigationProps |
Navigation settings |
EditorCollectionOpsProps |
Gallery/carousel operations |
EditorMediaUtilsProps |
Duration utilities |
3. Permissions (permissions.ts)
RBAC (Role-Based Access Control) permission definitions.
Permission Enum
export enum Permission {
// User permissions
READ_USERS = 'READ_USERS',
CREATE_USERS = 'CREATE_USERS',
UPDATE_USERS = 'UPDATE_USERS',
DELETE_USERS = 'DELETE_USERS',
// Role permissions
READ_ROLES = 'READ_ROLES',
CREATE_ROLES = 'CREATE_ROLES',
UPDATE_ROLES = 'UPDATE_ROLES',
DELETE_ROLES = 'DELETE_ROLES',
// Project permissions
READ_PROJECTS = 'READ_PROJECTS',
CREATE_PROJECTS = 'CREATE_PROJECTS',
UPDATE_PROJECTS = 'UPDATE_PROJECTS',
DELETE_PROJECTS = 'DELETE_PROJECTS',
// ... 60+ total permissions covering all entities
}
Permission Helper
// Generate CRUD permissions for any entity
export const getEntityPermissions = (entityName: string) => {
const uppercased = entityName.toUpperCase();
return {
read: `READ_${uppercased}` as PermissionString,
create: `CREATE_${uppercased}` as PermissionString,
update: `UPDATE_${uppercased}` as PermissionString,
delete: `DELETE_${uppercased}` as PermissionString,
};
};
// Usage
const assetPerms = getEntityPermissions('assets');
// { read: 'READ_ASSETS', create: 'CREATE_ASSETS', ... }
4. Runtime Types (runtime.ts)
Types for runtime presentation playback.
RuntimeProject
export interface RuntimeProject {
id: string;
name?: string;
slug?: string;
description?: string;
}
RuntimePage
// Extends PreloadPage with display/navigation fields
export interface RuntimePage extends PreloadPage {
slug?: string;
name?: string;
sort_order?: number;
ui_schema_json?: string;
environment?: 'dev' | 'stage' | 'production';
// Background video playback settings
background_video_autoplay?: boolean;
background_video_loop?: boolean;
background_video_muted?: boolean;
background_video_start_time?: number | null;
background_video_end_time?: number | null;
// Background audio playback settings
background_audio_autoplay?: boolean;
background_audio_loop?: boolean;
background_audio_start_time?: number | null;
background_audio_end_time?: number | null;
// Design canvas dimensions (copied from project on save)
design_width?: number | null;
design_height?: number | null;
}
RuntimeTransition
export interface RuntimeTransition {
id: string;
name?: string;
slug?: string;
video_url?: string;
duration_sec?: number;
supports_reverse?: boolean;
}
TransitionOverlayState
export interface TransitionOverlayState {
targetPageId: string;
transitionName: string;
videoUrl: string;
isReverse: boolean;
durationSec?: number;
}
Global UI Control Types (uiControls.ts)
Global UI-control types describe the fullscreen, sound, and offline system buttons and their cascade:
export type SystemUiControlType = 'fullscreen' | 'sound' | 'offline';
export type SystemUiControlAnchor =
| 'center'
| 'top-left'
| 'top-right'
| 'bottom-left'
| 'bottom-right';
export interface SystemUiControlSettings {
enabled?: boolean;
hidden?: boolean;
xPercent?: number;
yPercent?: number;
anchor?: SystemUiControlAnchor;
buttonSizePercent?: number;
iconSizePercent?: number;
defaultIconUrl?: string;
activeIconUrl?: string;
defaultBackgroundColor?: string;
activeBackgroundColor?: string;
defaultBorderColor?: string;
activeBorderColor?: string;
}
Helpers:
resolveUiControlsSettings(global, project, page)merges the cascade field-by-field.parseUiControlsSettings(value)normalizes JSON/string input.getSystemControlAnchorBounds(anchor, size, aspectRatio)clamps controls inside the visible canvas.
5. Presentation Types (presentation.ts)
Shared types for RuntimePresentation and constructor.tsx.
Note: Not exported from index.ts, must import directly from @/types/presentation.
Navigation Types
export interface NavigableElement {
id: string;
type: string;
targetPageSlug?: string;
targetPageId?: string;
transitionVideoUrl?: string;
navType?: 'forward' | 'back';
navDisabled?: boolean;
}
export interface NavigationTarget {
page: RuntimePage;
pageId: string;
transitionVideoUrl?: string;
isBack: boolean;
}
RuntimeProject (Presentation)
// Duplicate definition for page data loader context
export interface RuntimeProject {
id: string;
name?: string;
slug?: string;
description?: string;
}
Transition Phase
export type TransitionPhase =
| 'idle' // No transition
| 'preparing' // Loading video
| 'playing' // Forward playback
| 'reversing' // Reverse playback
| 'completed'; // Finished
Background State
export interface BackgroundState {
imageUrl: string;
videoUrl: string;
audioUrl: string;
}
export interface TransitionPreviewState {
targetPageId: string;
videoUrl: string;
storageKey: string;
isReverse: boolean;
}
Page Data Loader
export interface PageDataLoaderResult {
project: RuntimeProject | null;
pages: RuntimePage[];
isLoading: boolean;
error: string;
reload: (preservePageId?: string) => Promise<void>;
}
Runtime API Config
export interface RuntimeApiConfig {
headers: {
'X-Runtime-Project-Slug'?: string;
'X-Runtime-Environment'?: string;
};
}
Background Transition Options
export interface BackgroundTransitionOptions {
pendingTransitionComplete: boolean;
isBackgroundReady: boolean;
transitionVideoRef: React.RefObject<HTMLVideoElement | null>;
pageSwitch: {
clearPreviousBackground: () => void;
isSwitching: boolean;
isNewBgReady: boolean;
previousBgImageUrl: string;
};
onCleanup: () => void;
}
6. Preload Types (preload.ts)
Minimal types for asset preloading infrastructure.
PreloadPage
// Simplified page type (subset of TourPage)
export interface PreloadPage {
id: string;
background_image_url?: string;
background_video_url?: string;
background_audio_url?: string;
}
PreloadPageLink
export interface PreloadPageLink {
id: string;
from_pageId?: string;
to_pageId?: string;
is_active?: boolean;
transition?: {
id: string;
video_url?: string;
};
}
PreloadElement
export interface PreloadElement {
id: string;
pageId?: string;
element_type?: string;
content_json?: string;
}
PreloadAssetInfo
export interface PreloadAssetInfo {
url: string;
pageId: string;
assetType: 'image' | 'video' | 'audio' | 'transition' | 'other';
priority: number;
}
PreloadNeighborInfo
export interface PreloadNeighborInfo {
pageId: string;
distance: number;
}
7. Offline Types (offline.ts)
Types for PWA and offline storage functionality.
Asset Variant & Type
export type AssetVariantType =
| 'thumbnail' | 'preview' | 'webp'
| 'mp4_low' | 'mp4_high' | 'original';
export type AssetType = 'image' | 'video' | 'audio' | 'transition' | 'other';
Preload Job
export type PreloadJobStatus =
| 'queued' | 'downloading' | 'completed' | 'error' | 'paused';
export interface PreloadJob {
id: string;
assetId: string;
url: string;
filename: string;
progress: number;
status: PreloadJobStatus;
bytesLoaded: number;
totalBytes: number;
pageId?: string;
variantType?: AssetVariantType;
assetType?: AssetType;
error?: string;
addedAt: number;
startedAt?: number;
completedAt?: number;
}
Offline Project
export type ProjectOfflineStatus =
| 'not_downloaded' | 'downloading' | 'downloaded' | 'outdated' | 'error';
export interface OfflineProject {
id: string;
slug: string;
name: string;
status: ProjectOfflineStatus;
totalAssets: number;
downloadedAssets: number;
totalSizeBytes: number;
downloadedSizeBytes: number;
lastSyncedAt?: number;
version?: string;
}
Offline Asset (IndexedDB)
export interface OfflineAsset {
id: string;
projectId: string;
url: string;
filename: string;
variantType: AssetVariantType;
assetType: AssetType;
mimeType: string;
sizeBytes: number;
blob: Blob;
downloadedAt: number;
}
Download Queue Item
export interface DownloadQueueItem {
id: string;
projectId: string;
assetId: string;
url: string;
filename: string;
status: PreloadJobStatus;
priority: number;
retryCount: number;
bytesLoaded: number;
totalBytes: number;
addedAt: number;
lastAttemptAt?: number;
error?: string;
}
Network & Storage Info
export interface NetworkInfo {
isOnline: boolean;
effectiveType?: 'slow-2g' | '2g' | '3g' | '4g';
downlink?: number; // Mbps
rtt?: number; // ms
saveData?: boolean;
}
export interface StorageQuotaInfo {
usage: number;
quota: number;
percentUsed: number;
available: number;
canStore: (bytes: number) => boolean;
}
Offline Manifest
export interface OfflineManifest {
version: string;
projectId: string;
projectSlug: string;
assets: ManifestAsset[];
totalSizeBytes: number;
generatedAt: number;
}
export interface ManifestAsset {
id: string;
url: string;
filename: string;
variantType: AssetVariantType;
assetType: AssetType;
mimeType: string;
sizeBytes: number;
pageIds: string[];
}
Preload State & Neighbor Graph
export interface PreloadState {
isActive: boolean;
currentPageId: string | null;
queuedAssets: string[];
loadingAssets: string[];
completedAssets: string[];
failedAssets: string[];
totalProgress: number;
}
export interface NeighborGraph {
connections: Map<string, Array<{ pageId: string; distance: number }>>;
getNeighbors: (pageId: string, maxDepth: number) => string[];
getAssetsForPages: (pageIds: string[]) => string[];
}
Event Payloads
export interface PreloadStartEvent {
jobId: string;
assetId: string;
url: string;
}
export interface PreloadProgressEvent {
jobId: string;
progress: number;
bytesLoaded: number;
totalBytes: number;
}
export interface PreloadCompleteEvent {
jobId: string;
assetId: string;
}
export interface PreloadErrorEvent {
jobId: string;
assetId: string;
error: string;
}
export interface ProjectDownloadProgressEvent {
projectId: string;
progress: number;
downloadedAssets: number;
totalAssets: number;
downloadedBytes: number;
totalBytes: number;
}
export interface ProjectDownloadCompleteEvent {
projectId: string;
}
8. API Types (api.ts)
Types for API requests and responses.
Paginated Response
export interface PaginatedResponse<T> {
rows: T[];
count: number;
}
Fetch Parameters
export interface FetchParams {
id?: string;
query?: string;
limit?: number;
page?: number;
}
List Query Parameters
export interface ListQueryParams {
page?: number;
limit?: number;
sort?: 'asc' | 'desc';
field?: string;
[filterKey: string]: string | number | boolean | undefined;
}
Sort Model & Autocomplete
export interface SortModel {
field: string;
sort: 'asc' | 'desc';
}
export interface AutocompleteItem {
id: string;
label: string;
}
API Error
export interface ApiError {
message?: string;
statusCode?: number;
errors?: Record<string, { _errors: string[] }>;
}
Mutation Payloads
export interface MutationPayload<T> {
id?: string;
data: Partial<T>;
}
export interface DeleteByIdsPayload {
ids: string[];
}
export interface CsvUploadResponse {
imported: number;
errors?: string[];
}
9. Redux Types (redux.ts)
Types for Redux state management.
Notification State
export interface NotificationState {
showNotification: boolean;
textNotification: string;
typeNotification: 'warn' | 'error' | 'success' | 'info' | '';
}
Entity Slice State
export interface EntitySliceState<T> {
data: T[];
loading: boolean;
count: number;
refetch: boolean;
notify: NotificationState;
}
Slice Factory Config
export interface EntitySliceConfig {
name: string;
endpoint: string;
singularName?: string; // For notification messages
}
Core State Types
export interface AuthState {
currentUser: User | null;
token: string | null;
isFetching: boolean;
errorMessage: string | null;
loadingMessage: string | null;
notify: NotificationState;
}
export interface StyleState {
darkMode: boolean;
bgLayoutColor: string;
focusRingColor: string;
corners: string;
cardsColor: string;
}
export interface MainState {
isAsideMobileExpanded: boolean;
isAsideLgActive: boolean;
}
10. Forms Types (forms.ts)
Types for form rendering and validation.
Form Field Types
export type FormFieldType =
| 'text' | 'email' | 'number' | 'password'
| 'textarea' | 'richtext'
| 'select' | 'multiselect'
| 'date' | 'datetime'
| 'boolean' | 'switch'
| 'image' | 'file' | 'enum';
Form Field Config
export interface FormFieldConfig {
name: string;
label: string;
type: FormFieldType;
required?: boolean;
placeholder?: string;
itemRef?: string; // Entity endpoint for options
showField?: string; // Display field from options
options?: EnumOption[];
uploadPath?: string;
fileSchema?: FileSchema;
min?: number;
max?: number;
maxLength?: number;
className?: string;
}
Form Page Config
export interface FormPageConfig<TFormData> {
entityName: string;
entityTitle: string;
mode: 'create' | 'edit';
permission: string;
initialValues: TFormData;
fields: FormFieldConfig[];
listPath?: string;
}
11. Filters Types (filters.ts)
Types for table filtering and sorting.
Filter Definition
export type FilterType = 'text' | 'enum' | 'date' | 'number' | 'boolean';
export interface Filter {
label: string;
title: string; // Field name to filter by
type?: FilterType;
options?: string[]; // For enum filters
number?: boolean;
date?: boolean;
}
Active Filter
export interface FilterItem {
id: string;
fields: FilterFields;
}
export interface FilterFields {
selectedField: string;
filterValue: string;
filterValueFrom: string;
filterValueTo: string;
}
Table Configuration
export interface TableColumnConfig {
field: string;
headerName: string;
width?: number;
minWidth?: number;
maxWidth?: number;
flex?: number;
editable?: boolean;
sortable?: boolean;
filterable?: boolean;
type?: 'string' | 'number' | 'date' | 'dateTime' | 'boolean' | 'singleSelect';
valueOptions?: string[];
renderType?: 'link' | 'boolean' | 'date' | 'datetime' | 'image' | 'actions' | 'relation';
relationField?: string;
}
export interface TableConfig {
entityName: string;
columns: TableColumnConfig[];
filters: Filter[];
defaultSort?: { field: string; sort: 'asc' | 'desc' };
perPage?: number;
}
12. Specialized Types
Additional type files for specific features.
Charts Types (charts.ts)
export interface ChartDataPoint {
label: string;
value: number;
}
export interface DashboardStats {
totalProjects: number;
totalPages: number;
totalAssets: number;
recentActivity: ActivityItem[];
}
Components Types (components.ts)
export interface BaseComponentProps {
className?: string;
children?: React.ReactNode;
}
export interface DataGridProps<T> {
rows: T[];
columns: GridColDef[];
loading?: boolean;
}
Menu Types (menu.ts)
export interface MenuItem {
label: string;
href?: string;
icon?: string;
permission?: string;
children?: MenuItem[];
}
UI Types (ui.ts)
export interface ToastNotification {
id: string;
type: 'success' | 'error' | 'info' | 'warning';
message: string;
duration?: number;
}
export interface ModalProps {
isOpen: boolean;
onClose: () => void;
title?: string;
}
Type Relationships
┌─────────────────────────────────────────────────────────────┐
│ entities.ts │
│ BaseEntity → User, Project, Asset, TourPage, etc. │
└─────────────────────────────────────────────────────────────┘
│
├──────────────────────────────┐
▼ ▼
┌─────────────────────────┐ ┌─────────────────────────────┐
│ constructor.ts │ │ runtime.ts │
│ │ │ │
│ CanvasElement │ │ RuntimePage extends │
│ (extends styles/effects)│ │ PreloadPage │
└─────────────────────────┘ └─────────────────────────────┘
│ │
▼ ▼
┌─────────────────────────┐ ┌─────────────────────────────┐
│ presentation.ts │ │ preload.ts │
│ │ │ │
│ NavigableElement │◄───│ PreloadPage │
│ NavigationTarget │ │ PreloadPageLink │
│ TransitionPhase │ │ PreloadElement │
└─────────────────────────┘ └─────────────────────────────┘
│
▼
┌─────────────────────────────┐
│ offline.ts │
│ │
│ OfflineAsset │
│ DownloadQueueItem │
│ PreloadJob │
└─────────────────────────────┘
Import Patterns
Central Import (Recommended)
// Import from central index (10 modules re-exported)
// entities, api, redux, forms, filters, permissions,
// offline, preload, runtime, constructor
import type {
User,
Project,
Asset,
CanvasElement,
Permission,
PaginatedResponse,
} from '@/types';
Direct Import (For Specific Modules)
// Import from specific file
import type { CanvasElement, CanvasElementType } from '@/types/constructor';
import type { RuntimePage, RuntimeProject } from '@/types/runtime';
import type { PreloadJob, OfflineAsset } from '@/types/offline';
// Note: presentation.ts is NOT exported from index.ts, must import directly
import type { NavigableElement, TransitionPhase } from '@/types/presentation';
Usage Examples
Entity Types in API Calls
import type { User, PaginatedResponse } from '@/types';
const response = await axios.get<PaginatedResponse<User>>('/api/users');
const users: User[] = response.data.rows;
Canvas Elements in Constructor
import type { CanvasElement, CanvasElementType } from '@/types/constructor';
import { isCanvasElementType } from '@/types/constructor';
const handleAddElement = (type: string) => {
if (isCanvasElementType(type)) {
const element: CanvasElement = createDefaultElement(type);
setElements([...elements, element]);
}
};
Permissions in Components
import { Permission } from '@/types/permissions';
const canEdit = userPermissions.includes(Permission.UPDATE_PROJECTS);
Redux State Types
import type { EntitySliceState, NotificationState } from '@/types/redux';
interface UsersSliceState extends EntitySliceState<User> {
// Additional state if needed
}
Offline Storage Types
import type { OfflineAsset, PreloadJobStatus } from '@/types/offline';
const asset: OfflineAsset = {
id: 'asset-1',
projectId: 'project-1',
url: 'https://...',
filename: 'image.jpg',
variantType: 'original',
assetType: 'image',
mimeType: 'image/jpeg',
sizeBytes: 1024000,
blob: imageBlob,
downloadedAt: Date.now(),
};
Best Practices
1. Use Type Guards
// Use type guards for runtime type checking
if (isCanvasElementType(element.type)) {
// TypeScript knows type is CanvasElementType
}
2. Prefer Interfaces for Objects
// Good - interfaces are extendable
export interface User extends BaseEntity { ... }
// Use types for unions/primitives
export type CanvasElementType = 'navigation_next' | 'navigation_prev' | ...
3. Use Generic Types
// Generic response types
export interface PaginatedResponse<T> {
rows: T[];
count: number;
}
// Usage
const response: PaginatedResponse<Asset>;
4. Document Deprecations
export interface CanvasElement {
/** @deprecated Use targetPageSlug instead - IDs change when copied */
targetPageId?: string;
targetPageSlug?: string;
}
5. Export via Index
// types/index.ts
export * from './entities';
export * from './api';
// ... all modules
// Consumer
import type { User, Asset, Permission } from '@/types';
Related Documentation
- entities.ts Definitions - Used in Redux slices
- constructor.ts Usage - Constructor page documentation
- lib-module.md - Element styles/effects types from lib
- hooks-module.md - Hooks using these types
- stores-module.md - Redux state types