diff --git a/SAS/TMSS/frontend/tmss_webapp/src/components/AuthComponent.js b/SAS/TMSS/frontend/tmss_webapp/src/components/AuthComponent.js index ea9ef18cd57c3770f679956b288b851e1fbe0404..39e2aaa41323917d7ca65c88034e5744d193d09e 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/components/AuthComponent.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/components/AuthComponent.js @@ -3,6 +3,8 @@ import { BrowserRouter as Router } from 'react-router-dom'; import { Redirect} from 'react-router-dom'; import Auth from '../authenticate/auth' import { Login } from '../authenticate/login'; +import AppLoader from '../layout/components/AppLoader'; +import { AppTopbar } from '../layout/components/AppTopbar'; class AuthComponent extends Component { @@ -36,7 +38,16 @@ class AuthComponent extends Component { <> { this.state.authenticated ? this.props.children: <> - {!this.state.isLoginProgress && + {this.state.isLoginProgress? + <> + <div className="layout-topbar clearfix auth-topbar"> + <span class="header-title">TMSS</span> + </div> + <div className="auth-load-content"> + <AppLoader /> + <h2>Authentication & Authorization in progress. Please wait.</h2> + </div> + </>: <Router basename={ "/" }> <Redirect to={{pathname: "/login"}} /> <Login onLogin={this.loggedIn} /> diff --git a/SAS/TMSS/frontend/tmss_webapp/src/layout/components/TopProgressBar.js b/SAS/TMSS/frontend/tmss_webapp/src/layout/components/TopProgressBar.js new file mode 100644 index 0000000000000000000000000000000000000000..2f8be827b941fc3a604053381f917344fe4e2a80 --- /dev/null +++ b/SAS/TMSS/frontend/tmss_webapp/src/layout/components/TopProgressBar.js @@ -0,0 +1,9 @@ +import { ProgressBar } from "primereact/progressbar"; + +export default () => { + return ( + <div style={{marginTop: "-10px", marginBottom: "10px"}}> + <ProgressBar mode="indeterminate" style={{ height: '2px' }}/> + </div> + ); +} \ No newline at end of file diff --git a/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_auth.scss b/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_auth.scss new file mode 100644 index 0000000000000000000000000000000000000000..44842c604eb1b985ec4a67dc74f2fa8ea699017f --- /dev/null +++ b/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_auth.scss @@ -0,0 +1,9 @@ +.auth-topbar { + margin-top: -100px; +} + +.auth-load-content { + width: 100%; + text-align: center; + margin-top: 100px; +} \ No newline at end of file diff --git a/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_layout.scss b/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_layout.scss index a0f4e9f39658e0ded9ebd4c253e8ad0ae7b0f7ca..00fa0131c6b9232b347b5e08bd9a944c2dd832af 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_layout.scss +++ b/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_layout.scss @@ -2,6 +2,7 @@ @import "./_splash"; @import "./_main"; @import "./_topbar"; +@import "./_auth"; @import "./_sidebar"; @import "./_profile"; @import "./_menu"; diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/view.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/view.js index 0a22bca55a751f814a4314d31af5961caacf8660..aff69be4044cc441561ace5d5a7924dda522d96c 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/view.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/view.js @@ -25,6 +25,7 @@ import ReservationSummary from '../Reservation/reservation.summary'; import { TieredMenu } from 'primereact/tieredmenu'; import { MultiSelect } from 'primereact/multiselect'; import { Button } from 'primereact/button'; +import { ProgressBar } from 'primereact/progressbar'; import TimelineListTabs from './list.tabs'; import TimelineCommonUtils from './common.utils'; import AuthStore from '../../authenticate/auth.store'; @@ -33,6 +34,7 @@ import DynamicScheduler from '../../components/DynamicScheduler'; import TaskSummary from '../Task/summary'; import UnitConversion from '../../utils/unit.converter'; import { appGrowl } from '../../layout/components/AppGrowl'; +import TopProgressBar from '../../layout/components/TopProgressBar'; //import { TRUE } from 'node-sass'; // Color constant for SU status @@ -351,14 +353,18 @@ export class TimelineView extends Component { } // Set the selectedStationGroup if the previous selected station groups are stored const selectedStationGroup = this.timelineUIAttributes.stationGroups || _.keys(this.timelineCommonUtils.getMainStationGroups()); - const schedulingUnits = await this.getSchedulingUnits(defaultStartTime, defaultEndTime); this.setState({ - suBlueprints: schedulingUnits.original, suBlueprintList: schedulingUnits.formatted, - datasetStartTime: schedulingUnits.datasetStartTime, datasetEndTime: schedulingUnits.datasetEndTime, loader: false, taskTypes: taskTypes, currentUTC: currentUTC, isLoading: false, currentStartTime: defaultStartTime, currentEndTime: defaultEndTime, selectedStationGroup: selectedStationGroup, + isFetchingData: true + }); + const schedulingUnits = await this.getSchedulingUnits(defaultStartTime, defaultEndTime); + this.setState({ + suBlueprints: schedulingUnits.original, suBlueprintList: schedulingUnits.formatted, + datasetStartTime: schedulingUnits.datasetStartTime, datasetEndTime: schedulingUnits.datasetEndTime, + isFetchingData: false }); this.getUnschedulableUnits().then(unschedulableList => this.setState({unschedulableList: unschedulableList})); await this.dateRangeCallback(defaultStartTime, defaultEndTime, true); @@ -803,6 +809,7 @@ export class TimelineView extends Component { async dateRangeCallback(startTime, endTime, loadOldData) { let suBlueprints = this.state.suBlueprints; if (!loadOldData) { + this.setState({ isFetchingData: true }); suBlueprints = _.sortBy((await this.getSchedulingUnits(startTime, endTime)).original, 'start_time'); } let suBlueprintList = [], group = [], items = []; @@ -858,7 +865,8 @@ export class TimelineView extends Component { await this.setState({ suBlueprints: suBlueprints, suBlueprintList: _.filter(suBlueprintList, (suBlueprint) => { return suBlueprint.start_time != null }), - currentStartTime: startTime, currentEndTime: endTime + currentStartTime: startTime, currentEndTime: endTime, + isFetchingData: false }); // On range change close the Details pane // this.closeSummaryPanel(); @@ -1578,6 +1586,9 @@ export class TimelineView extends Component { { icon: 'fa-calendar-alt', title: 'Week View', props: { pathname: `/su/timelineview/week` } } ]} /> + {this.state.isFetchingData && + <TopProgressBar /> + } { this.state.isLoading ? <AppLoader /> : <div className="p-grid"> {/* SU List Panel */} diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/week.view.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/week.view.js index d0def4bf718c33e81efefd9b1da8bcd7ebe55369..c3b3b71fb58f839bad3850d5236b96f5a3327e4b 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/week.view.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/week.view.js @@ -33,6 +33,7 @@ import TimelineCommonUtils from './common.utils'; import ReservationService from '../../services/reservation.service'; import AuthUtil from '../../utils/auth.util'; import AuthStore from '../../authenticate/auth.store'; +import TopProgressBar from '../../layout/components/TopProgressBar'; // Color constant for status const STATUS_COLORS = { @@ -299,6 +300,14 @@ export class WeekTimelineView extends Component { const groupDate = defaultStartTime.clone().add(count, 'days'); group.push({ 'id': groupDate.format("MMM DD ddd"), title: groupDate.format("MMM DD - ddd"), value: groupDate }); } + this.setState({ + suBlueprints: [], suBlueprintList: [], + unschedulableList: [], + group: _.sortBy(group, ['value']), + items: items, currentUTC: currentUTC, isLoading: false, + startTime: defaultStartTime, endTime: defaultEndTime, + isFetchingData: true + }); const unschedulableList = await this.getUnschedulableUnits(); // Get all scheduling constraint templates ScheduleService.getSchedulingConstraintTemplates() @@ -306,11 +315,7 @@ export class WeekTimelineView extends Component { this.suConstraintTemplates = suConstraintTemplates; }); this.setState({ - suBlueprints: [], suBlueprintList: [], - unschedulableList: unschedulableList, - group: _.sortBy(group, ['value']), - items: items, currentUTC: currentUTC, isLoading: false, - startTime: defaultStartTime, endTime: defaultEndTime + unschedulableList: unschedulableList }); let updatedItemGroupData = await this.dateRangeCallback(defaultStartTime, defaultEndTime, true); this.timeline.updateTimeline(updatedItemGroupData); @@ -673,6 +678,7 @@ export class WeekTimelineView extends Component { let suBlueprintList = [], group = [], items = []; let currentUTC = this.state.currentUTC; if (refreshData) { + this.setState({isFetchingData: true}); const schedulingUnits = await this.getSchedulingUnits(startTime, endTime); suBlueprints = schedulingUnits.original; for (const count of _.range(11)) { @@ -716,7 +722,8 @@ export class WeekTimelineView extends Component { this.setState({ suBlueprints: suBlueprints, suBlueprintList: _.filter(suBlueprintList, (suBlueprint) => { return suBlueprint.start_time != null }), - group: group, items: items, currentUTC: currentUTC, startTime: startTime, endTime: endTime + group: group, items: items, currentUTC: currentUTC, startTime: startTime, endTime: endTime, + isFetchingData: false }); if (!this.state.datasetStartTime) { this.setState({datasetStartTime: schedulingUnits.datasetStartTime, @@ -1267,6 +1274,9 @@ export class WeekTimelineView extends Component { type: 'button', actOn: 'click', props: { callback: this.showDymanicSchedulerPopup }, }, { icon: 'fa-bars', title: '', type: 'button', actOn: 'mouseOver', props: { callback: this.showOptionMenu }, }, { icon: 'fa-clock', title: 'View Timeline', props: { pathname: `/su/timelineview` } }]} /> + {this.state.isFetchingData && + <TopProgressBar /> + } { this.state.isLoading ? <AppLoader /> : <> {/* <div className="p-field p-grid">