Skip to content

Instantly share code, notes, and snippets.

@filipecrosk
Last active November 9, 2016 02:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save filipecrosk/f2c54336baa47a832269b6e1df02c74e to your computer and use it in GitHub Desktop.
Save filipecrosk/f2c54336baa47a832269b6e1df02c74e to your computer and use it in GitHub Desktop.
Reflexion Challenge
import Ember from 'ember';
const {
computed
} = Ember;
export default Ember.Component.extend({
patients: computed.mapBy('group', 'patient_name'),
groupPain: computed.mapBy('group', 'pain_value'),
highestPain: computed.max('groupPain'),
actions: {
removeItem() {
this.sendAction('removeGroup', this.get('group'));
},
goToItem() {
alert('Redirect user to another page');
}
}
});
import Ember from 'ember';
const {
computed
} = Ember;
export default Ember.Component.extend({
iconType: computed('notification.type', function() {
let type = this.get('notification.type');
switch ( type ) {
case 'assessment_needs_review':
return 'pencil-square-o';
case 'exercise_trouble':
return 'info';
case 'event_pain':
return 'exclamation-triangle';
default:
return 'info';
}
}),
actions: {
removeItem() {
this.sendAction('removeItem', this.get('notification'));
},
goToItem() {
alert('Redirect user to another page');
}
}
});
import Ember from 'ember';
const {
computed
} = Ember;
export default Ember.Component.extend({
groupedPain: computed('notifications.[]', function() {
let sessions = this.get('notifications').filterBy('type','event_pain');
let arr = {};
sessions.forEach(function(item){
if ( !arr[ item['therapy_session_id'] ] ){
arr[ item['therapy_session_id'] ] = [];
}
if ( !arr[ item['therapy_session_id'] ].includes(item) ){
arr[ item['therapy_session_id'] ].pushObject(item);
}
});
return arr;
}),
groupedAssessment: computed('notifications.[]', function() {
let sessions = this.get('notifications').filterBy('type','assessment_needs_review');
let arr = {};
sessions.forEach(function(item){
if ( !arr[ item['patient_id'] ] ){
arr[ item['patient_id'] ] = [];
}
if ( !arr[ item['patient_id'] ].includes(item) ){
arr[ item['patient_id'] ].pushObject(item);
}
});
return arr;
}),
groupedExerciseTrouble: computed.filterBy('notifications','type','exercise_trouble'),
actions: {
clearAll() {
this.sendAction('clearAll');
},
removeItem(item) {
this.sendAction('removeItem', item);
},
removeGroup(group) {
this.sendAction('removeGroup', group);
}
}
});
import Ember from 'ember';
const {
computed
} = Ember;
export default Ember.Component.extend({
patients: computed.mapBy('group', 'patient_name'),
groupPain: computed.mapBy('group', 'pain_value'),
highestPain: computed.max('groupPain'),
actions: {
removeItem() {
this.sendAction('removeGroup', this.get('group'));
},
goToItem() {
alert('Redirect user to another page');
}
}
});
import Ember from 'ember';
export default Ember.Controller.extend({
appName: 'Ember Twiddle'
});
import Ember from 'ember';
const { computed } = Ember;
export default Ember.Controller.extend({
hasNotifications: computed.gt('model.length', 0),
showNotifications: false,
actions: {
toggleNotifications() {
this.toggleProperty('showNotifications');
},
clearAll() {
this.get('model').clear();
this.send('toggleNotifications');
},
removeItem(item) {
console.log('log item', item);
this.get('model').removeObject(item);
},
removeGroup(group) {
let groupIds = group.mapBy('id');
let model = this.get('model');
console.log('log - ids to remove', groupIds);
group.forEach(function(item) {
console.log('log - item', item);
model.removeObject(item);
});
}
}
});
import Ember from 'ember';
export default Ember.Helper.helper(function([date, format]){
/*if (typeof(date) === "string") {
if (date === "") {
date = new Date();
} else {
date = moment(date, ["MM/DD/YYYY", "YYYY-MM-DD", "hh:mm:ss"]);
}
}
return moment(date).format(format);*/
return date;
});
import Ember from 'ember';
var pluralize = Ember.String.pluralize;
export default Ember.Helper.helper(function([count, word, options]){
if ( Ember.isNone(word) ){
return;
}
if (count !== 1) {
count = count || 0;
word = pluralize(word);
}
return ( options !== 'omitCount' ? count + ' ' : '') + word;
});
import Ember from 'ember';
import config from './config/environment';
const Router = Ember.Router.extend({
location: 'none',
rootURL: config.rootURL
});
Router.map(function() {
});
export default Router;
import Ember from 'ember';
export default Ember.Route.extend({
model: () => {
return [{
id: "bb0bc339-1f49-4634-8e3c-a2328fe27043",
timestamp: "2016-03-23T11:50:39.000-07:00",
type: "assessment_needs_review",
patient_id: "3449eb26-8f38-4c3c-a3cb-b7eb7b43d23d",
patient_name: "Ash Test",
assigned_id: "a1c6accb-512e-47e5-a18a-89d3a73a8b29",
template_id: "1b3bbae0-92f7-4137-9383-ea0575f8ba23",
test_name: "Sit to Stand Test",
test_session_id: "a73bb2bb-8d4e-4bdf-bb44-1043e07d343b",
therapy_session_id: "bd490377-d175-4043-ac9e-e7f5ca789921",
message: "Sit to Stand Test test is ready to review"
}, {
id: "d7da87b0-6b01-4c3e-adc0-5a40ecede260",
timestamp: "2016-03-23T11:53:32.000-07:00",
type: "assessment_needs_review",
patient_id: "3449eb26-8f38-4c3c-a3cb-b7eb7b43d23d",
patient_name: "Ash Test",
assigned_id: "a1c6accb-512e-47e5-a18a-89d3a73a8b29",
template_id: "1b3bbae0-92f7-4137-9383-ea0575f8ba23",
test_name: "Sit to Stand Test",
test_session_id: "d09825a3-f4ff-42e7-aaaa-965bd4ba87a5",
therapy_session_id: "626967cf-ec92-4e33-9128-1acfe954b6c0",
message: "Sit to Stand Test test is ready to review"
},
{
id: "d950e650-3aef-457b-a679-cadd4debe142",
timestamp: "2016-03-24T10:52:16.000-04:00",
type: "event_pain",
patient_id: "9baa28b2-08b9-4726-bb6d-549849fa1f94",
patient_name: "Toby O",
exercise_session_id: "18a588a7-0f14-4443-9090-19d5826374c6",
therapy_session_id: "6b9a8e0d-aca5-4d2e-ad84-c75d11362a47",
therapy_plan_id: "be5a1401-596d-4cb2-b5cd-7b2387ac3afe",
pain_value: 2,
message: "Reported pain level 2"
}, {
id: "f419e36f-c3a7-4eec-81eb-04163de1d25d",
timestamp: "2016-03-24T11:02:46.000-04:00",
type: "event_pain",
patient_id: "9baa28b2-08b9-4726-bb6d-549849fa1f94",
patient_name: "Toby O",
exercise_session_id: "919fe9e7-73b8-404d-ad69-b1b3e740e826",
therapy_session_id: "6b9a8e0d-aca5-4d2e-ad84-c75d11362a47",
therapy_plan_id: "be5a1401-596d-4cb2-b5cd-7b2387ac3afe",
pain_value: 10,
message: "Reported pain level 10"
}, {
id: "d531b4d8-410e-4a26-b18d-209123299e72",
timestamp: "2016-03-24T11:04:04.000-04:00",
type: "exercise_trouble",
patient_id: "9baa28b2-08b9-4726-bb6d-549849fa1f94",
patient_name: "Toby O",
exercise_session_id: "db4d51a5-76ab-41b6-9b1a-80be1f267310",
therapy_session_id: "6b9a8e0d-aca5-4d2e-ad84-c75d11362a47",
therapy_plan_id: "be5a1401-596d-4cb2-b5cd-7b2387ac3afe",
exercise_name: "Alternating Shallow Lunge",
message: "Had trouble with Alternating Shallow Lunge"
}, {
id: "c426bba6-69b7-4489-b5a6-3aec0b6c437f",
timestamp: "2016-03-24T11:25:07.000-04:00",
type: "exercise_trouble",
patient_id: "9baa28b2-08b9-4726-bb6d-549849fa1f94",
patient_name: "Toby O",
exercise_session_id: "81cd0656-092e-4c6e-a63d-46bd6dc37e9f",
therapy_session_id: "90e2998e-7010-42a8-a081-a01ace67d458",
therapy_plan_id: "92542542-aff3-4a33-81e2-aba9519d7bf4",
exercise_name: "Deep Squat",
message: "Had trouble with Deep Squat"
}, {
id: "7573bef2-d1ab-4f26-940e-2a5fdc2cfc50",
timestamp: "2016-03-24T10:11:42.000-07:00",
type: "exercise_trouble",
patient_id: "fa129eea-e803-40c0-a82f-c77ebeb7aae2",
patient_name: "Ash Test3",
exercise_session_id: "9ce46e48-e7aa-48df-82d9-567adc0b8037",
therapy_session_id: "d387c29b-0191-46d2-82d9-b098c348cd63",
therapy_plan_id: "c50d543a-6ab1-4051-99f3-d79e3ccb366d",
exercise_name: "Deep Squat",
message: "Had trouble with Deep Squat"
}, {
id: "c27340e4-25d9-428b-b5bf-a20f684559e8",
timestamp: "2016-03-24T13:25:34.000-04:00",
type: "event_pain",
patient_id: "9baa28b2-08b9-4726-bb6d-549849fa1f94",
patient_name: "Toby O",
exercise_session_id: "a4aad04e-e59a-453f-8cd4-2ce22bf08d45",
therapy_session_id: "27bf8b26-fef7-4923-b476-fb7c5934ad14",
therapy_plan_id: "4490c789-83f5-4b21-b6f1-9cf69ec27224",
pain_value: 10,
message: "Reported pain level 10"
}, {
id: "4dcedd7a-c21d-4d21-b514-20ef91afb509",
timestamp: "2016-03-25T09:19:16.000-07:00",
type: "exercise_trouble",
patient_id: "8ca9e942-d895-40a6-92d1-6cb3cc626b38",
patient_name: "A Patient",
exercise_session_id: "86c578de-b2bf-474e-927d-ddafacf8e6ef",
therapy_session_id: "898bcd0a-ff42-4170-969c-fbc273a36102",
therapy_plan_id: "182df1ce-5df7-416c-b179-8cf3de8c3c56",
exercise_name: "Single Leg Balance",
message: "Had trouble with Single Leg Balance"
}, {
id: "dcdf7a78-f227-434e-8cab-c4715d4127a4",
timestamp: "2016-04-01T11:40:46.000-07:00",
type: "assessment_needs_review",
patient_id: "c3fcbdbd-62f8-49e9-9db9-048b2af9f962",
patient_name: "Richard Hicks",
assigned_id: "74d7404b-cd22-414f-a472-44cd55fee431",
template_id: "0a2586f3-6e8d-4e12-a725-3a059a8e0006",
test_name: "Knee Extension Test",
test_session_id: "fddd6f0c-cdb8-4ed5-8f50-c314ed957b6c",
therapy_session_id: "9d3b0305-95d5-4931-8f4f-02db01d928dd",
message: "Knee Extension Test test is ready to review"
}];
}
});
@import 'https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css';
body {
padding: 0;
margin: 0;
font-family: "Helvetica Neue", Helvetica, sans-serif;
background-color: #fff;
}
header {
background-color: #2d4d6d
}
nav {
width: 1024px;
margin: 0 auto;
}
.nav-list {
list-style-type: none;
margin: 0;
padding: 0;
}
.nav-list-item {
color: white;
display: inline-block;
padding: 25px;
}
.search {
background-color: #1d324a;
}
.notifications {
padding: inherit;
}
.clinician-name {
margin-right: 10px
}
/* utility classes*/
.right {
float: right;
}
.left {
float: left;
}
.group:before,
.group:after {
content: "";
display: table;
}
.group:after {
clear: both;
}
/* CUSTOM CODE */
.has-notifications {
position: relative;
}
.has-notifications:after{
content:" ";
position: absolute;
background: red;
height:0.5rem;
top:0;
right:0;
width:0.5rem;
border-radius: 50%;
}
.has-notifications .fa-bell-o {
cursor: pointer;
}
.notifications-show .notificationscenter {
visibility: visible; /* shows sub-menu */
opacity: 1;
z-index: 1;
transform: translateY(0%);
transition-delay: 0s, 0s, 0.3s;
}
.notificationscenter {
box-sizing: border-box;
position: absolute;
width: 250px;
background: #eff0f0;
top: 35px;
left: -220px;
height: auto;
max-height: 300px;
border: 1px solid #eff0f0;
padding: 10px;
transition: all 0.3s ease-in-out 0s, visibility 0s linear 0.3s, z-index 0s linear 0.01s;
visibility: hidden;
opacity: 0;
transform: translateY(-15em);
z-index: -1;
}
.notificationscenter:after, .notificationscenter:before {
bottom: 100%;
left: 92%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.notificationscenter:after {
border-color: rgba(204, 204, 204, 0);
border-bottom-color: #eff0f0;
border-width: 8px;
margin-left: -8px;
}
.notificationscenter:before {
border-color: rgba(191, 191, 191, 0);
border-bottom-color: #eff0f0;
border-width: 13px;
margin-left: -13px;
}
.notificationscenter__header {
display: flex;
margin-bottom: 10px;
line-height: 18px;
}
.notificationscenter__header h2 {
flex: 1;
font-size: 18px;
font-weight: normal;
text-align: center;
color: #2d4d6d;
margin: 0;
}
.notificationscenter__header a {
font-size: 12px;
color: #1fb0f8;
text-decoration: none;
}
.notificationscenter__list {
position: relative;
max-height: 250px;
overflow: auto;
}
.notificationscenter__item {
display: flex;
margin-bottom: 10px;
background: #FFF;
padding: 10px;
}
.notificationscenter__icon {
width: 30px;
height: 30px;
line-height: 30px;
text-align: center;
background: #eff0f0;
color: #FFF;
border-radius: 50%;
font-size: 16px;
box-sizing: border-box;
margin-right: 10px
}
.notificationscenter__item-assessment_needs_review .notificationscenter__icon {
background-color: #1fb0f8;
padding-left: 3px;
}
.notificationscenter__item-exercise_trouble .notificationscenter__icon {
background-color: #ffb003;
}
.notificationscenter__item-event_pain .notificationscenter__icon {
background-color: #fd571d;
}
.notificationscenter__close {
color: #999;
text-decoration: none;
font-size: 15px;
font-weight: bold;
}
.notificationscenter__content {
flex: 1;
}
.notificationscenter__content_title {
margin: 0;
font-weight: normal;
font-size: 15px;
margin-bottom: 5px;
}
.notificationscenter__item-assessment_needs_review .notificationscenter__content_title {
color: #1fb0f8;
}
.notificationscenter__item-exercise_trouble .notificationscenter__content_title {
color: #ffb003;
}
.notificationscenter__item-event_pain .notificationscenter__content_title {
color: #fd571d;
}
.notificationscenter__content_text {
color: #97a8bc;
font-size: 12px;
line-height: 15px;
margin-top: 0px;
margin-bottom: 5px;
}
.notificationscenter__content_data {
color: #d0d2d2;
font-size: 11px;
}
<div class="notificationscenter__item notificationscenter__item-assessment_needs_review">
<div class="notificationscenter__icon">
<i class="fa fa-pencil-square-o"></i>
</div>
<div class="notificationscenter__content" {{action "goToItem"}}>
<h3 class="notificationscenter__content_title">{{patients.lastObject}}</h3>
<p class="notificationscenter__content_text">
Has assessments ready to review
</p>
<span class="notificationscenter__content_data">{{h-moment group.lastObject.timestamp "MMMM DD \a\t h:mmA"}}</span>
</div>
<a href="#" class="notificationscenter__close" {{action "removeItem"}}>
x
</a>
</div>
<div class="notificationscenter__item notificationscenter__item-{{notification.type}}">
<div class="notificationscenter__icon">
<i class="fa fa-{{iconType}}"></i>
</div>
<div class="notificationscenter__content" {{action "goToItem"}}>
<h3 class="notificationscenter__content_title">{{notification.patient_name}}</h3>
<p class="notificationscenter__content_text">{{notification.message}}</p>
<span class="notificationscenter__content_data">{{h-moment notification.timestamp "MMMM DD \a\t h:mmA"}}</span>
</div>
<a href="#" class="notificationscenter__close" {{action "removeItem"}}>
x
</a>
</div>
<div class="notificationscenter">
<div class="notificationscenter__header">
<h2>Notifications</h2>
<a href="#" {{action "clearAll"}}>Clear All</a>
</div>
<div class="notificationscenter__list">
{{#each-in groupedPain as |therapy_session_id group|}}
{{notifications-pain group=group removeGroup=(action "removeGroup" group)}}
{{/each-in}}
{{#each-in groupedAssessment as |patient_id group|}}
{{notifications-assessment group=group removeGroup=(action "removeGroup" group)}}
{{/each-in}}
{{#each groupedExerciseTrouble as |notification|}}
{{notifications-item notification=notification removeItem=(action "removeItem")}}
{{/each}}
</div>
</div>
<div class="notificationscenter__item notificationscenter__item-event_pain">
<div class="notificationscenter__icon">
<i class="fa fa-exclamation-triangle"></i>
</div>
<div class="notificationscenter__content" {{action "goToItem"}}>
<h3 class="notificationscenter__content_title">{{patients.lastObject}}</h3>
<p class="notificationscenter__content_text">
Reported pain {{h-pluralize group.length "time"}} with highest pain {{highestPain}}
</p>
<span class="notificationscenter__content_data">{{h-moment group.lastObject.timestamp "MMMM DD \a\t h:mmA"}}</span>
</div>
<a href="#" class="notificationscenter__close" {{action "removeItem"}}>
x
</a>
</div>
<header>
<nav class="group">
<ul class="nav-list left">
<li class="nav-list-item search">
<i class="fa fa-search"></i>
</li>
<li class="nav-list-item">
<span>Patients</span>
</li>
<li class="nav-list-item">
<span>Protocols</span>
</li>
<li class="nav-list-item">
<span>Clinicians</span>
</li>
</ul>
<ul class="nav-list right">
<li class="nav-list-item notifications {{if hasNotifications "has-notifications"}} {{if showNotifications "notifications-show"}}">
<i class="fa fa-bell-o" {{action "toggleNotifications"}}></i>
{{#if model}}
{{notifications-list notifications=model clearAll=(action "clearAll") removeItem=(action "removeItem") removeGroup=(action "removeGroup")}}
{{/if}}
</li>
<li class="nav-list-item">
<span class="clinician-name">John Doe</span><i class="fa fa-chevron-down"></i>
</li>
</ul>
</nav>
</header>
import Ember from 'ember';
export default function destroyApp(application) {
Ember.run(application, 'destroy');
}
import Resolver from '../../resolver';
import config from '../../config/environment';
const resolver = Resolver.create();
resolver.namespace = {
modulePrefix: config.modulePrefix,
podModulePrefix: config.podModulePrefix
};
export default resolver;
import Ember from 'ember';
import Application from '../../app';
import config from '../../config/environment';
const { run } = Ember;
const assign = Ember.assign || Ember.merge;
export default function startApp(attrs) {
let application;
let attributes = assign({rootElement: "#test-root"}, config.APP);
attributes = assign(attributes, attrs); // use defaults, but you can override;
run(() => {
application = Application.create(attributes);
application.setupForTesting();
application.injectTestHelpers();
});
return application;
}
import resolver from './helpers/resolver';
import {
setResolver
} from 'ember-qunit';
setResolver(resolver);
{
"version": "0.10.6",
"EmberENV": {
"FEATURES": {}
},
"options": {
"use_pods": false,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.js",
"ember": "2.9.0",
"ember-data": "2.9.0",
"ember-template-compiler": "2.9.0",
"ember-testing": "2.9.0"
},
"addons": {
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment