-
Notifications
You must be signed in to change notification settings - Fork 154
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* basic polling * btn placement, panel * fun with polling * mostly implemented * shimmer on loading * polling from config * pr feedback
- Loading branch information
1 parent
2093efa
commit 957b847
Showing
19 changed files
with
622 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
ui/app/src/components/shared/notifications/AddNotificationDemo.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import React, { useContext } from 'react'; | ||
import { Operation } from '../../../models/operation'; | ||
import { PrimaryButton } from '@fluentui/react'; | ||
import { NotificationsContext } from './NotificationsContext'; | ||
import dummyOp from './dummyOp.json'; | ||
import dummyOpSteps from './dummyOpSteps.json'; | ||
import { HttpMethod, ResultType, useAuthApiCall } from '../../../useAuthApiCall'; | ||
|
||
export const AddNotificationDemo: React.FunctionComponent = () => { | ||
const opsContext = useContext(NotificationsContext); | ||
const apiCall = useAuthApiCall(); | ||
|
||
const addSampleNotification = () => { | ||
let d = JSON.parse(JSON.stringify(dummyOp)) as Operation; // avoid reusing the same object | ||
console.log("adding test notification", d); | ||
opsContext.addOperation(d); | ||
} | ||
|
||
const addSampleNotificationWithSteps = () => { | ||
let d = JSON.parse(JSON.stringify(dummyOpSteps)) as Operation; // avoid reusing the same object | ||
console.log("adding test notification with steps", d); | ||
opsContext.addOperation(d); | ||
} | ||
|
||
const postDemoPatch = async () => { | ||
let body = { | ||
properties: { | ||
description: `Updated ${new Date().getTime()}` | ||
} | ||
} | ||
// patch "Jda VM" | ||
let op = await apiCall("workspaces/1e800001-7385-46a1-9f6d-490a6201ea01/workspace-services/8c70974a-5f66-4ae9-9502-7a54e9e0bb86/user-resources/8b6e42a0-e236-46ae-9541-01b462e4b468", HttpMethod.Patch, "816634e3-141d-4183-87a1-aaf2b95b7e12", body, ResultType.JSON, undefined, undefined, "*"); | ||
opsContext.addOperation(op.operation); | ||
} | ||
|
||
const postMultiStageVm = async () => { | ||
let body = { | ||
templateName: "tre-service-dev-vm", | ||
properties: { | ||
display_name: "my user resource", | ||
description: "some description" | ||
} | ||
} | ||
let op = await apiCall("workspaces/30314a30-ddf5-4b66-9854-fa580c00b54e/workspace-services/6fba7e63-96bd-4253-aacb-76f62137fd63/user-resources", HttpMethod.Post, "653a0b60-b798-401d-a6cb-3e824b6f4308", body, ResultType.JSON, undefined, undefined, "*"); | ||
opsContext.addOperation(op.operation); | ||
} | ||
|
||
return ( | ||
<> | ||
<h4>Notifications test harness</h4> | ||
<PrimaryButton onClick={() => addSampleNotification()}>Add Test Notification</PrimaryButton> | ||
<PrimaryButton onClick={() => addSampleNotificationWithSteps()}>Add Test Notification (with steps)</PrimaryButton> | ||
<PrimaryButton onClick={() => postDemoPatch()}>Patch a real VM</PrimaryButton> | ||
<PrimaryButton onClick={() => postMultiStageVm()}>Post a multi-step VM</PrimaryButton> | ||
</> | ||
); | ||
}; |
92 changes: 92 additions & 0 deletions
92
ui/app/src/components/shared/notifications/NotificationItem.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import React, { useState } from 'react'; | ||
import { Icon, ProgressIndicator, Link as FluentLink, Stack } from '@fluentui/react'; | ||
import { TRENotification } from '../../../models/treNotification'; | ||
import { completedStates, failedStates, inProgressStates, OperationStep } from '../../../models/operation'; | ||
import { Link } from 'react-router-dom'; | ||
import moment from 'moment'; | ||
import { useInterval } from './useInterval'; | ||
import { isNoSubstitutionTemplateLiteral } from 'typescript'; | ||
import { relative } from 'path'; | ||
|
||
interface NotificationItemProps { | ||
notification: TRENotification | ||
} | ||
|
||
export const NotificationItem: React.FunctionComponent<NotificationItemProps> = (props: NotificationItemProps) => { | ||
const [now, setNow] = useState(moment.utc()); | ||
const [isExpanded, setIsExpanded] = useState(false); | ||
|
||
const getRelativeTime = (createdWhen: number) => { | ||
return (moment.utc(moment.unix(createdWhen))).from(now); | ||
} | ||
|
||
// update the 'now' time for comparison - only while the item is rendered (panel is open) | ||
useInterval(() => { | ||
setNow(moment.utc()); | ||
}, 10000) | ||
|
||
const getIconAndColourForStatus = (status: string) => { | ||
if (failedStates.includes(status)) return ['ErrorBadge', 'red']; | ||
if (completedStates.includes(status)) return ['SkypeCheck', 'green']; | ||
if (status === "not_deployed") return ['Clock', '#cccccc']; | ||
return ['ProgressLoopInner', 'blue']; | ||
} | ||
|
||
return ( | ||
<li className="tre-notification-item"> | ||
{ | ||
inProgressStates.includes(props.notification.operation.status) ? | ||
<> | ||
<ProgressIndicator | ||
barHeight={4} | ||
label={<Link style={{ textDecoration: 'none', fontWeight: 'bold', color: 'blue' }} to={props.notification.operation.resourcePath}> | ||
{props.notification.resource.properties.display_name}: {props.notification.operation.action} | ||
</Link>} | ||
description={`${props.notification.resource.resourceType} is ${props.notification.operation.status}`} /> | ||
</> | ||
: | ||
<ProgressIndicator | ||
barHeight={4} | ||
percentComplete={100} | ||
label={ | ||
<Link style={{ textDecoration: 'none', fontWeight: 'bold', color: 'blue' }} to={props.notification.operation.resourcePath}> | ||
<Icon iconName={getIconAndColourForStatus(props.notification.operation.status)[0]} style={{ color: getIconAndColourForStatus(props.notification.operation.status)[1], position: 'relative', top: '2px', marginRight: '10px' }} /> | ||
{props.notification.resource.properties.display_name}: {props.notification.operation.action} | ||
</Link> | ||
} | ||
description={`${props.notification.resource.resourceType} is ${props.notification.operation.status}`} /> | ||
} | ||
<Stack horizontal style={{ marginTop: '10px' }}> | ||
<Stack.Item grow={5}> | ||
{ | ||
props.notification.operation.steps && props.notification.operation.steps.length > 0 && !(props.notification.operation.steps.length === 1 && props.notification.operation.steps[0].stepId === 'main') ? | ||
<FluentLink title={isExpanded ? 'Show less' : 'Show more'} href="#" onClick={() => { setIsExpanded(!isExpanded) }} style={{ position: 'relative', top: '2px' }}>{isExpanded ? <Icon iconName='ChevronUp' aria-label='Expand Steps' /> : <Icon iconName='ChevronDown' aria-label='Collapse Steps' />}</FluentLink> | ||
: | ||
' ' | ||
} | ||
</Stack.Item> | ||
<Stack.Item> <div className="tre-notification-time">{getRelativeTime(props.notification.operation.createdWhen)}</div></Stack.Item> | ||
</Stack> | ||
|
||
{ | ||
isExpanded && | ||
<> | ||
<ul className="tre-notifications-steps-list"> | ||
{props.notification.operation.steps && props.notification.operation.steps.map((s: OperationStep, i: number) => { | ||
return ( | ||
<li key={i}> | ||
<Icon iconName={getIconAndColourForStatus(s.status)[0]} style={{ color: getIconAndColourForStatus(s.status)[1], position: 'relative', top: '2px', marginRight: '10px' }} /> | ||
{ | ||
s.stepId === "main" ? | ||
<>{props.notification.resource.properties.display_name}: {props.notification.operation.action}</> : | ||
s.stepTitle | ||
} | ||
</li>) | ||
}) | ||
} | ||
</ul> | ||
</> | ||
} | ||
</li> | ||
); | ||
}; |
Oops, something went wrong.