diff --git a/src/app/issue/issue.selector.ts b/src/app/issue/issue.selector.ts new file mode 100644 index 0000000..87d3205 --- /dev/null +++ b/src/app/issue/issue.selector.ts @@ -0,0 +1,13 @@ +import { createSelector } from '@ngrx/store'; +import { selectJiraIssueEntities } from './jira/jira-issue/store/jira-issue.reducer'; + +export const selectIssueEntityMap = createSelector( + selectJiraIssueEntities, + ( + (jiraIssues) => { + return { + JIRA: jiraIssues + }; + } + ) +); diff --git a/src/app/issue/issue.service.ts b/src/app/issue/issue.service.ts index eaf4d5a..4aea5f4 100644 --- a/src/app/issue/issue.service.ts +++ b/src/app/issue/issue.service.ts @@ -1,8 +1,5 @@ -import { map } from 'rxjs/operators'; import { Injectable } from '@angular/core'; -import { JiraIssueService } from './jira/jira-issue/jira-issue.service'; -import { combineLatest, Observable } from 'rxjs'; -import { IssueEntityMap, IssueProviderKey } from './issue'; +import { IssueProviderKey } from './issue'; import { JiraIssueContentComponent } from './jira/jira-issue/jira-issue-content/jira-issue-content.component'; import { JiraIssueHeaderComponent } from './jira/jira-issue/jira-issue-header/jira-issue-header.component'; @@ -10,15 +7,7 @@ import { JiraIssueHeaderComponent } from './jira/jira-issue/jira-issue-header/ji providedIn: 'root' }) export class IssueService { - public issueEntityMap$: Observable = combineLatest( - this._jiraIssueService.jiraIssuesEntities$ - ).pipe(map(([jiraEntities]) => { - return { - JIRA: jiraEntities - }; - })); - - constructor(private _jiraIssueService: JiraIssueService) { + constructor() { } public getTabHeader(issueType: IssueProviderKey) { diff --git a/src/app/issue/jira/jira-issue/store/jira-issue.reducer.ts b/src/app/issue/jira/jira-issue/store/jira-issue.reducer.ts index 830de54..dd80fa8 100644 --- a/src/app/issue/jira/jira-issue/store/jira-issue.reducer.ts +++ b/src/app/issue/jira/jira-issue/store/jira-issue.reducer.ts @@ -3,8 +3,9 @@ import { JiraIssueActions, JiraIssueActionTypes } from './jira-issue.actions'; import { JiraIssue } from '../jira-issue.model'; import { createFeatureSelector, createSelector } from '@ngrx/store'; import { TaskActionTypes } from '../../../../tasks/store/task.actions'; +import { IssueProviderKey } from '../../../issue'; -export const JIRA_ISSUE_FEATURE_NAME = 'issues'; +export const JIRA_ISSUE_FEATURE_NAME: IssueProviderKey = 'JIRA'; export interface JiraIssueState extends EntityState { // additional entities state properties @@ -13,7 +14,6 @@ export interface JiraIssueState extends EntityState { export const jiraIssueAdapter: EntityAdapter = createEntityAdapter(); - // SELECTORS // --------- export const selectJiraIssueFeatureState = createFeatureSelector(JIRA_ISSUE_FEATURE_NAME); diff --git a/src/app/tasks/add-task-bar/add-task-bar.component.ts b/src/app/tasks/add-task-bar/add-task-bar.component.ts index 2defc90..ebefcb5 100644 --- a/src/app/tasks/add-task-bar/add-task-bar.component.ts +++ b/src/app/tasks/add-task-bar/add-task-bar.component.ts @@ -70,7 +70,7 @@ export class AddTaskBarComponent implements OnInit, OnDestroy { console.log(issueOrTitle); if (typeof issueOrTitle === 'string') { - this._taskService.add(issueOrTitle,true); + this._taskService.add(issueOrTitle); } else { this._taskService.addWithIssue( issueOrTitle.summary, diff --git a/src/app/tasks/store/task.reducer.ts b/src/app/tasks/store/task.reducer.ts index 1f3289d..3816e1b 100644 --- a/src/app/tasks/store/task.reducer.ts +++ b/src/app/tasks/store/task.reducer.ts @@ -3,6 +3,8 @@ import { TaskActions, TaskActionTypes } from './task.actions'; import { Task } from '../task.model'; import { createFeatureSelector, createSelector } from '@ngrx/store'; import { calcTotalTimeSpent } from '../util/calc-total-time-spent'; +import { selectIssueEntityMap } from '../../issue/issue.selector'; +import { tasks } from 'googleapis/build/src/apis/tasks'; export const TASK_FEATURE_NAME = 'tasks'; @@ -23,25 +25,53 @@ export interface TaskState extends EntityState { export const taskAdapter: EntityAdapter = createEntityAdapter(); +const mapIssueDataToTask = (tasks_, issueEntityMap) => { + return tasks_ && tasks_.map((task) => { + const issueData = (task.issueId && task.issueType) && issueEntityMap[task.issueType][task.issueId]; + return issueData ? {...task, issueData: issueData} : task; + }); +}; + +const mapSubTasksToTasks = (tasks__) => { + return tasks__.filter((task) => !task.parentId) + .map((task) => { + if (task.subTaskIds && task.subTaskIds.length > 0) { + return { + ...task, + subTasks: task.subTaskIds + .map((subTaskId) => { + return tasks__.find((task_) => task_.id === subTaskId); + }) + // filter out undefined + // .filter((subTask) => !!subTask) + }; + } else { + return task; + } + }); +}; + +const mapTasksFromIds = (tasks__, ids) => { + return ids.map(id => tasks__.find(task => task.id === id)); +}; // SELECTORS // --------- +const {selectIds, selectEntities, selectAll, selectTotal} = taskAdapter.getSelectors(); export const selectTaskFeatureState = createFeatureSelector(TASK_FEATURE_NAME); +export const selectBacklogTaskIds = createSelector(selectTaskFeatureState, state => state.backlogTaskIds); +export const selectTodaysTaskIds = createSelector(selectTaskFeatureState, state => state.todaysTaskIds); +export const selectCurrentTask = createSelector(selectTaskFeatureState, state => state.currentTaskId); -const {selectIds, selectEntities, selectAll, selectTotal} = taskAdapter.getSelectors(); export const selectAllTasks = createSelector(selectTaskFeatureState, selectAll); +export const selectAllTasksWithIssueData = createSelector(selectAllTasks, selectIssueEntityMap, mapIssueDataToTask); -// export const selectAllTasksWithIssueData = createSelector((state) => { -// const tasks = state[TASK_FEATURE_NAME]; -// const issues = state[JIRA_ISSUE_FEATURE_NAME]; -// return state.tasks; -// }); -// const selectBacklogTasks = createSelector(selectTaskFeatureState, (state) => state.backlogTaskIds.map(id => state.entities[id])); +export const selectAllTasksWithSubTasks = createSelector(selectAllTasksWithIssueData, mapSubTasksToTasks); -export const selectCurrentTask = createSelector(selectTaskFeatureState, state => state.currentTaskId); -export const selectBacklogTaskIds = createSelector(selectTaskFeatureState, state => state.backlogTaskIds); -export const selectTodaysTaskIds = createSelector(selectTaskFeatureState, state => state.todaysTaskIds); +export const selectTodaysTasksWithSubTasks = createSelector(selectAllTasksWithSubTasks, selectTodaysTaskIds, mapTasksFromIds); + +export const selectBacklogTasksWithSubTasks = createSelector(selectAllTasksWithSubTasks, selectBacklogTaskIds, mapTasksFromIds); // REDUCER diff --git a/src/app/tasks/task.service.ts b/src/app/tasks/task.service.ts index 678ea3f..5961023 100644 --- a/src/app/tasks/task.service.ts +++ b/src/app/tasks/task.service.ts @@ -5,7 +5,13 @@ import { Task, TaskWithSubTasks } from './task.model'; import { select, Store } from '@ngrx/store'; import { TaskActionTypes } from './store/task.actions'; import shortid from 'shortid'; -import { initialTaskState, selectAllTasks, selectCurrentTask } from './store/task.reducer'; +import { + initialTaskState, + selectAllTasksWithSubTasks, + selectBacklogTasksWithSubTasks, + selectCurrentTask, + selectTodaysTasksWithSubTasks, +} from './store/task.reducer'; import { ProjectService } from '../project/project.service'; import { PersistenceService } from '../core/persistence/persistence.service'; import { IssueService } from '../issue/issue.service'; @@ -13,48 +19,17 @@ import { IssueProviderKey } from '../issue/issue'; import { TimeTrackingService } from '../core/time-tracking/time-tracking.service'; import { Tick } from '../core/time-tracking/time-tracking'; -const mapIssueDataToTasks = map(([tasks, issueEntityMap]) => tasks.map((task) => { - const issueData = (task.issueId && task.issueType) && issueEntityMap[task.issueType][task.issueId]; - return issueData ? {...task, issueData: issueData} : task; -})); - -const mapSubTasksToTasks = map(tasks => { - return tasks.filter((task) => !task.parentId) - .map((task) => { - if (task.subTaskIds && task.subTaskIds.length > 0) { - return { - ...task, - subTasks: task.subTaskIds - .map((subTaskId) => { - return tasks.find((task_) => task_.id === subTaskId); - }) - // filter out undefined - // .filter((subTask) => !!subTask) - }; - } else { - return task; - } - }); -}); - @Injectable() export class TaskService { currentTaskId$: Observable = this._store.pipe(select(selectCurrentTask)); - tasks$: Observable = combineLatest( - this._store.pipe(select(selectAllTasks)), - this._issueService.issueEntityMap$ - ).pipe(mapIssueDataToTasks, mapSubTasksToTasks); + tasks$: Observable = this._store.pipe(select(selectAllTasksWithSubTasks)); - backlogTasks$: Observable = - this.tasks$.pipe(map( - (tasks) => tasks && tasks.filter((task: TaskWithSubTasks) => task.isBacklogTask) - )); + todaysTasks$: Observable = this._store.pipe(select(selectTodaysTasksWithSubTasks)); + + backlogTasks$: Observable = this._store.pipe(select(selectBacklogTasksWithSubTasks)); - todaysTasks$: Observable = this.tasks$.pipe(map( - (tasks) => tasks && tasks.filter((task: TaskWithSubTasks) => !task.isBacklogTask) - )); undoneTasks$: Observable = this.todaysTasks$.pipe(map( (tasks) => tasks && tasks.filter((task: TaskWithSubTasks) => !task.isDone) @@ -104,7 +79,7 @@ export class TaskService { private readonly _persistenceService: PersistenceService, private readonly _timeTrackingService: TimeTrackingService, ) { - // this.test$.subscribe((val) => console.log(val)); + this.todaysTasks$.subscribe((val) => console.log(val)); this.missingIssuesForTasks$.subscribe((val) => { if (val && val.length > 0) { console.error('MISSING ISSUE', val); @@ -156,7 +131,7 @@ export class TaskService { // Tasks // ----- - add(title: string, isAddToBacklog = true) { + add(title: string, isAddToBacklog = false) { this._store.dispatch({ type: TaskActionTypes.AddTask, payload: {