diff --git a/src/app/doubtfire-angularjs.module.ts b/src/app/doubtfire-angularjs.module.ts
index 4855d04ad6..6340cf689d 100644
--- a/src/app/doubtfire-angularjs.module.ts
+++ b/src/app/doubtfire-angularjs.module.ts
@@ -74,13 +74,13 @@ import 'build/src/app/units/states/tasks/inbox/inbox.js';
import 'build/src/app/units/states/tasks/tasks.js';
import 'build/src/app/units/states/tasks/definition/definition.js';
import 'build/src/app/units/states/groups/groups.js';
-import 'build/src/app/units/states/states.js';
+import './units/states/states';
import 'build/src/app/units/states/edit/directives/unit-group-set-editor/unit-group-set-editor.js';
import 'build/src/app/units/states/edit/directives/unit-details-editor/unit-details-editor.js';
import 'build/src/app/units/states/edit/directives/unit-ilo-editor/unit-ilo-editor.js';
import 'build/src/app/units/states/edit/directives/directives.js';
import 'build/src/app/units/states/edit/edit.js';
-import 'build/src/app/units/states/index/index.js';
+import './units/states/index/index.module';
import 'build/src/app/units/states/students-list/students-list.js';
import 'build/src/app/units/states/analytics/analytics.js';
import 'build/src/app/common/filters/filters.js';
diff --git a/src/app/units/states/index/index.coffee b/src/app/units/states/index/index.coffee
deleted file mode 100644
index 69b9888ea5..0000000000
--- a/src/app/units/states/index/index.coffee
+++ /dev/null
@@ -1,50 +0,0 @@
-angular.module('doubtfire.units.states.index', [])
-
-#
-# Root state for units
-#
-.config(($stateProvider) ->
- $stateProvider.state 'units/index', {
- url: "/units/:unitId"
- abstract: true
- views:
- main:
- controller: "UnitsIndexStateCtrl"
- templateUrl: "units/states/index/index.tpl.html"
- data:
- pageTitle: "_Home_"
- roleWhitelist: ['Tutor', 'Convenor', 'Admin', 'Auditor']
- }
-)
-
-.controller("UnitsIndexStateCtrl", ($scope, $rootScope, $state, $stateParams, newUnitService, newProjectService, listenerService, globalStateService, newUserService, alertService) ->
- # Error - required unitId is missing!
- unitId = +$stateParams.unitId
- return $state.go('home') unless unitId
-
- globalStateService.onLoad () ->
- # Load assessing unit role
- $scope.unitRole = globalStateService.loadedUnitRoles.currentValues.find((unitRole) -> unitRole.unit.id == unitId)
-
- if (! $scope.unitRole?) && ( newUserService.currentUser.role == "Admin" || newUserService.currentUser.role == "Auditor" )
- $scope.unitRole = newUserService.adminOrAuditorRoleFor(newUserService.currentUser.role, unitId, newUserService.currentUser)
-
- # Go home if no unit role was found
- return $state.go('home') unless $scope.unitRole?
-
- globalStateService.setView("UNIT", $scope.unitRole)
-
- newUnitService.get(unitId).subscribe({
- next: (unit)->
- newProjectService.loadStudents(unit).subscribe({
- next: (students)->
- $scope.unit = unit
- error: (err)->
- alertService.error( "Error loading students: " + err, 8000)
- setTimeout((()-> $state.go('home')), 5000)
- })
- error: (err)->
- alertService.error( "Error loading unit: " + err, 8000)
- setTimeout((()-> $state.go('home')), 5000)
- })
-)
diff --git a/src/app/units/states/index/index.component.html b/src/app/units/states/index/index.component.html
new file mode 100644
index 0000000000..7a00cdf7d4
--- /dev/null
+++ b/src/app/units/states/index/index.component.html
@@ -0,0 +1,7 @@
+
+
+
+
{{ unit.name }}
+
+
+
diff --git a/src/app/units/states/index/index.component.scss b/src/app/units/states/index/index.component.scss
new file mode 100644
index 0000000000..fc971af160
--- /dev/null
+++ b/src/app/units/states/index/index.component.scss
@@ -0,0 +1,8 @@
+/*
+!! REQUIRED for index.component.html - dont delete !!
+
+.units-index-container {
+ future teams can extend styling
+}
+
+*/
\ No newline at end of file
diff --git a/src/app/units/states/index/index.component.ts b/src/app/units/states/index/index.component.ts
new file mode 100644
index 0000000000..f2c7e9cbcb
--- /dev/null
+++ b/src/app/units/states/index/index.component.ts
@@ -0,0 +1,106 @@
+import { Component, OnInit, OnDestroy } from '@angular/core';
+import { ActivatedRoute, Router } from '@angular/router';
+import { Subject } from 'rxjs';
+import { takeUntil } from 'rxjs/operators';
+import { UnitService } from '../../../api/services/unit.service';
+import { ProjectService } from '../../../api/services/project.service';
+import { GlobalStateService } from '../../../projects/states/index/global-state.service';
+import { UserService } from '../../../api/services/user.service';
+import { AlertService } from '../../../common/services/alert.service';
+
+@Component({
+ selector: 'app-units-index-state',
+ templateUrl: './index.component.html',
+ styleUrls: ['./index.component.scss'],
+})
+export class UnitsIndexStateComponent implements OnInit, OnDestroy {
+ unit: any;
+ unitRole: any;
+ private destroy$ = new Subject();
+
+ constructor(
+ private route: ActivatedRoute,
+ private router: Router,
+ private UnitService: UnitService,
+ private newProjectService: ProjectService,
+ private globalStateService: GlobalStateService,
+ private newUserService: UserService,
+ private alertService: AlertService
+ ) {}
+
+ ngOnInit(): void {
+ // Get unitId from route parameters
+ this.route.params.pipe(takeUntil(this.destroy$)).subscribe((params) => {
+ const unitId = +params['unitId'];
+ if (!unitId) {
+ this.router.navigate(['/home']);
+ return;
+ }
+ this.loadUnit(unitId);
+ });
+ }
+
+ private loadUnit(unitId: number): void {
+ this.globalStateService.onLoad(() => {
+ // Load assessing unit role
+ this.unitRole = this.globalStateService.loadedUnitRoles.currentValues.find(
+ (unitRole: any) => unitRole.unit.id === unitId
+ );
+
+ // Check for Admin or Auditor roles
+ if (
+ !this.unitRole &&
+ (this.newUserService.currentUser.role === 'Admin' ||
+ this.newUserService.currentUser.role === 'Auditor')
+ ) {
+ this.unitRole = this.newUserService.adminOrAuditorRoleFor(
+ this.newUserService.currentUser.role,
+ unitId,
+ this.newUserService.currentUser
+ );
+ }
+
+ // Go home if no unit role was found
+ if (!this.unitRole) {
+ this.router.navigate(['/home']);
+ return;
+ }
+
+ // REMOVED: this.globalStateService.setView(this.unit, this.unitRole);
+ // This line was causing the routing error
+
+ // Load unit and students
+ this.UnitService
+ .get(unitId)
+ .pipe(takeUntil(this.destroy$))
+ .subscribe({
+ next: (unit) => {
+ this.newProjectService
+ .loadStudents(unit)
+ .pipe(takeUntil(this.destroy$))
+ .subscribe({
+ next: () => {
+ this.unit = unit;
+ },
+ error: (err) => {
+ this.alertService.error(
+ 'Error loading students: ' + err,
+ 8000
+ );
+ setTimeout(() => this.router.navigate(['/home']), 5000);
+ },
+ });
+ },
+ error: (err) => {
+ this.alertService.error('Error loading unit: ' + err, 8000);
+ setTimeout(() => this.router.navigate(['/home']), 5000);
+ },
+ });
+ });
+ }
+
+ ngOnDestroy(): void {
+ this.destroy$.next();
+ this.destroy$.complete();
+ }
+}
diff --git a/src/app/units/states/index/index.module.ts b/src/app/units/states/index/index.module.ts
new file mode 100644
index 0000000000..7891f7fd1a
--- /dev/null
+++ b/src/app/units/states/index/index.module.ts
@@ -0,0 +1,15 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { UIRouterModule } from '@uirouter/angular';
+
+import { UnitsIndexStateComponent } from './index.component';
+import { unitsIndexState } from './index.state';
+
+@NgModule({
+ declarations: [UnitsIndexStateComponent],
+ imports: [
+ CommonModule,
+ UIRouterModule.forChild({ states: [unitsIndexState] }),
+ ],
+})
+export class UnitsIndexStateModule {}
diff --git a/src/app/units/states/index/index.state.ts b/src/app/units/states/index/index.state.ts
new file mode 100644
index 0000000000..27002edca1
--- /dev/null
+++ b/src/app/units/states/index/index.state.ts
@@ -0,0 +1,13 @@
+import { StateDeclaration } from '@uirouter/core';
+import { UnitsIndexStateComponent } from './index.component';
+
+export const unitsIndexState: StateDeclaration = {
+ name: 'units.index',
+ url: '/units/:unitId',
+ abstract: true,
+ component: UnitsIndexStateComponent,
+ data: {
+ pageTitle: '_Home_',
+ roleWhitelist: ['Student', 'Tutor', 'Convenor', 'Admin', 'Auditor'],
+ },
+} as any;
diff --git a/src/app/units/states/states.coffee b/src/app/units/states/states.coffee
deleted file mode 100644
index 6860c0f2a0..0000000000
--- a/src/app/units/states/states.coffee
+++ /dev/null
@@ -1,9 +0,0 @@
-angular.module('doubtfire.units.states', [
- # 'doubtfire.units.states.all'
- 'doubtfire.units.states.index'
- 'doubtfire.units.states.edit'
- 'doubtfire.units.states.tasks'
- 'doubtfire.units.states.groups'
- 'doubtfire.units.states.students'
- 'doubtfire.units.states.analytics'
-])
diff --git a/src/app/units/states/states.ts b/src/app/units/states/states.ts
new file mode 100644
index 0000000000..a7e45fcf6a
--- /dev/null
+++ b/src/app/units/states/states.ts
@@ -0,0 +1,37 @@
+import { NgModule } from '@angular/core';
+
+
+// Import all state modules
+import { UnitsIndexStateModule } from './index/index.module';
+
+
+// working on child components, will need to create components for the following to complete this migration
+/*
+import { UnitsEditStateModule } from './edit/edit.module';
+import { UnitsTasksStateModule } from './tasks/tasks.module';
+import { UnitsGroupsStateModule } from './groups/groups.module';
+import { UnitsStudentsStateModule } from './students/students.module';
+import { UnitsAnalyticsStateModule } from './analytics/analytics.module';
+import { UnitsPortfoliosStateModule } from './portfolios/portfolios.module';
+import { UnitsRolloverStateModule } from './rollover/rollover.module';
+*/
+
+
+@NgModule({
+ imports: [
+ UnitsIndexStateModule
+ /*,
+ UnitsEditStateModule,
+ UnitsTasksStateModule,
+ UnitsGroupsStateModule,
+ UnitsStudentsStateModule,
+ UnitsAnalyticsStateModule,
+ UnitsPortfoliosStateModule,
+ UnitsRolloverStateModule,
+ */
+ ],
+})
+export class UnitsStatesModule {}
+
+
+