{"version":3,"file":"main.js","mappings":"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","sources":["webpack://roadmap/./src/layout.ts","webpack://roadmap/./src/core/Signal.ts","webpack://roadmap/./src/utils/arrayUtils.ts","webpack://roadmap/./src/utils/dateUtils.ts","webpack://roadmap/./src/state/index.ts","webpack://roadmap/./src/state/context.ts","webpack://roadmap/./src/components/ColumnGrid/ColumnGrid.module.css?95ac","webpack://roadmap/./src/components/ColumnGrid/index.tsx","webpack://roadmap/./src/core/Api.ts","webpack://roadmap/./src/components/Header/AuthButton.tsx","webpack://roadmap/./src/constants.ts","webpack://roadmap/./src/components/Header/Checkbox.tsx","webpack://roadmap/./src/components/Header/Checkbox.module.css?c3ae","webpack://roadmap/./src/components/Header/DatePanel.tsx","webpack://roadmap/./src/utils/stringUtils.ts","webpack://roadmap/./src/components/Header/HeaderColumn.tsx","webpack://roadmap/./src/components/Header/SearchPanel.module.css?cb39","webpack://roadmap/./src/state/search.ts","webpack://roadmap/./src/utils/taskUtils.ts","webpack://roadmap/./src/components/Header/SearchInput.tsx","webpack://roadmap/./src/components/Header/SearchPanel.tsx","webpack://roadmap/./src/components/Header/Switch.tsx","webpack://roadmap/./src/components/Header/Switch.module.css?2aa5","webpack://roadmap/./src/state/actions.ts","webpack://roadmap/./src/components/Header/index.tsx","webpack://roadmap/./src/components/Scroll/index.tsx","webpack://roadmap/./src/components/RowsSidebar/RowGroup.module.css?0f1e","webpack://roadmap/./src/components/RowsSidebar/SolutionsSidebarRows.tsx","webpack://roadmap/./src/components/RowsSidebar/OrganizationsSidebarRows.tsx","webpack://roadmap/./src/components/RowsSidebar/index.tsx","webpack://roadmap/./src/components/Rows/SolutionRowCell.module.css?cc0b","webpack://roadmap/./src/components/TaskList/Tooltip.tsx","webpack://roadmap/./src/components/TaskList/TaskListItem.tsx","webpack://roadmap/./src/components/TaskList/TaskListItem.module.css?7b9e","webpack://roadmap/./src/components/TaskList/index.tsx","webpack://roadmap/./src/components/Rows/SolutionRowCell.tsx","webpack://roadmap/./src/components/Rows/SolutionRows.tsx","webpack://roadmap/./src/components/Rows/OrganizationRowCell.tsx","webpack://roadmap/./src/components/Rows/OrganizationRowCell.module.css?727e","webpack://roadmap/./src/components/Rows/OrganizationRows.tsx","webpack://roadmap/./src/components/Rows/index.tsx","webpack://roadmap/./src/components/TasksPanel/Group.tsx","webpack://roadmap/./src/components/TasksPanel/Group.module.css?3dda","webpack://roadmap/./src/components/TasksPanel/OrganizationsTasks.tsx","webpack://roadmap/./src/components/TasksPanel/SolutionsTasks.tsx","webpack://roadmap/./src/components/TasksPanel/Count.tsx","webpack://roadmap/./src/components/Checkbox/index.tsx","webpack://roadmap/./src/components/Checkbox/Checkbox.module.css?b008","webpack://roadmap/./src/components/TasksPanel/index.tsx","webpack://roadmap/./src/components/TasksPanel/TasksPanel.module.css?0902","webpack://roadmap/./src/components/Spinner/index.tsx","webpack://roadmap/./src/components/Spinner/Spinner.module.css?a0b3","webpack://roadmap/./src/components/SkeletonApp/index.tsx","webpack://roadmap/./src/App.tsx","webpack://roadmap/./src/AuthCallback/index.tsx","webpack://roadmap/./src/ErrorPage.tsx","webpack://roadmap/./src/index.tsx"],"sourcesContent":["// Solution lauout\r\nexport const HEADER_HEIGHT = 150 as const;\r\nexport const SIDEBAR_WIDTH = 320 as const;\r\n\r\n// Table layout\r\nexport const COLLAPSED_COLUMN_WIDTH = 100 as const;\r\nexport const EXPANDED_COLUMN_WIDTH = 330 as const;\r\nexport const COLLAPSED_ROW_HEIGHT = 138 as const;\r\nexport const MIN_EXPANDED_ROW_HEIGHT = 180 as const;\r\n\r\nexport const TASK_HEIGHT = 30 as const;\r\nexport const TASK_CELL_PADDING = 72 as const;\r\nexport const COLUMNS_START_PADDING = 4 as const;\r\n\r\n// Solution view layout\r\nexport const APPLICATION_ROW_TASK_HEIGHT = 60 as const;\r\nexport const APPLICATION_TASK_TAB_PAD_HEIGHT = 40 as const;\r\n\r\n// Organization view layout\r\nexport const ORGANIZATION_MIN_EXPANDED_GROUP_HEIGHT = 350 as const;\r\n\r\nexport const INNER_Y_PADDING = 16 as const;\r\nexport const ORGANIZATION_APPPLICATION_GUTTER = 24 as const;\r\n\r\n// Unnasigned view layout\r\nexport const UNASSIGNED_Y_PADDING = 32 as const;\r\nexport const UNASSIGNED_COLUMNS = 4 as const;\r\nexport const UNASSIGNED_GAP = 16 as const;\r\n","export type SignalSubscriber = (data: T) => void;\r\nexport type SignalDispatch = (data: T) => void;\r\nexport type SignalUnsubscribe = () => void;\r\n\r\nconst createEventSignal = (): [\r\n (subscriber: SignalSubscriber) => SignalUnsubscribe,\r\n SignalDispatch\r\n] => {\r\n const subscribers: SignalSubscriber[] = [];\r\n\r\n const subscribe = (subscriber: SignalSubscriber): SignalUnsubscribe => {\r\n let isSubscribed = true;\r\n subscribers.push(subscriber);\r\n\r\n const unsubscribe = () => {\r\n if (isSubscribed) {\r\n isSubscribed = false;\r\n const index = subscribers.indexOf(subscriber);\r\n subscribers.splice(index, 1);\r\n }\r\n }\r\n\r\n return unsubscribe;\r\n };\r\n\r\n const dispatch = (data: Data) => {\r\n subscribers.forEach((subscriber) => subscriber(data));\r\n };\r\n\r\n return [\r\n subscribe,\r\n dispatch\r\n ];\r\n};\r\n\r\nexport default createEventSignal;\r\n","export const groupBy = (\r\n array: T[],\r\n key: (item: T) => string,\r\n): Record => {\r\n const map: Record = {};\r\n\r\n for (const item of array) {\r\n const groupKey = key(item);\r\n if (!map[groupKey]) {\r\n map[groupKey] = [];\r\n }\r\n map[groupKey].push(item);\r\n }\r\n\r\n return map;\r\n};\r\n","const shortMonthNames = [\r\n 'Jan',\r\n 'Feb',\r\n 'Mar',\r\n 'Apr',\r\n 'Maj',\r\n 'Jun',\r\n 'Jul',\r\n 'Aug',\r\n 'Sep',\r\n 'Okt',\r\n 'Nov',\r\n 'Dec',\r\n];\r\n\r\nconst fullMonthNames = [\r\n 'Januar',\r\n 'Februar',\r\n 'Marts',\r\n 'April',\r\n 'Maj',\r\n 'Juni',\r\n 'Juli',\r\n 'August',\r\n 'September',\r\n 'Oktober',\r\n 'November',\r\n 'December',\r\n];\r\n\r\nexport const getStartOfYear = () => {\r\n const date = new Date();\r\n\r\n date.setMonth(0);\r\n date.setDate(1);\r\n date.setHours(0, 0, 0, 0);\r\n\r\n return date;\r\n};\r\n\r\nexport const getEndOfYear = () => {\r\n const date = new Date();\r\n\r\n date.setMonth(11);\r\n date.setDate(31);\r\n date.setHours(23, 59, 59, 999);\r\n\r\n return date;\r\n};\r\n\r\nexport const getMonthName = (date: Date) => fullMonthNames[date.getMonth()];\r\n\r\nexport const getShortMonthName = (date: Date) => shortMonthNames[date.getMonth()];\r\n\r\nexport const formatDateInputValue = (date: Date) => {\r\n const year = date.getFullYear();\r\n let month: number | string = date.getMonth() + 1;\r\n let day: number | string = date.getDate();\r\n\r\n if (month < 10) {\r\n month = `0${month}`;\r\n }\r\n\r\n if (day < 10) {\r\n day = `0${day}`;\r\n }\r\n\r\n return `${year}-${month}-${day}`;\r\n}\r\n","import { RoadmapResult } from '../core/Api';\r\nimport createEventSignal from '../core/Signal';\r\nimport { APPLICATION_TASK_TAB_PAD_HEIGHT, COLLAPSED_ROW_HEIGHT, INNER_Y_PADDING, MIN_EXPANDED_ROW_HEIGHT, ORGANIZATION_APPPLICATION_GUTTER, ORGANIZATION_MIN_EXPANDED_GROUP_HEIGHT, TASK_CELL_PADDING, TASK_HEIGHT, UNASSIGNED_COLUMNS, UNASSIGNED_GAP, UNASSIGNED_Y_PADDING } from '../layout';\r\nimport { Solution, SolutionVersion, DateRange, TaskCategory, Organization, Release, Task, Filter } from '../types';\r\nimport { groupBy as groupArrayBy } from '../utils/arrayUtils';\r\nimport { getEndOfYear, getStartOfYear } from '../utils/dateUtils';\r\n\r\n// Signals\r\nexport const [onFiltersChange, dispatchFiltersChange] = createEventSignal();\r\nexport const [onExpandedColumnsChange, dispatchOnExpandedColumnsChange] = createEventSignal();\r\nexport const [onExpandedRowsChange, dispatchOnExpandedRowsChange] = createEventSignal();\r\nexport const [onDateRangeChange, dispatchOnDateRangeChange] = createEventSignal();\r\nexport const [onGroupByChange, dispatchOnGroupByChange] = createEventSignal<'solution' | 'organization'>();\r\nexport const [onRowHeightsChange, dispatchOnRowHeightsChange] = createEventSignal>();\r\nexport const [onFilteredTasksChange, dispatchOnFilteredTasksChange] = createEventSignal();\r\nexport const [onTasksChange, dispatchOnTasksChange] = createEventSignal();\r\nexport const [onSelectTaskChange, dispatchOnSelectTaskChange] = createEventSignal();\r\nexport const [onIsAuthenticatedChange, dispatchIsAuthenticatedChange] = createEventSignal();\r\n\r\nlet dateRange: DateRange = [\r\n getStartOfYear(),\r\n getEndOfYear(),\r\n];\r\nlet filters: Filter[] = ['error', 'support', 'request', 'maintenance', 'documentation'];\r\nlet groupBy: 'solution' | 'organization' = 'solution';\r\nlet expandedColumns: number[] = [];\r\nlet expandedRows: number[] = [];\r\n\r\nlet selectedTask: Task | null = null;\r\nlet tasks: Task[] = [];\r\nlet releases: Release[] = [];\r\nlet organizations: Organization[] = [];\r\nlet solutions: Solution[] = [];\r\nlet solutionVersions: SolutionVersion[] = [];\r\nlet rowHeights: Record = {};\r\nlet isAuthenticated: boolean = false;\r\n\r\nlet solutionVersionsById: Record = {};\r\n\r\nexport const getFilteredTasks = () => {\r\n return tasks\r\n .filter((task) => {\r\n if (filters.includes('exclude-on-hold') && task.statusCode === 'onHold') {\r\n return false;\r\n }\r\n\r\n return filters.includes(task.category);\r\n });\r\n};\r\nexport const getTasks = () => tasks;\r\nexport const getReleases = () => releases;\r\nexport const getOrganizations = () => organizations;\r\nexport const getSolutions = () => solutions;\r\nexport const getSolutionVersions = () => solutionVersions;\r\nexport const getSolutionVersionsById = () => solutionVersionsById;\r\nexport const getExpandedColumns = () => expandedColumns;\r\nexport const getExpandedRows = () => expandedRows;\r\nexport const getFilters = () => filters;\r\nexport const getDateRange = () => dateRange;\r\nexport const getGroupBy = () => groupBy;\r\nexport const getRowHeights = () => rowHeights;\r\nexport const getIsAuthenticated = () => isAuthenticated;\r\nexport const getSelectedTask = () => selectedTask;\r\n\r\nexport const calculateRowHeights = () => {\r\n const heights: Record = {};\r\n\r\n if (groupBy === 'organization') {\r\n const tasks = groupArrayBy(getTasks(), (item) => `${item.organizationId}-${item.releaseId || 'UNASSIGNED'}`);\r\n\r\n for (const organization of organizations) {\r\n const isExpanded = expandedRows.includes(organization.id);\r\n let maxHeight = COLLAPSED_ROW_HEIGHT as number;\r\n\r\n if (isExpanded) {\r\n maxHeight = ORGANIZATION_MIN_EXPANDED_GROUP_HEIGHT;\r\n\r\n // Unassigned tasks\r\n const unassignedTasks = tasks[`${organization.id}-UNASSIGNED`];\r\n\r\n if (unassignedTasks) {\r\n const numberOfRows = Math.ceil(unassignedTasks.length / UNASSIGNED_COLUMNS);\r\n const unassignedTasksHeight = (\r\n (numberOfRows - 1) * UNASSIGNED_GAP +\r\n (numberOfRows * TASK_HEIGHT) +\r\n UNASSIGNED_Y_PADDING * 2\r\n );\r\n if (unassignedTasksHeight > maxHeight) {\r\n maxHeight = unassignedTasksHeight;\r\n }\r\n }\r\n\r\n for (const release of releases) {\r\n const filteredTasks = tasks[`${organization.id}-${release.id}`];\r\n\r\n if (filteredTasks) {\r\n const numberOfSolutions = Object.keys(\r\n groupArrayBy(\r\n filteredTasks,\r\n (item) => `${item.solutionId}`\r\n )\r\n ).length;\r\n\r\n const height = (\r\n (INNER_Y_PADDING * 2) +\r\n (numberOfSolutions * TASK_HEIGHT) +\r\n ((numberOfSolutions - 1) * ORGANIZATION_APPPLICATION_GUTTER) +\r\n (filteredTasks.length * TASK_HEIGHT) +\r\n APPLICATION_TASK_TAB_PAD_HEIGHT\r\n );\r\n\r\n if (height > maxHeight) {\r\n maxHeight = height;\r\n }\r\n }\r\n }\r\n }\r\n\r\n heights[organization.id] = maxHeight;\r\n }\r\n\r\n return heights;\r\n }\r\n\r\n for (const solution of solutions) {\r\n const isExpanded = expandedRows.includes(solution.id);\r\n\r\n if (isExpanded) {\r\n let maxHeight = MIN_EXPANDED_ROW_HEIGHT as number;\r\n\r\n for (const release of releases) {\r\n const key = `${solution.id}-${release.id}`;\r\n const tasks = groupArrayBy(getTasks(), (item) => `${item.solutionId}-${item.releaseId}`)[key];\r\n const taskCount = tasks?.length || 0;\r\n const height = TASK_CELL_PADDING + TASK_HEIGHT * taskCount;\r\n\r\n if (height > maxHeight) {\r\n maxHeight = height;\r\n }\r\n }\r\n\r\n heights[solution.id] = maxHeight + 32;\r\n } else {\r\n heights[solution.id] = COLLAPSED_ROW_HEIGHT;\r\n }\r\n }\r\n\r\n return heights;\r\n};\r\n\r\n// Actions\r\nexport const reset = (data: RoadmapResult) => {\r\n tasks = data.tasks;\r\n releases = data.releases;\r\n organizations = data.organizations;\r\n solutions = data.solutions;\r\n solutionVersions = data.solutionVersions;\r\n rowHeights = calculateRowHeights();\r\n\r\n releases.sort((a, b) => a.releaseDate.getTime() - b.releaseDate.getTime());\r\n solutions.sort((a, b) => a.name.localeCompare(b.name));\r\n organizations.sort((a, b) => a.name.localeCompare(b.name));\r\n\r\n solutionVersionsById = {};\r\n\r\n for (const solutionVersion of solutionVersions) {\r\n solutionVersionsById[solutionVersion.id] = solutionVersion;\r\n }\r\n\r\n if (expandedColumns.length === 0) {\r\n const currentYear = new Date().getFullYear();\r\n const currentMonth = new Date().getMonth();\r\n\r\n const currrentRelease = releases\r\n .find((release) => release.releaseDate.getFullYear() === currentYear && release.releaseDate.getMonth() === currentMonth);\r\n\r\n if (currrentRelease) {\r\n toggleColumn(currrentRelease.id);\r\n }\r\n }\r\n\r\n const nextIsAuthenticated = data.user ? true : false;\r\n if (isAuthenticated !== nextIsAuthenticated) {\r\n isAuthenticated = nextIsAuthenticated;\r\n dispatchIsAuthenticatedChange(isAuthenticated);\r\n };\r\n\r\n dispatchOnTasksChange(tasks);\r\n dispatchOnFilteredTasksChange(getFilteredTasks());\r\n};\r\n\r\nexport const setDateRange = (newDateRange: DateRange) => {\r\n dateRange = newDateRange;\r\n dispatchOnDateRangeChange(newDateRange);\r\n};\r\n\r\nexport const setFilters = (newFilters: TaskCategory[]) => {\r\n filters = newFilters;\r\n dispatchFiltersChange(newFilters);\r\n dispatchOnFilteredTasksChange(getFilteredTasks());\r\n};\r\n\r\nexport const setGroupBy = (newGroupBy: 'solution' | 'organization') => {\r\n groupBy = newGroupBy;\r\n rowHeights = calculateRowHeights();\r\n\r\n dispatchOnGroupByChange(newGroupBy);\r\n dispatchOnRowHeightsChange(rowHeights);\r\n};\r\n\r\nexport const setIsAuthenticated = (newIsAuthenticated: boolean) => {\r\n isAuthenticated = newIsAuthenticated;\r\n dispatchIsAuthenticatedChange(newIsAuthenticated);\r\n};\r\n\r\nexport const toggleColumn = (column: number, exclusive = false) => {\r\n if (exclusive) {\r\n expandedColumns = [];\r\n }\r\n\r\n const isExpanded = expandedColumns.includes(column);\r\n\r\n if (isExpanded) {\r\n expandedColumns = expandedColumns.filter((c) => c !== column);\r\n } else {\r\n expandedColumns = [...expandedColumns, column];\r\n }\r\n\r\n dispatchOnExpandedColumnsChange(expandedColumns);\r\n};\r\n\r\nexport const toggleRow = (row: number, exclusive = false) => {\r\n if (exclusive) {\r\n expandedRows = [];\r\n }\r\n\r\n const isExpanded = expandedRows.includes(row);\r\n\r\n if (isExpanded) {\r\n expandedRows = expandedRows.filter((r) => r !== row);\r\n } else {\r\n expandedRows = [...expandedRows, row];\r\n }\r\n\r\n rowHeights = calculateRowHeights();\r\n dispatchOnExpandedRowsChange(expandedRows);\r\n dispatchOnRowHeightsChange(rowHeights);\r\n};\r\n\r\nexport const selectTask = (task: Task | null | undefined) => {\r\n selectedTask = task || null;\r\n dispatchOnSelectTaskChange(task);\r\n};\r\n\r\nexport const scrollTaskIntoView = (taskId: number) => {\r\n const foundTask = tasks.find((task) => task.id === taskId);\r\n if (!foundTask) {\r\n selectTask(null);\r\n }\r\n\r\n if (groupBy === 'organization') {\r\n const organization = organizations.find((org) => org.id === foundTask.organizationId);\r\n if (!organization) {\r\n return selectTask(foundTask);\r\n }\r\n\r\n const isExpanded = expandedRows.includes(organization.id);\r\n if (!isExpanded) {\r\n toggleRow(organization.id, true);\r\n }\r\n }\r\n\r\n if (groupBy === 'solution') {\r\n const solution = solutions.find((app) => app.id === foundTask.solutionId);\r\n if (!solution) {\r\n return selectTask(foundTask);\r\n }\r\n\r\n const isExpanded = expandedRows.includes(solution.id);\r\n if (!isExpanded) {\r\n toggleRow(solution.id, true);\r\n }\r\n }\r\n\r\n const release = releases.find((release) => release.id === foundTask.releaseId);\r\n if (!release) {\r\n return selectTask(foundTask);\r\n }\r\n\r\n toggleColumn(release.id, true);\r\n return selectTask(foundTask);\r\n};\r\n","import { useEffect, useMemo, useRef, useState } from 'react';\r\nimport {\r\n getSolutions,\r\n getDateRange,\r\n getExpandedColumns,\r\n getExpandedRows,\r\n getFilteredTasks,\r\n getFilters,\r\n getGroupBy,\r\n getOrganizations,\r\n getReleases,\r\n getRowHeights,\r\n onDateRangeChange,\r\n onExpandedColumnsChange,\r\n onExpandedRowsChange,\r\n onFiltersChange,\r\n onGroupByChange,\r\n onRowHeightsChange,\r\n setDateRange,\r\n setFilters,\r\n setGroupBy,\r\n toggleColumn,\r\n toggleRow,\r\n getIsAuthenticated,\r\n onIsAuthenticatedChange,\r\n setIsAuthenticated,\r\n onTasksChange,\r\n onFilteredTasksChange,\r\n onSelectTaskChange,\r\n getSelectedTask,\r\n getSolutionVersions,\r\n getSolutionVersionsById,\r\n} from '.'\r\nimport {\r\n Solution,\r\n DateRange,\r\n TaskCategory,\r\n Organization,\r\n Release,\r\n Task,\r\n SolutionVersion,\r\n Filter,\r\n} from '../types';\r\nimport { groupBy } from '../utils/arrayUtils';\r\n\r\nexport const useIsTaskSelected = (task: Task): boolean => {\r\n const [isSelected, setIsSelected] = useState(() => {\r\n const selectedTask = getSelectedTask();\r\n return selectedTask && selectedTask.id === task.id;\r\n });\r\n const selectedRef = useRef(isSelected);\r\n\r\n useEffect(() => {\r\n return onSelectTaskChange((selectedTask) => {\r\n const nextIsSelected = selectedTask && selectedTask.id === task.id;\r\n if (nextIsSelected !== selectedRef.current) {\r\n setIsSelected(nextIsSelected);\r\n selectedRef.current = nextIsSelected;\r\n }\r\n });\r\n }, [task]);\r\n\r\n return isSelected;\r\n};\r\n\r\nexport const useFilteredTasks = (): Task[] => {\r\n const [tasks, setTasks] = useState(getFilteredTasks);\r\n\r\n useEffect(() => {\r\n return onFilteredTasksChange(() => setTasks(getFilteredTasks()));\r\n }, []);\r\n\r\n return tasks;\r\n};\r\n\r\nexport const useTasks = (): Task[] => {\r\n const [tasks, setTasks] = useState(getFilteredTasks);\r\n\r\n useEffect(() => {\r\n return onTasksChange(() => setTasks(getFilteredTasks()));\r\n }, []);\r\n\r\n return tasks;\r\n};\r\n\r\nexport const useReleases = (): Release[] => getReleases();\r\nexport const useOrganizations = (): Organization[] => getOrganizations();\r\nexport const useSolutions = (): Solution[] => getSolutions();\r\nexport const useSolutionVersionsById = (): Record => getSolutionVersionsById();\r\n\r\nexport const useTasksByRelease = (): Record => {\r\n const tasks = useFilteredTasks();\r\n\r\n return useMemo(\r\n () => groupBy(tasks, (task) => `${task.releaseId}`),\r\n [tasks],\r\n );\r\n};\r\n\r\n// Return tasks grouped by solution id\r\nexport const useTasksBySolution = (): Record => {\r\n const tasks = useFilteredTasks();\r\n\r\n return useMemo(\r\n () => groupBy(tasks, (task) => `${task.solutionId}`),\r\n [tasks],\r\n );\r\n};\r\n\r\n// Return tasks grouped by solution id and release id\r\nexport const useTasksBySolutionAndRelease = (): Record => {\r\n const tasks = useFilteredTasks();\r\n\r\n return useMemo(\r\n () => groupBy(tasks, (task) => `${task.solutionId}-${task.releaseId}`),\r\n [tasks],\r\n );\r\n};\r\n\r\nexport const useTasksByOrganizationAndRelease = (): Record => {\r\n const tasks = useFilteredTasks();\r\n\r\n return useMemo(\r\n () => groupBy(tasks, (task) => `${task.organizationId}-${task.releaseId}`),\r\n [tasks],\r\n );\r\n};\r\n\r\nexport const useUnassignedTasks = (): Task[] => {\r\n return useFilteredTasks().filter((task) => !task.releaseId);\r\n};\r\n\r\nexport const useUnassignedTasksByOrganization = (): Record => {\r\n const tasks = useFilteredTasks().filter((task) => !task.releaseId);\r\n\r\n return useMemo(\r\n () => groupBy(tasks, (task) => `${task.organizationId}`),\r\n [tasks],\r\n );\r\n};\r\n\r\nexport const useUnassignedTasksBySolution = (): Record => {\r\n const tasks = useFilteredTasks().filter((task) => !task.releaseId);\r\n\r\n return useMemo(\r\n () => groupBy(tasks, (task) => `${task.solutionId}`),\r\n [tasks],\r\n );\r\n};\r\n\r\nexport const useTasksByOrganization = (): Record => {\r\n const tasks = useFilteredTasks();\r\n\r\n return useMemo(\r\n () => groupBy(tasks, (task) => `${task.organizationId}`),\r\n [tasks],\r\n );\r\n}\r\n\r\nexport const useExpandedColumns = (): [\r\n number[],\r\n React.Dispatch>\r\n] => {\r\n const [_columns, _setColumns] = useState(getExpandedColumns());\r\n\r\n useEffect(\r\n () => onExpandedColumnsChange(_setColumns),\r\n [],\r\n );\r\n\r\n return [\r\n _columns,\r\n toggleColumn,\r\n ];\r\n};\r\n\r\nexport const useExpandedRows = (): [\r\n number[],\r\n React.Dispatch>\r\n] => {\r\n const [_rows, _setRows] = useState(getExpandedRows());\r\n\r\n useEffect(\r\n () => onExpandedRowsChange(_setRows),\r\n [],\r\n );\r\n\r\n return [\r\n _rows,\r\n toggleRow,\r\n ];\r\n};\r\n\r\nexport const useIsAuthenticated = (): boolean => {\r\n const [isAuthenticated, setIsAuthenticated] = useState(getIsAuthenticated);\r\n\r\n useEffect(\r\n () => onIsAuthenticatedChange(setIsAuthenticated),\r\n [],\r\n );\r\n\r\n return isAuthenticated;\r\n};\r\n\r\nexport const useSetIsAuthenticated = (): (isAuthenticated: boolean) => void => {\r\n return setIsAuthenticated;\r\n};\r\n\r\nexport const useFilters = (): [\r\n Filter[],\r\n React.Dispatch>\r\n] => {\r\n const [_filters, _setFilters] = useState(getFilters());\r\n\r\n useEffect(\r\n () => onFiltersChange(_setFilters),\r\n [],\r\n );\r\n\r\n return [\r\n _filters,\r\n setFilters,\r\n ];\r\n};\r\n\r\nexport const useDateRange = (): [\r\n DateRange,\r\n React.Dispatch>\r\n] => {\r\n const [_dateRange, _setDateRange] = useState(getDateRange());\r\n\r\n useEffect(\r\n () => onDateRangeChange(_setDateRange),\r\n [],\r\n );\r\n\r\n return [\r\n _dateRange,\r\n setDateRange,\r\n ];\r\n};\r\n\r\nexport const useGroupBy = (): [\r\n 'solution' | 'organization',\r\n React.Dispatch>\r\n] => {\r\n const [_groupBy, _setGroupBy] = useState<'solution' | 'organization'>(() => getGroupBy());\r\n\r\n useEffect(\r\n () => onGroupByChange(_setGroupBy),\r\n [],\r\n );\r\n\r\n return [\r\n _groupBy,\r\n setGroupBy,\r\n ];\r\n};\r\n\r\nexport const useRowHeights = (): Record => {\r\n const [_rowHeights, _setRowHeights] = useState>(getRowHeights());\r\n\r\n useEffect(\r\n () => onRowHeightsChange(_setRowHeights),\r\n [],\r\n );\r\n\r\n return _rowHeights;\r\n};\r\n","// extracted by mini-css-extract-plugin\nexport default {\"stripe\":\"mgDIoM7vJNA3NO4PRzgB\",\"expanded\":\"_xm4WqIhxwnq6N2eH4Om\"};","import classes from './ColumnGrid.module.css';\r\nimport * as React from 'react';\r\nimport { useExpandedColumns, useReleases } from '../../state/context';\r\nimport classNames from 'classnames';\r\nimport { COLLAPSED_COLUMN_WIDTH, COLUMNS_START_PADDING, EXPANDED_COLUMN_WIDTH } from '../../layout';\r\n\r\ntype ColumnGridProps = {\r\n excludeLeftPadding?: boolean;\r\n};\r\n\r\nconst ColumnGrid = ({ excludeLeftPadding }: ColumnGridProps) => {\r\n const releases = useReleases();\r\n const [expandedColumns] = useExpandedColumns();\r\n const stripes = React.useMemo(() => {\r\n let left = excludeLeftPadding ? 0 : COLUMNS_START_PADDING;\r\n const stripes: React.ReactElement[] = [];\r\n\r\n releases.forEach((release) => {\r\n const isExpanded = expandedColumns.includes(release.id);\r\n if (isExpanded) {\r\n stripes.push(\r\n \r\n );\r\n\r\n left += EXPANDED_COLUMN_WIDTH;\r\n } else {\r\n\r\n stripes.push(\r\n \r\n );\r\n\r\n left += COLLAPSED_COLUMN_WIDTH;\r\n }\r\n });\r\n\r\n return stripes;\r\n }, [releases, expandedColumns]);\r\n\r\n return (\r\n
\r\n {stripes}\r\n
\r\n );\r\n};\r\n\r\nexport default ColumnGrid;\r\n","import axios from 'axios';\r\nimport {\r\n Task,\r\n Organization,\r\n Release,\r\n SolutionVersion,\r\n Solution,\r\n User,\r\n} from '../types';\r\n\r\ntype RoadmapPayloadRelease = Omit & {\r\n releaseDate: string;\r\n};\r\n\r\ntype RoadmapPayload = {\r\n user: User | null;\r\n fromDate: string;\r\n toDate: string;\r\n tasks: Task[];\r\n organizations: Organization[];\r\n releases: RoadmapPayloadRelease[];\r\n solutionVersions: SolutionVersion[];\r\n solutions: Solution[];\r\n}\r\n\r\nexport type RoadmapResult = {\r\n user: User | null;\r\n tasks: Task[];\r\n organizations: Organization[];\r\n releases: Release[];\r\n solutionVersions: SolutionVersion[];\r\n solutions: Solution[];\r\n};\r\n\r\nconst Api = axios.create({\r\n baseURL: process.env.API_BASE_URL,\r\n headers: {\r\n 'X-Client': 'solution',\r\n 'Pragma': 'no-cache',\r\n 'Cache-Control': 'no-cache',\r\n },\r\n});\r\n\r\ntype FetchDataParams = {\r\n fromDate?: Date;\r\n toDate?: Date;\r\n};\r\n\r\nexport const fetchData = async (params: FetchDataParams = {}): Promise => {\r\n const { data } = await Api.get('/Search', {\r\n params: {\r\n fromDateTime: params.fromDate?.toISOString(),\r\n toDateTime: params.toDate?.toISOString(),\r\n },\r\n });\r\n\r\n return {\r\n ...data,\r\n releases: data.releases.map((release) => ({\r\n ...release,\r\n releaseDate: new Date(release.releaseDate),\r\n })),\r\n };\r\n};\r\n\r\nexport const login = async (token: string): Promise => {\r\n await Api.post('/authentication/login', { token });\r\n};\r\n\r\nexport const logout = async (): Promise => {\r\n await Api.post('/authentication/logout');\r\n};\r\n","import * as React from 'react';\r\nimport { logout } from '../../core/Api';\r\nimport { useIsAuthenticated, useSetIsAuthenticated } from '../../state/context';\r\n\r\nconst AuthButton = () => {\r\n const isAuthenticated = useIsAuthenticated();\r\n const setIsAuthenticated = useSetIsAuthenticated();\r\n\r\n const handleLogin = () => {\r\n const url = process.env.SSO_LOGIN_URL as string;\r\n window.location.replace(url);\r\n };\r\n\r\n const handleLogout = () => {\r\n logout()\r\n .finally(() => {\r\n setIsAuthenticated(false);\r\n })\r\n };\r\n\r\n return (\r\n \r\n {isAuthenticated ? 'Log ud' : 'Log ind'}\r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\nexport default AuthButton;\r\n","import { TaskCategory } from './types';\r\n\r\nexport const TASK_CATEGORY_BG_COLORS: Record = {\r\n error: 'bg-types-error',\r\n support: 'bg-types-support',\r\n request: 'bg-types-request',\r\n maintenance: 'bg-types-maintenance',\r\n documentation: 'bg-types-documentation',\r\n} as const;\r\n","import styles from './Checkbox.module.css';\r\nimport * as React from 'react';\r\nimport classNames from 'classnames';\r\nimport { TaskCategory } from '../../types';\r\nimport { TASK_CATEGORY_BG_COLORS } from '../../constants';\r\n\r\ntype HeaderCheckboxProps = {\r\n type: TaskCategory\r\n checked?: boolean;\r\n onChange: (checked: boolean) => void;\r\n label: string;\r\n className?: string;\r\n};\r\n\r\nconst HeaderCheckbox = ({\r\n type,\r\n checked,\r\n onChange,\r\n label,\r\n className,\r\n}: HeaderCheckboxProps) => {\r\n return (\r\n \r\n );\r\n};\r\n\r\nexport default HeaderCheckbox;\r\n","// extracted by mini-css-extract-plugin\nexport default {\"checkbox\":\"SuSlM8r2qfrk2jTI7Ay9\"};","import classNames from 'classnames';\r\nimport * as React from 'react';\r\nimport { FiChevronDown, FiChevronUp } from 'react-icons/fi';\r\nimport { DateRange } from '../../types';\r\nimport { formatDateInputValue, getShortMonthName } from '../../utils/dateUtils';\r\n\r\ntype DatePanelProps = {\r\n dateRange: DateRange;\r\n onChange: (dateRange: DateRange) => void;\r\n onToggleChange: (isExpanded: boolean) => void;\r\n};\r\n\r\nconst DatePanel = ({\r\n dateRange,\r\n onChange,\r\n onToggleChange,\r\n}: DatePanelProps) => {\r\n const [isExpanded, setIsExpanded] = React.useState(false);\r\n const [startDate, setStartDate] = React.useState(dateRange[0]);\r\n const [endDate, setEndDate] = React.useState(dateRange[1]);\r\n const startDateInputRef = React.useRef(null);\r\n const endDateInputRef = React.useRef(null);\r\n const ref = React.useRef(null);\r\n const isValid = (startDate !== null && isNaN(startDate.getTime()) === false) && (endDate !== null && isNaN(endDate.getTime()) === false);\r\n\r\n React.useEffect(() => {\r\n onToggleChange(isExpanded);\r\n }, [isExpanded]);\r\n\r\n React.useEffect(() => {\r\n const handleClickOutside = (event: MouseEvent) => {\r\n if (ref.current && !ref.current.contains(event.target as Node)) {\r\n setIsExpanded(false);\r\n }\r\n };\r\n\r\n document.addEventListener('click', handleClickOutside);\r\n\r\n return () => {\r\n document.removeEventListener('click', handleClickOutside);\r\n };\r\n }, []);\r\n\r\n React.useEffect(() => {\r\n if (startDateInputRef.current) {\r\n startDateInputRef.current.valueAsDate = startDate;\r\n }\r\n\r\n if (endDateInputRef.current) {\r\n endDateInputRef.current.valueAsDate = endDate;\r\n }\r\n }, [startDate, endDate]);\r\n\r\n React.useEffect(() => {\r\n const handleKeyDown = (event: KeyboardEvent) => {\r\n if (event.key === 'Escape') {\r\n event.preventDefault();\r\n return setIsExpanded(false);\r\n }\r\n\r\n if (event.key === 'Enter') {\r\n\r\n if (isValid) {\r\n event.preventDefault();\r\n onChange([startDate, endDate]);\r\n }\r\n\r\n return setIsExpanded(false);\r\n }\r\n }\r\n\r\n document.addEventListener('keydown', handleKeyDown);\r\n\r\n return () => {\r\n document.removeEventListener('keydown', handleKeyDown);\r\n };\r\n }, [isValid, startDate, endDate, onChange]);\r\n\r\n return (\r\n
\r\n setIsExpanded(!isExpanded)}\r\n className=\"uppercase font-bold h-5 flex items-center leading-4\"\r\n >\r\n {`${getShortMonthName(dateRange[0])}. ${dateRange[0].getFullYear()} - ${getShortMonthName(dateRange[1])}. ${dateRange[1].getFullYear()}`}\r\n {isExpanded\r\n ? \r\n : }\r\n \r\n {isExpanded && (\r\n
\r\n
\r\n \r\n {\r\n const { valueAsDate } = event.target as HTMLInputElement;\r\n\r\n if (valueAsDate !== null && isNaN(valueAsDate.getTime()) === false) {\r\n setStartDate(valueAsDate);\r\n }\r\n }}\r\n onBlur={(event) => {\r\n const { valueAsDate } = event.target as HTMLInputElement;\r\n setStartDate(valueAsDate);\r\n }}\r\n />\r\n
\r\n
\r\n \r\n {\r\n const { valueAsDate } = event.target as HTMLInputElement;\r\n\r\n if (valueAsDate !== null && isNaN(valueAsDate.getTime()) === false) {\r\n setEndDate(valueAsDate);\r\n }\r\n }}\r\n onBlur={(event) => {\r\n const { valueAsDate } = event.target as HTMLInputElement;\r\n setEndDate(valueAsDate);\r\n }}\r\n />\r\n
\r\n {\r\n if (isValid) {\r\n onChange([startDate, endDate]);\r\n }\r\n setIsExpanded(false);\r\n }}\r\n className={classNames(\r\n 'w-full py-1.5 bg-blue-500 font-semibold text-white rounded-sm mt-4 active:bg-blue-600',\r\n isValid === false && 'opacity-50 cursor-default pointer-events-none',\r\n )}\r\n >\r\n Vælg periode\r\n \r\n
\r\n )}\r\n
\r\n );\r\n};\r\n\r\nexport default DatePanel;\r\n","export const pluralize = (count: number, singular: string, plural: string) => {\r\n return count === 1 ? singular : plural;\r\n};\r\n","import classNames from 'classnames';\r\nimport * as React from 'react';\r\nimport { FiChevronRight, FiX } from 'react-icons/fi';\r\nimport { COLLAPSED_COLUMN_WIDTH, EXPANDED_COLUMN_WIDTH } from '../../layout';\r\nimport { Release, Task } from '../../types';\r\nimport { getMonthName } from '../../utils/dateUtils';\r\nimport { pluralize } from '../../utils/stringUtils';\r\n\r\ntype HeaderColumnProps = {\r\n release: Release;\r\n numberOfTasks: number;\r\n numberOfSolutions: number;\r\n isExpanded: boolean;\r\n toggle: () => void;\r\n};\r\n\r\nconst HeaderColumn = ({\r\n release,\r\n numberOfTasks,\r\n numberOfSolutions,\r\n isExpanded,\r\n toggle,\r\n}: HeaderColumnProps) => {\r\n const monthName = React.useMemo(() => getMonthName(release.releaseDate), [release.releaseDate]);\r\n const fullYear = React.useMemo(() => release.releaseDate.getFullYear(), [release.releaseDate]);\r\n const style: React.CSSProperties = React.useMemo(() => {\r\n return {\r\n width: `${isExpanded ? EXPANDED_COLUMN_WIDTH : COLLAPSED_COLUMN_WIDTH}px`\r\n }\r\n }, [isExpanded]);\r\n\r\n return (\r\n
\r\n \r\n \r\n \r\n \r\n
{numberOfTasks}
\r\n
\r\n {`${pluralize(numberOfTasks, 'sag', 'sager')} i sprintet`}\r\n
\r\n
\r\n \r\n
{numberOfSolutions}
\r\n
\r\n {pluralize(numberOfSolutions, 'applikation', 'applikationer')}\r\n
\r\n \r\n
{monthName}
\r\n
Sprint
\r\n
{fullYear}
\r\n \r\n );\r\n};\r\n\r\nexport default HeaderColumn;\r\n","// extracted by mini-css-extract-plugin\nexport default {\"panel\":\"dOI4E2PMdQApkBJ0jWga\",\"open\":\"ZE_RvkOluUxk7t0h5ckE\"};","import Fuse from 'fuse.js';\r\nimport { Task } from '../types';\r\nimport { getFilteredTasks, onFilteredTasksChange } from './';\r\n\r\nconst fuse = new Fuse(getFilteredTasks(), {\r\n keys: ['id', 'title'],\r\n includeScore: true,\r\n threshold: 0.5,\r\n});\r\n\r\nonFilteredTasksChange((tasks) => {\r\n fuse.setCollection(tasks);\r\n});\r\n\r\nexport function search(query: string) {\r\n return fuse.search(query);\r\n}\r\n","import { TASK_CATEGORY_BG_COLORS } from '../constants';\r\nimport { TaskCategory } from '../types';\r\n\r\nexport const zeroPadId = (id: number) => {\r\n const string = id.toString();\r\n return string.length === 4 ? string : `00000${string}`.slice(-4);\r\n};\r\n\r\nexport const getTaskCategoryColor = (category: TaskCategory): string => {\r\n return TASK_CATEGORY_BG_COLORS[category] || '';\r\n};\r\n","import classNames from 'classnames';\r\nimport * as React from 'react';\r\nimport { FiSearch } from 'react-icons/fi';\r\nimport { search } from '../../state/search';\r\nimport { Task } from '../../types';\r\nimport { getTaskCategoryColor, zeroPadId } from '../../utils/taskUtils';\r\n\r\ntype SearchInputProps = {\r\n className?: string;\r\n onSelect: (task: Task) => void;\r\n onClear: () => void;\r\n};\r\n\r\nconst SearchInput = (props: SearchInputProps) => {\r\n const [isFocused, setIsFocused] = React.useState(false);\r\n const [searchTerm, setSearchTerm] = React.useState('');\r\n const [searchResults, setSearchResults] = React.useState([]);\r\n const [activeResultIndex, setActiveResultIndex] = React.useState(0);\r\n const inputRef = React.useRef(null);\r\n const itemsRef = React.useRef([]);\r\n\r\n React.useEffect(() => {\r\n const results = search(searchTerm).map((result) => result.item);\r\n setActiveResultIndex(0);\r\n setSearchResults(results);\r\n }, [searchTerm]);\r\n\r\n const handleSelect = () => {\r\n const task = searchResults[activeResultIndex];\r\n if (!task) {\r\n return\r\n }\r\n\r\n props.onSelect(task);\r\n setSearchTerm(`${task.id}`);\r\n inputRef.current?.blur();\r\n };\r\n\r\n React.useEffect(() => {\r\n itemsRef.current = itemsRef.current.slice(0, searchResults.length);\r\n }, [searchResults]);\r\n\r\n React.useEffect(() => {\r\n if (itemsRef.current[activeResultIndex]) {\r\n itemsRef.current[activeResultIndex].scrollIntoView({\r\n block: 'nearest',\r\n });\r\n }\r\n }, [activeResultIndex]);\r\n\r\n const handleKeyDown = (event: React.KeyboardEvent) => {\r\n if (event.key === 'ArrowDown') {\r\n event.preventDefault();\r\n setActiveResultIndex(Math.min(activeResultIndex + 1, searchResults.length - 1));\r\n } else if (event.key === 'ArrowUp') {\r\n event.preventDefault();\r\n setActiveResultIndex(Math.max(activeResultIndex - 1, 0));\r\n } else if (event.key === 'Enter') {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n handleSelect();\r\n } else if (event.key === 'Escape') {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n props.onClear();\r\n setIsFocused(false);\r\n setSearchResults([]);\r\n setSearchTerm('');\r\n }\r\n };\r\n\r\n const toggleFocus = (event: React.FocusEvent) => {\r\n setIsFocused(event.type === 'focus');\r\n };\r\n\r\n const handleItemMouseDown = (event: React.MouseEvent) => {\r\n event.preventDefault();\r\n handleSelect();\r\n };\r\n\r\n return (\r\n \r\n {\r\n setSearchTerm(event.target.value);\r\n }}\r\n />\r\n
\r\n \r\n
\r\n\r\n {isFocused && searchTerm && (\r\n \r\n {searchResults.length === 0 && (\r\n
Ingen resultater
\r\n )}\r\n {searchResults.map((task, index) => (\r\n setActiveResultIndex(index)}\r\n ref={(element) => {\r\n itemsRef.current[index] = element!;\r\n }}\r\n onClick={handleSelect}\r\n >\r\n
\r\n {zeroPadId(task.id)}\r\n \r\n
\r\n
{task.title}
\r\n \r\n ))}\r\n \r\n )}\r\n \r\n );\r\n};\r\n\r\nexport default SearchInput;\r\n","import classes from './SearchPanel.module.css';\r\nimport * as React from 'react';\r\nimport SearchInput from './SearchInput';\r\n\r\ntype SearchPanelProps = {\r\n isOpen: boolean;\r\n onSelect: React.ComponentProps['onSelect'];\r\n onClose: () => void;\r\n};\r\n\r\nconst SearchPanel = ({\r\n isOpen,\r\n onSelect,\r\n onClose,\r\n}: SearchPanelProps) => {\r\n const panelRef = React.useRef(null);\r\n\r\n React.useEffect(() => {\r\n if (isOpen) {\r\n panelRef.current?.classList.add(classes.open);\r\n } else {\r\n panelRef.current?.classList.remove(classes.open);\r\n }\r\n }, [isOpen]);\r\n\r\n return (\r\n \r\n \r\n \r\n );\r\n}\r\n\r\nexport default SearchPanel;\r\n","import * as React from 'react';\r\nimport classes from './Switch.module.css';\r\nimport classNames from 'classnames';\r\n\r\ntype SwitchProps = {\r\n checked?: boolean;\r\n onChange: (checked: boolean) => void;\r\n}\r\n\r\nconst Switch = ({\r\n checked,\r\n onChange,\r\n}: SwitchProps) => {\r\n return (\r\n \r\n onChange(target.checked)}\r\n />\r\n \r\n \r\n );\r\n};\r\n\r\nexport default Switch;\r\n","// extracted by mini-css-extract-plugin\nexport default {\"switch\":\"kblrIn0Y_t6CM6uzTMOM\",\"checked\":\"BFZpFI7YU9g74BWxiuvx\"};","import createEventSignal from '../core/Signal';\r\n\r\nexport const [onToggleTasksPanel, dispatchToggleTasksPanel] = createEventSignal();\r\n","import * as React from 'react';\r\nimport { FiSearch } from 'react-icons/fi';\r\nimport { COLUMNS_START_PADDING, HEADER_HEIGHT, SIDEBAR_WIDTH } from '../../layout';\r\nimport { scrollTaskIntoView, selectTask } from '../../state';\r\nimport { useDateRange, useExpandedColumns, useTaskCategories, useGroupBy, useReleases, useTasksByRelease, useFilters } from '../../state/context';\r\nimport { Filter, Task, TaskCategory } from '../../types';\r\nimport ColumnGrid from '../ColumnGrid';\r\nimport AuthButton from './AuthButton';\r\nimport HeaderCheckbox from './Checkbox';\r\nimport DatePanel from './DatePanel';\r\nimport HeaderColumn from './HeaderColumn';\r\nimport SearchPanel from './SearchPanel';\r\nimport Switch from './Switch';\r\nimport { dispatchToggleTasksPanel } from '../../state/actions';\r\nimport classNames from 'classnames';\r\n\r\nconst getNumberOfSolutions = (tasks: Task[]) => {\r\n const solutionIds: number[] = [];\r\n\r\n tasks.forEach((task) => {\r\n if (!solutionIds.includes(task.solutionId)) {\r\n solutionIds.push(task.solutionId);\r\n }\r\n });\r\n\r\n return solutionIds.length;\r\n};\r\n\r\nconst Header = () => {\r\n const releases = useReleases();\r\n const [filters, setFilters] = useFilters();\r\n const [expandedColumns, toggleColumn] = useExpandedColumns();\r\n const [isSearchPanelOpen, setIsSearchPanelOpen] = React.useState(false);\r\n const [groupBy, setGroupBy] = useGroupBy();\r\n const [dateRange, setDateRange] = useDateRange();\r\n const tasksByRelease = useTasksByRelease();\r\n const innerRef = React.useRef(null);\r\n\r\n const toggleFilter = (filter: Filter) => {\r\n if (filters.includes(filter)) {\r\n setFilters(filters.filter((f) => f !== filter));\r\n } else {\r\n setFilters([...filters, filter]);\r\n }\r\n }\r\n\r\n React.useEffect(() => {\r\n const handleScroll = () => {\r\n if (innerRef.current) {\r\n innerRef.current.style.transform = `translateX(-${window.scrollX}px)`;\r\n }\r\n };\r\n\r\n window.addEventListener('scroll', handleScroll);\r\n\r\n return () => {\r\n window.removeEventListener('scroll', handleScroll);\r\n };\r\n }, []);\r\n\r\n return (\r\n \r\n \r\n
\r\n

FIU Roadmap

\r\n \r\n
\r\n
\r\n toggleFilter('error')}\r\n />\r\n toggleFilter('request')}\r\n />\r\n toggleFilter('support')}\r\n />\r\n toggleFilter('maintenance')}\r\n />\r\n toggleFilter('documentation')}\r\n />\r\n
\r\n
\r\n {\r\n if (isDatePanelOpen) {\r\n setIsSearchPanelOpen(false);\r\n }\r\n }}\r\n />\r\n
\r\n \r\n setGroupBy(checked ? 'organization' : 'solution')}\r\n />\r\n Forbund\r\n \r\n
\r\n {\r\n event.preventDefault();\r\n if (isSearchPanelOpen) {\r\n selectTask(null);\r\n }\r\n setIsSearchPanelOpen(!isSearchPanelOpen);\r\n\r\n }}\r\n className={classNames(\r\n 'h-6 w-6 flex items-center justify-center rounded-md',\r\n isSearchPanelOpen && 'bg-gray-200',\r\n )}\r\n >\r\n \r\n \r\n
\r\n {\r\n setIsSearchPanelOpen(false);\r\n selectTask(null);\r\n }}\r\n onSelect={(task) => {\r\n if (!task.releaseId) {\r\n dispatchToggleTasksPanel(true);\r\n }\r\n\r\n scrollTaskIntoView(task.id);\r\n }}\r\n />\r\n \r\n \r\n
\r\n \r\n {releases.map((release) => (\r\n toggleColumn(release.id)}\r\n />\r\n ))}\r\n
\r\n \r\n \r\n );\r\n};\r\n\r\nexport default Header;\r\n","import * as React from 'react';\r\nimport {\r\n APPLICATION_TASK_TAB_PAD_HEIGHT,\r\n COLLAPSED_COLUMN_WIDTH,\r\n COLLAPSED_ROW_HEIGHT,\r\n COLUMNS_START_PADDING,\r\n EXPANDED_COLUMN_WIDTH,\r\n HEADER_HEIGHT,\r\n SIDEBAR_WIDTH,\r\n} from '../../layout';\r\nimport {\r\n useExpandedColumns,\r\n useGroupBy,\r\n useReleases,\r\n useRowHeights,\r\n} from '../../state/context';\r\n\r\nconst Scroll = () => {\r\n const releases = useReleases();\r\n const [expandedColumns] = useExpandedColumns();\r\n const [groupBy] = useGroupBy();\r\n const rowHeights = useRowHeights();\r\n\r\n const width = React.useMemo(\r\n () => {\r\n const collapsedColumns = releases.length - expandedColumns.length;\r\n\r\n return (\r\n SIDEBAR_WIDTH +\r\n COLUMNS_START_PADDING +\r\n (expandedColumns.length * EXPANDED_COLUMN_WIDTH) +\r\n (collapsedColumns * COLLAPSED_COLUMN_WIDTH)\r\n );\r\n },\r\n [releases.length, expandedColumns.length]\r\n );\r\n\r\n const height = React.useMemo(\r\n () => {\r\n let value = (\r\n HEADER_HEIGHT +\r\n Object.values(rowHeights).reduce((acc, curr) => acc + curr, 0)\r\n );\r\n\r\n value += APPLICATION_TASK_TAB_PAD_HEIGHT;\r\n\r\n return value;\r\n },\r\n [rowHeights, groupBy]\r\n );\r\n\r\n return (\r\n \r\n );\r\n};\r\n\r\nexport default Scroll;\r\n","// extracted by mini-css-extract-plugin\nexport default {\"rowGroup\":\"TnackOBZJyeEQTofoUx7\",\"tab\":\"x3_BvyBdJg5ckWYqq84g\"};","import classes from './RowGroup.module.css';\r\nimport classNames from 'classnames';\r\nimport * as React from 'react';\r\nimport { COLLAPSED_ROW_HEIGHT } from '../../layout';\r\nimport { useSolutions, useRowHeights, useTasksBySolution } from '../../state/context';\r\n\r\nconst SolutionSidebarRows = () => {\r\n const solutions = useSolutions();\r\n const tasks = useTasksBySolution();\r\n const rowHeights = useRowHeights();\r\n\r\n return (\r\n <>\r\n {solutions.map((solution) => (\r\n \r\n

{solution.name}

\r\n
\r\n
{tasks[`${solution.id}`]?.length || 0}
\r\n
sager
\r\n
I alt over hele perioden
\r\n
\r\n ))}\r\n \r\n );\r\n};\r\n\r\nexport default SolutionSidebarRows;\r\n","import classes from './RowGroup.module.css';\r\nimport classNames from 'classnames';\r\nimport * as React from 'react';\r\nimport { COLLAPSED_ROW_HEIGHT } from '../../layout';\r\nimport { useExpandedRows, useOrganizations, useRowHeights, useTasksByOrganization } from '../../state/context';\r\nimport { FiChevronDown, FiImage } from 'react-icons/fi';\r\nimport { pluralize } from '../../utils/stringUtils';\r\nimport { Organization, Task } from '../../types';\r\n\r\ntype OrganizationSidebarRowProps = {\r\n organization: Organization;\r\n tasks: Task[];\r\n height: number;\r\n onToggle: (id: number) => void;\r\n};\r\n\r\nconst OrganizationSidebarRow = ({\r\n tasks,\r\n organization,\r\n height,\r\n onToggle,\r\n}: OrganizationSidebarRowProps) => {\r\n const [expandedRows] = useExpandedRows();\r\n const isExpanded = expandedRows.includes(organization.id);\r\n const numberOfSolutions = React.useMemo(() => {\r\n return tasks\r\n .map((task) => task.solutionId)\r\n .filter((value, index, self) => self.indexOf(value) === index)\r\n .length;\r\n }, [tasks]);\r\n\r\n return (\r\n \r\n
\r\n
\r\n
\r\n {organization.logoUrl && (\r\n \r\n {organization.name}\r\n
\r\n )}\r\n {!organization.logoUrl && (\r\n
\r\n \r\n
\r\n )}\r\n
\r\n\r\n
\r\n
{tasks.length}
\r\n
\r\n {pluralize(tasks.length, 'sag', 'sager')}\r\n
\r\n
I alt over hele perioden
\r\n
\r\n\r\n
\r\n
{numberOfSolutions}
\r\n
\r\n {pluralize(numberOfSolutions, 'applikation', 'applikationer')}\r\n
\r\n
Fordeler sagerne sig på
\r\n
\r\n\r\n onToggle(organization.id)}\r\n >\r\n {isExpanded ? 'Vis mindre' : 'Vis mere'} \r\n \r\n
\r\n \r\n \r\n );\r\n};\r\n\r\nconst OrganizationSidebarRows = () => {\r\n const organizations = useOrganizations();\r\n const rowHeights = useRowHeights();\r\n const tasks = useTasksByOrganization();\r\n const [_, toggleRow] = useExpandedRows();\r\n\r\n return (\r\n <>\r\n {organizations.map((organization) => (\r\n \r\n ))}\r\n \r\n );\r\n};\r\n\r\nexport default OrganizationSidebarRows;\r\n","import * as React from 'react';\r\nimport { HEADER_HEIGHT, SIDEBAR_WIDTH } from '../../layout';\r\nimport { useGroupBy } from '../../state/context';\r\nimport SolutionSidebarRows from './SolutionsSidebarRows';\r\nimport OrganizationsSidebarRows from './OrganizationsSidebarRows';\r\n\r\nconst RowsSidebar = () => {\r\n const [groupBy] = useGroupBy();\r\n const innerRef = React.useRef(null);\r\n\r\n React.useEffect(() => {\r\n const handleScroll = () => {\r\n if (innerRef.current) {\r\n innerRef.current.style.transform = `translateY(-${window.scrollY}px)`;\r\n }\r\n };\r\n\r\n window.addEventListener('scroll', handleScroll);\r\n\r\n return () => {\r\n window.removeEventListener('scroll', handleScroll);\r\n };\r\n }, []);\r\n\r\n return (\r\n \r\n \r\n {groupBy === 'solution' && (\r\n \r\n )}\r\n {groupBy === 'organization' && (\r\n \r\n )}\r\n \r\n \r\n );\r\n};\r\n\r\nexport default RowsSidebar;\r\n","// extracted by mini-css-extract-plugin\nexport default {\"cell\":\"bieMEGUjRjXv0v6CVx3Y\",\"tab\":\"EdwsRjOwL8dsKCXZL3S1\",\"row-expanded\":\"dIQ5jnrKUmAIE1MBfBlK\",\"empty\":\"kGadwsBJ4goAIPALLvru\",\"column-expanded\":\"NxY5BqgHIqzFDODP_HTD\",\"container\":\"YWCSAmI4C_QBbZObgtWp\",\"placeholder\":\"EtwHhKDVS83dl3nmgyg_\"};","import { Task } from '../../types';\r\nimport * as React from 'react';\r\n\r\ntype TooltipContext = (task?: Task, ref?: React.MutableRefObject) => void;\r\n\r\nconst TooltipContext = React.createContext(() => {});\r\n\r\nexport const TooltipProvider = ({ children }: { children: React.ReactNode }) => {\r\n const [task, setTask] = React.useState(null);\r\n const tooltipRef = React.useRef(null);\r\n const taskRef = React.useRef(null);\r\n\r\n const setTooltip = React.useCallback((task?: Task, ref?: React.MutableRefObject) => {\r\n if (ref) {\r\n taskRef.current = ref.current;\r\n }\r\n\r\n setTask(task);\r\n }, []);\r\n\r\n React.useEffect(() => {\r\n if (task && taskRef.current) {\r\n tooltipRef.current!.classList.remove('hidden');\r\n\r\n tooltipRef.current!.style.top = `${taskRef.current.offsetTop}px`;\r\n } else {\r\n tooltipRef.current!.classList.add('hidden');\r\n }\r\n }, [task]);\r\n\r\n return (\r\n \r\n
\r\n {task && (\r\n
\r\n {task.title}\r\n
\r\n )}\r\n
\r\n {children}\r\n
\r\n );\r\n};\r\n\r\nexport const useTooltip = () => {\r\n return React.useContext(TooltipContext);\r\n};\r\n","import classes from './TaskListItem.module.css'\r\nimport * as React from 'react';\r\nimport classNames from 'classnames';\r\nimport { Task } from '../../types';\r\nimport { getTaskCategoryColor, zeroPadId } from '../../utils/taskUtils';\r\nimport { useTooltip } from './Tooltip';\r\nimport { useIsTaskSelected } from '../../state/context';\r\n\r\ntype TaskListItem = {\r\n task: Task;\r\n isExpanded: boolean;\r\n organizationName?: string;\r\n className?: string;\r\n onMouseEnter?: (task: Task, ref: React.MutableRefObject) => void;\r\n onMouseLeave?: (task: Task, ref: React.MutableRefObject) => void;\r\n};\r\n\r\nconst TaskListItem = ({\r\n task,\r\n isExpanded,\r\n organizationName,\r\n className,\r\n onMouseEnter,\r\n onMouseLeave,\r\n}: TaskListItem) => {\r\n const taskRef = React.useRef(null);\r\n const setTooltip = useTooltip();\r\n const isSelected = useIsTaskSelected(task);\r\n\r\n return (\r\n isExpanded && task.title && setTooltip(task, taskRef)}\r\n onMouseLeave={() => setTooltip(null)}\r\n className={classNames(\r\n 'px-3 text-xs relative',\r\n className,\r\n isSelected && 'bg-yellow-200',\r\n )}\r\n >\r\n {task.taskUrl && (\r\n \r\n )}\r\n
\r\n {zeroPadId(task.id)}\r\n \r\n {isExpanded && (\r\n
{task.title}
\r\n )}\r\n {isExpanded && organizationName && (\r\n
\r\n {organizationName}\r\n
\r\n )}\r\n {task.statusCode === 'onHold' && (\r\n
\r\n
\r\n
\r\n )}\r\n
\r\n
\r\n );\r\n};\r\n\r\nexport default TaskListItem;\r\n","// extracted by mini-css-extract-plugin\nexport default {\"task\":\"t0mIzilMAWjZhcjWBEDE\"};","import * as React from 'react';\r\nimport { Organization, Task } from '../../types';\r\nimport { useOrganizations } from '../../state/context';\r\nimport TaskListItem from './TaskListItem';\r\nimport { TooltipProvider } from './Tooltip';\r\n\r\ntype TaskListProps = {\r\n tasks: Task[];\r\n isExpanded: boolean;\r\n includeOrganizationName?: boolean;\r\n};\r\n\r\nconst getOrganizationNameById = (organizations: Organization[], organizationId: number) => {\r\n const organization = organizations.find(({ id }) => id === organizationId);\r\n return organization ? organization.name : undefined;\r\n};\r\n\r\nconst TaskList = ({\r\n tasks,\r\n isExpanded,\r\n includeOrganizationName,\r\n}: TaskListProps) => {\r\n const organizations = useOrganizations();\r\n\r\n return (\r\n \r\n {tasks.map((task) => (\r\n \r\n ))}\r\n \r\n );\r\n};\r\n\r\nexport default TaskList;\r\n","import classes from './SolutionRowCell.module.css';\r\nimport * as React from 'react';\r\nimport { COLLAPSED_COLUMN_WIDTH, EXPANDED_COLUMN_WIDTH } from '../../layout';\r\nimport { Task } from '../../types';\r\nimport classNames from 'classnames';\r\nimport { pluralize } from '../../utils/stringUtils';\r\nimport { FiChevronDown } from 'react-icons/fi';\r\nimport TaskList from '../TaskList';\r\nimport { useSolutionVersionsById } from '../../state/context';\r\n\r\ntype SolutionRowCellProps = {\r\n isColumnExpanded: boolean;\r\n isRowExpanded: boolean;\r\n tasks: Task[];\r\n onClick: () => void;\r\n};\r\n\r\nconst SolutionRowCell = ({\r\n isColumnExpanded,\r\n isRowExpanded,\r\n tasks,\r\n onClick,\r\n}: SolutionRowCellProps) => {\r\n const solutionVersionsById = useSolutionVersionsById();\r\n const solutionVersionId = React.useMemo(() => {\r\n return tasks.length > 0 ? tasks[0].solutionVersionId : undefined;\r\n }, [tasks]);\r\n const solutionVersion = solutionVersionId ? solutionVersionsById[solutionVersionId] : undefined;\r\n\r\n return (\r\n \r\n \r\n \r\n {isColumnExpanded && (\r\n <>\r\n {tasks.length === 0 && (\r\n
\r\n Ingen sager
i dette sprint\r\n
\r\n )}\r\n
{solutionVersion ? `v${solutionVersion.name}` : null}
\r\n\r\n \r\n \r\n )}\r\n {isColumnExpanded === false && (\r\n <>\r\n {tasks.length === 0 && (\r\n <>\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n )}\r\n
{solutionVersion ? `v${solutionVersion.name}` : null}
\r\n \r\n \r\n )}\r\n
\r\n
\r\n );\r\n};\r\n\r\nexport default SolutionRowCell;\r\n","import * as React from 'react';\r\nimport { COLLAPSED_ROW_HEIGHT, COLUMNS_START_PADDING, } from '../../layout';\r\nimport {\r\n useSolutions,\r\n useExpandedColumns,\r\n useExpandedRows,\r\n useReleases,\r\n useRowHeights,\r\n useTasksBySolutionAndRelease,\r\n useSolutionVersionsById,\r\n} from '../../state/context';\r\nimport SolutionRowCell from './SolutionRowCell';\r\nimport ColumnGrid from '../ColumnGrid';\r\n\r\nconst SolutionRows = () => {\r\n const releases = useReleases();\r\n const solutions = useSolutions();\r\n const rowHeights = useRowHeights();\r\n const [expandedColumns] = useExpandedColumns();\r\n const [expandedRows, toggleRow] = useExpandedRows();\r\n const tasks = useTasksBySolutionAndRelease();\r\n const solutionVersionsById = useSolutionVersionsById();\r\n\r\n return (\r\n
\r\n \r\n {solutions.map((solution) => (\r\n \r\n {releases.map((release) => (\r\n toggleRow(solution.id)}\r\n />\r\n ))}\r\n
\r\n ))}\r\n
\r\n );\r\n};\r\n\r\nexport default SolutionRows;\r\n","import classes from './OrganizationRowCell.module.css';\r\nimport * as React from 'react';\r\nimport { COLLAPSED_COLUMN_WIDTH, EXPANDED_COLUMN_WIDTH } from '../../layout';\r\nimport { useSolutionVersionsById, useSolutions } from '../../state/context';\r\nimport { Solution, SolutionVersion, Task } from '../../types';\r\nimport TaskList from '../TaskList';\r\nimport classNames from 'classnames';\r\n\r\ntype OrganizationRowCellProps = {\r\n tasks: Task[];\r\n isColumnExpanded: boolean;\r\n};\r\n\r\ntype SolutionTasksMap = Record;\r\n\r\nconst OrganizationRowCell = ({\r\n tasks,\r\n isColumnExpanded,\r\n}: OrganizationRowCellProps) => {\r\n const solutionVersionsById = useSolutionVersionsById();\r\n const solutions = useSolutions();\r\n const solutionsById = React.useMemo(() => {\r\n const map: Record = {};\r\n\r\n solutions.forEach((solution) => {\r\n map[solution.id] = solution;\r\n });\r\n\r\n return map;\r\n }, [solutions]);\r\n\r\n const solutionsWithTasks = React.useMemo(() => {\r\n const tasksBySolution: SolutionTasksMap = {};\r\n\r\n tasks.forEach((task) => {\r\n if (!tasksBySolution[task.solutionId]) {\r\n tasksBySolution[task.solutionId] = {\r\n tasks: [],\r\n version: solutionVersionsById[task.solutionVersionId],\r\n solution: solutionsById[task.solutionId],\r\n };\r\n }\r\n\r\n tasksBySolution[task.solutionId].tasks.push(task);\r\n });\r\n\r\n return Object.values(tasksBySolution)\r\n .sort((a, b) => a.solution.name.localeCompare(b.solution.name));\r\n }, [tasks, solutionsById]);\r\n\r\n return (\r\n \r\n
\r\n {solutionsWithTasks.length === 0 && (\r\n \r\n Ingen
\r\n sager\r\n
\r\n )}\r\n {solutionsWithTasks.map(({ solution, tasks, version }) => (\r\n
\r\n \r\n {solution.name}\r\n {version && (\r\n v{version.name}\r\n )}\r\n
\r\n \r\n
\r\n ))}\r\n
\r\n
\r\n );\r\n};\r\n\r\nexport default OrganizationRowCell;\r\n","// extracted by mini-css-extract-plugin\nexport default {\"container\":\"cvalCdfrLz6x4ZYIbati\",\"cell\":\"BjFInFO1GAsRAu9UV3KD\",\"column-expanded\":\"a55EDhemCFQU9erkDY_g\",\"solution-name\":\"ED3u7hYimaanFhWmWkHE\"};","import * as React from 'react';\r\nimport { COLLAPSED_ROW_HEIGHT, COLUMNS_START_PADDING } from '../../layout';\r\nimport { useExpandedColumns, useOrganizations, useReleases, useRowHeights, useTasksByOrganizationAndRelease } from '../../state/context';\r\nimport ColumnGrid from '../ColumnGrid';\r\nimport OrganizationRowCell from './OrganizationRowCell';\r\n\r\nconst OrganizationRows = () => {\r\n const organizations = useOrganizations();\r\n const rowHeights = useRowHeights();\r\n const tasks = useTasksByOrganizationAndRelease();\r\n const releases = useReleases();\r\n const [expandedColumns] = useExpandedColumns();\r\n\r\n return (\r\n
\r\n \r\n {organizations.map((organization) => (\r\n \r\n {releases.map((release) => (\r\n \r\n ))}\r\n
\r\n ))}\r\n \r\n );\r\n};\r\n\r\nexport default OrganizationRows;\r\n","import * as React from 'react';\r\nimport { APPLICATION_TASK_TAB_PAD_HEIGHT, COLLAPSED_COLUMN_WIDTH, COLLAPSED_ROW_HEIGHT, HEADER_HEIGHT, SIDEBAR_WIDTH } from '../../layout';\r\nimport { useGroupBy, useOrganizations, useReleases, useRowHeights } from '../../state/context';\r\nimport SolutionRows from './SolutionRows';\r\nimport OrganizationRows from './OrganizationRows';\r\nimport { onSelectTaskChange } from '../../state';\r\n\r\nconst Rows = () => {\r\n const releases = useReleases();\r\n const organizations = useOrganizations();\r\n const rowHeights = useRowHeights();\r\n const [groupBy] = useGroupBy();\r\n const innerRef = React.useRef(null);\r\n\r\n React.useEffect(() => {\r\n return onSelectTaskChange((task) => {\r\n if (!innerRef.current || !task) {\r\n return;\r\n }\r\n\r\n const solution = innerRef.current.querySelector(`[data-solution-id=\"${task.solutionId}\"]`) as HTMLDivElement;\r\n\r\n if (!solution) {\r\n return;\r\n }\r\n\r\n window.scrollTo({\r\n top: solution.offsetTop - HEADER_HEIGHT,\r\n left: solution.offsetLeft,\r\n behavior: 'smooth',\r\n });\r\n });\r\n }, []);\r\n\r\n React.useEffect(() => {\r\n const handleScroll = () => {\r\n if (innerRef.current) {\r\n innerRef.current.style.transform = `translate(-${window.scrollX}px, -${window.scrollY}px)`;\r\n }\r\n };\r\n\r\n window.addEventListener('scroll', handleScroll);\r\n\r\n return () => {\r\n window.removeEventListener('scroll', handleScroll);\r\n };\r\n }, []);\r\n\r\n const width = React.useMemo(\r\n () => (releases.length * COLLAPSED_COLUMN_WIDTH) + SIDEBAR_WIDTH,\r\n [releases.length],\r\n );\r\n\r\n const height = React.useMemo(\r\n () => {\r\n let value = (\r\n HEADER_HEIGHT +\r\n Object.values(rowHeights).reduce((acc, curr) => acc + curr, 0)\r\n );\r\n\r\n if (groupBy === 'organization') {\r\n value += APPLICATION_TASK_TAB_PAD_HEIGHT;\r\n }\r\n\r\n return value;\r\n },\r\n [organizations.length, rowHeights],\r\n );\r\n\r\n return (\r\n \r\n
\r\n {groupBy === 'solution' && (\r\n \r\n )}\r\n {groupBy === 'organization' && (\r\n \r\n )}\r\n
\r\n \r\n );\r\n};\r\n\r\nexport default Rows;\r\n","import * as React from 'react';\r\nimport classes from './Group.module.css';\r\nimport { Task } from '../../types';\r\nimport TaskListItem from '../TaskList/TaskListItem';\r\n\r\ntype OrganizationGroupProps = {\r\n height: number;\r\n tasks: Task[];\r\n}\r\n\r\nconst OrganizationGroup = ({\r\n height,\r\n tasks,\r\n}: OrganizationGroupProps) => {\r\n return (\r\n \r\n {tasks.length === 0 && (\r\n
\r\n

Ingen sager der skal placeres

\r\n
\r\n )}\r\n {tasks.length > 0 && (\r\n
\r\n {tasks.map((task) => (\r\n \r\n ))}\r\n
\r\n )}\r\n \r\n );\r\n};\r\n\r\nexport default OrganizationGroup;\r\n","// extracted by mini-css-extract-plugin\nexport default {\"group\":\"SP6CJb1xVIbzpWd40MIX\"};","import * as React from 'react';\r\nimport { useOrganizations, useRowHeights, useUnassignedTasksByOrganization } from '../../state/context';\r\nimport Group from './Group';\r\n\r\nconst OrganizationsTasks = () => {\r\n const organizations = useOrganizations();\r\n const rowHeights = useRowHeights();\r\n const tasks = useUnassignedTasksByOrganization();\r\n const ref = React.useRef(null);\r\n\r\n React.useEffect(() => {\r\n const handleScroll = () => {\r\n if (ref.current) {\r\n ref.current.style.transform = `translateY(-${window.scrollY}px)`;\r\n }\r\n };\r\n\r\n window.addEventListener('scroll', handleScroll);\r\n\r\n return () => {\r\n window.removeEventListener('scroll', handleScroll);\r\n };\r\n }, []);\r\n\r\n return (\r\n
\r\n {organizations.map((organization) => (\r\n \r\n ))}\r\n
\r\n );\r\n};\r\n\r\nexport default OrganizationsTasks;\r\n","import * as React from 'react';\r\nimport { useSolutions, useRowHeights, useUnassignedTasksBySolution } from '../../state/context';\r\nimport Group from './Group';\r\n\r\nconst SolutionsTasks = () => {\r\n const solutions = useSolutions();\r\n const rowHeights = useRowHeights();\r\n const tasks = useUnassignedTasksBySolution();\r\n const ref = React.useRef(null);\r\n\r\n React.useEffect(() => {\r\n const handleScroll = () => {\r\n if (ref.current) {\r\n ref.current.style.transform = `translateY(-${window.scrollY}px)`;\r\n }\r\n };\r\n\r\n window.addEventListener('scroll', handleScroll);\r\n\r\n return () => {\r\n window.removeEventListener('scroll', handleScroll);\r\n };\r\n }, []);\r\n\r\n return (\r\n
\r\n {solutions.map((solution) => (\r\n \r\n ))}\r\n
\r\n );\r\n};\r\n\r\nexport default SolutionsTasks;\r\n","import * as React from 'react';\r\nimport { useUnassignedTasks } from '../../state/context';\r\n\r\nconst Count = () => {\r\n const count = useUnassignedTasks().length;\r\n\r\n return (\r\n
{count}
\r\n );\r\n};\r\n\r\nexport default Count;\r\n","import styles from './Checkbox.module.css';\r\nimport * as React from 'react';\r\nimport classNames from 'classnames';\r\n\r\ntype CheckboxProps = {\r\n checked?: boolean;\r\n onChange: (checked: boolean) => void;\r\n className?: string;\r\n children?: React.ReactNode;\r\n};\r\n\r\nconst Checkbox = ({\r\n checked,\r\n onChange,\r\n className,\r\n children,\r\n}: CheckboxProps) => {\r\n return (\r\n \r\n );\r\n};\r\n\r\nexport default Checkbox;\r\n","// extracted by mini-css-extract-plugin\nexport default {\"checkbox\":\"sy8lKVWP56AlOR7ys_9A\"};","import classes from './TasksPanel.module.css';\r\nimport * as React from 'react';\r\nimport classNames from 'classnames';\r\nimport { useFilters, useGroupBy } from '../../state/context';\r\nimport OrganizationsTasks from './OrganizationsTasks';\r\nimport SolutionsTasks from './SolutionsTasks';\r\nimport Count from './Count';\r\nimport { HEADER_HEIGHT } from '../../layout';\r\nimport { onToggleTasksPanel } from '../../state/actions';\r\nimport Checkbox from '../Checkbox';\r\n\r\nconst TasksPanel = () => {\r\n const [isExpanded, setIsExpanded] = React.useState(false);\r\n const [filters, setFilters] = useFilters();\r\n const [groupBy] = useGroupBy();\r\n const excludeOnHold = filters.includes('exclude-on-hold');\r\n\r\n React.useEffect(() => {\r\n return onToggleTasksPanel(setIsExpanded);\r\n }, []);\r\n\r\n return (\r\n \r\n \r\n Sager der endnu ikke er tildelt et sprint \r\n \r\n
\r\n {\r\n if (excludeOnHold) {\r\n setFilters(filters.filter((filter) => filter !== 'exclude-on-hold'));\r\n } else {\r\n setFilters([...filters, 'exclude-on-hold']);\r\n }\r\n }}\r\n >\r\n
Sager sat på hold\r\n \r\n
\r\n
\r\n
\r\n {groupBy === 'organization' && (\r\n \r\n )}\r\n {groupBy === 'solution' && (\r\n \r\n )}\r\n
\r\n \r\n );\r\n};\r\n\r\nexport default TasksPanel;\r\n","// extracted by mini-css-extract-plugin\nexport default {\"panel\":\"iBZfUTZtayjDYItKhTBo\",\"expanded\":\"jw0awNddIQkzrx7QC7p4\",\"header\":\"E9RJ44dceHm7oezHExQ8\",\"tab\":\"ME3P5ii_HhwTKuLxTQyR\",\"content\":\"u6wkROzUG1sgey39jzbF\"};","import classes from './Spinner.module.css';\r\nimport * as React from 'react';\r\n\r\nconst Spinner = () => {\r\n return (\r\n \r\n
\r\n
\r\n
\r\n
\r\n );\r\n}\r\n\r\nexport default Spinner;\r\n","// extracted by mini-css-extract-plugin\nexport default {\"spinner\":\"m6c6ivJb2__bh6ILoZTM\",\"bounce1\":\"OWRkvatcJ4KQbDDH3hUm\",\"bounce\":\"Cf0yl68pkgU1fzPECgKi\",\"bounce2\":\"qx_e__8CQSY7CZIMZMqk\",\"bounce3\":\"SiNFJ7MurssG7iJLJZtD\"};","import * as React from 'react';\r\nimport { HEADER_HEIGHT, SIDEBAR_WIDTH } from '../../layout';\r\nimport Spinner from '../Spinner';\r\n\r\nconst SkeletonApp = () => (\r\n
\r\n \r\n \r\n
\r\n
\r\n \r\n
\r\n \r\n
\r\n
\r\n
\r\n);\r\n\r\nexport default SkeletonApp;\r\n","import './index.css';\r\nimport * as React from 'react';\r\nimport Header from './components/Header';\r\nimport Scroll from './components/Scroll';\r\nimport RowsSidebar from './components/RowsSidebar';\r\nimport Rows from './components/Rows';\r\nimport { fetchData, RoadmapResult } from './core/Api';\r\nimport { reset } from './state';\r\nimport TasksPanel from './components/TasksPanel';\r\nimport { useDateRange, useIsAuthenticated, useTasks } from './state/context';\r\nimport SkeletonApp from './components/SkeletonApp';\r\nimport { DateRange } from './types';\r\nimport { HEADER_HEIGHT } from './layout';\r\n\r\nconst App = () => {\r\n const isAuthenticated = useIsAuthenticated();\r\n const isAuthenticatedRef = React.useRef(isAuthenticated);\r\n const [isLoading, setIsLoading] = React.useState(true);\r\n const [dateRange] = useDateRange();\r\n const tasks = useTasks();\r\n\r\n const fetch = React.useCallback(\r\n (range: DateRange) => {\r\n const [fromDate, toDate] = dateRange;\r\n\r\n setIsLoading(true);\r\n\r\n fetchData({ fromDate, toDate })\r\n .then(reset)\r\n .finally(() => setIsLoading(false));\r\n },\r\n [dateRange],\r\n );\r\n\r\n React.useEffect(() => fetch(dateRange), [dateRange]);\r\n\r\n React.useEffect(() => {\r\n if (!isAuthenticated && isAuthenticatedRef.current) {\r\n fetch(dateRange);\r\n }\r\n\r\n isAuthenticatedRef.current = isAuthenticated;\r\n }, [isAuthenticated]);\r\n\r\n if (isLoading && !tasks.length) {\r\n return ;\r\n }\r\n\r\n return (\r\n <>\r\n {isLoading && (\r\n \r\n )}\r\n
\r\n \r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\nexport default App;\r\n","import * as React from 'react';\r\nimport { useLocation, useNavigate } from 'react-router-dom';\r\nimport { login } from '../core/Api';\r\n\r\nconst AuthCallback = () => {\r\n const [error, setError] = React.useState(null);\r\n const location = useLocation();\r\n const navigate = useNavigate();\r\n const query = React.useMemo(() => {\r\n const parsedQuery: Record = {};\r\n const queryFragments = location.search.slice(1)\r\n .split('&');\r\n\r\n for (const fragment of queryFragments) {\r\n const [key, value] = fragment.split('=');\r\n parsedQuery[key] = value;\r\n }\r\n\r\n return parsedQuery;\r\n }, [location.search]);\r\n\r\n const token = React.useMemo(\r\n () => query.token || null,\r\n [query],\r\n );\r\n\r\n React.useEffect(() => {\r\n login(token)\r\n .then(() => {\r\n navigate('/');\r\n })\r\n .catch((error) => {\r\n setError(error);\r\n });\r\n }, [token]);\r\n\r\n if (!token) {\r\n throw new Error('Ingen login-token fundet.');\r\n }\r\n\r\n if (error) {\r\n throw error;\r\n }\r\n\r\n return (\r\n
\r\n );\r\n};\r\n\r\nexport default AuthCallback;\r\n","import * as React from 'react';\r\nimport { isRouteErrorResponse, useRouteError } from 'react-router-dom';\r\n\r\nconst ErrorPage = () => {\r\n const error = useRouteError();\r\n\r\n if (isRouteErrorResponse(error) && error.status === 404) {\r\n return (\r\n
\r\n

404

\r\n

Siden, du ledte efter, eksistere ikke.

\r\n
\r\n );\r\n }\r\n\r\n return (\r\n
\r\n

Hov!

\r\n

Der opstod en uventet fejl.

\r\n\r\n
\r\n        {error instanceof Error && (\r\n          <>\r\n            {error.message\r\n              ? 

{error.message}

\r\n : null}\r\n\r\n \r\n )}\r\n
\r\n
\r\n );\r\n};\r\n\r\nexport default ErrorPage;\r\n","import * as React from 'react';\r\nimport { createRoot } from 'react-dom/client';\r\nimport { createBrowserRouter, RouterProvider } from 'react-router-dom';\r\nimport App from './App';\r\nimport AuthCallback from './AuthCallback';\r\nimport ErrorPage from './ErrorPage';\r\n\r\nconst router = createBrowserRouter([\r\n {\r\n path: '/',\r\n element: ,\r\n errorElement: ,\r\n },\r\n {\r\n path: '/callback',\r\n element: ,\r\n errorElement: ,\r\n }\r\n], {\r\n basename: '/roadmap',\r\n});\r\n\r\nconst container = document.getElementById('app')!;\r\nconst root = createRoot(container);\r\n\r\nroot.render(\r\n \r\n \r\n \r\n);\r\n"],"names":["HEADER_HEIGHT","SIDEBAR_WIDTH","COLLAPSED_COLUMN_WIDTH","EXPANDED_COLUMN_WIDTH","COLLAPSED_ROW_HEIGHT","subscribers","subscriber","isSubscribed","push","index","indexOf","splice","data","forEach","groupBy","array","key","map","item","groupKey","shortMonthNames","fullMonthNames","getShortMonthName","date","getMonth","formatDateInputValue","year","getFullYear","month","day","getDate","createEventSignal","onFiltersChange","dispatchFiltersChange","onExpandedColumnsChange","dispatchOnExpandedColumnsChange","onExpandedRowsChange","dispatchOnExpandedRowsChange","onDateRangeChange","dispatchOnDateRangeChange","onGroupByChange","dispatchOnGroupByChange","onRowHeightsChange","dispatchOnRowHeightsChange","onFilteredTasksChange","dispatchOnFilteredTasksChange","onTasksChange","dispatchOnTasksChange","onSelectTaskChange","dispatchOnSelectTaskChange","onIsAuthenticatedChange","dispatchIsAuthenticatedChange","dateRange","Date","setMonth","setDate","setHours","getEndOfYear","filters","expandedColumns","expandedRows","selectedTask","tasks","releases","organizations","solutions","solutionVersions","rowHeights","isAuthenticated","solutionVersionsById","getFilteredTasks","filter","task","includes","statusCode","category","getTasks","getIsAuthenticated","getSelectedTask","calculateRowHeights","heights","groupArrayBy","organizationId","releaseId","organization","isExpanded","id","maxHeight","unassignedTasks","numberOfRows","Math","ceil","length","unassignedTasksHeight","UNASSIGNED_Y_PADDING","release","filteredTasks","numberOfSolutions","Object","keys","solutionId","height","INNER_Y_PADDING","solution","reset","sort","a","b","releaseDate","getTime","name","localeCompare","solutionVersion","currentYear","currentMonth","currrentRelease","find","toggleColumn","nextIsAuthenticated","user","setDateRange","newDateRange","setFilters","newFilters","setGroupBy","newGroupBy","setIsAuthenticated","newIsAuthenticated","column","exclusive","c","toggleRow","row","r","selectTask","scrollTaskIntoView","taskId","foundTask","org","app","useFilteredTasks","useState","setTasks","useEffect","useReleases","useOrganizations","useSolutions","useSolutionVersionsById","useTasksByRelease","useMemo","useExpandedColumns","_columns","_setColumns","useExpandedRows","_rows","_setRows","useIsAuthenticated","useSetIsAuthenticated","useFilters","_filters","_setFilters","useDateRange","_dateRange","_setDateRange","useGroupBy","_groupBy","_setGroupBy","useRowHeights","_rowHeights","_setRowHeights","excludeLeftPadding","stripes","React","left","className","classNames","classes","style","width","i","Api","axios","baseURL","process","headers","fetchData","params","get","fromDateTime","fromDate","toISOString","toDateTime","toDate","login","token","post","logout","onClick","window","location","replace","xmlns","fill","viewBox","stroke","strokeLinecap","strokeLinejoin","strokeWidth","d","TASK_CATEGORY_BG_COLORS","error","support","request","maintenance","documentation","type","checked","onChange","label","target","onToggleChange","setIsExpanded","startDate","setStartDate","endDate","setEndDate","startDateInputRef","endDateInputRef","ref","isValid","isNaN","handleClickOutside","event","current","contains","document","addEventListener","removeEventListener","valueAsDate","handleKeyDown","preventDefault","htmlFor","defaultValue","onBlur","pluralize","count","singular","plural","numberOfTasks","toggle","monthName","getMonthName","fullYear","fuse","Fuse","includeScore","threshold","setCollection","zeroPadId","string","toString","slice","getTaskCategoryColor","props","isFocused","setIsFocused","searchTerm","setSearchTerm","searchResults","setSearchResults","activeResultIndex","setActiveResultIndex","inputRef","itemsRef","query","results","search","result","handleSelect","onSelect","blur","scrollIntoView","block","toggleFocus","handleItemMouseDown","placeholder","value","onFocus","onKeyDown","min","max","stopPropagation","onClear","onMouseDown","onMouseOver","element","title","isOpen","onClose","panelRef","classList","add","remove","onToggleTasksPanel","dispatchToggleTasksPanel","getNumberOfSolutions","solutionIds","isSearchPanelOpen","setIsSearchPanelOpen","tasksByRelease","innerRef","toggleFilter","f","handleScroll","transform","scrollX","isDatePanelOpen","paddingLeft","collapsedColumns","values","reduce","acc","curr","useTasksBySolution","OrganizationSidebarRow","onToggle","self","logoUrl","src","alt","useTasksByOrganization","scrollY","top","OrganizationsSidebarRows","TooltipContext","TooltipProvider","children","setTask","tooltipRef","taskRef","setTooltip","offsetTop","Provider","organizationName","onMouseEnter","onMouseLeave","isSelected","setIsSelected","selectedRef","useRef","nextIsSelected","useIsTaskSelected","taskUrl","href","rel","getOrganizationNameById","undefined","includeOrganizationName","isColumnExpanded","isRowExpanded","solutionVersionId","useTasksBySolutionAndRelease","solutionsById","solutionsWithTasks","tasksBySolution","version","useTasksByOrganizationAndRelease","querySelector","scrollTo","offsetLeft","behavior","useUnassignedTasksByOrganization","Group","useUnassignedTasksBySolution","excludeOnHold","fillRule","isAuthenticatedRef","isLoading","setIsLoading","useTasks","fetch","range","then","setError","useLocation","navigate","useNavigate","parsedQuery","split","Error","useRouteError","isRouteErrorResponse","status","message","router","createBrowserRouter","path","errorElement","basename","container","getElementById","createRoot","render"],"sourceRoot":""}