-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implementing a button for Presence in the 2de kamer #891
base: staging
Are you sure you want to change the base?
Changes from all commits
c5c11e3
cbf40b0
1e529e9
265bb3c
968e36e
6ac2040
4e3722b
945c56d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { Ability } from 'ember-can'; | ||
|
||
export default class StudyRoomPresence extends Ability { | ||
get canShow() { | ||
return this.session.hasPermission('study-room-presence.read'); | ||
} | ||
|
||
get canCreate() { | ||
return this.session.hasPermission('study-room-presence.create'); | ||
} | ||
|
||
get canDestroy() { | ||
return this.session.hasPermission('study-room-presence.destroy'); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
<div class='room-presence-dropdown page-action'> | ||
<BsButton @type='primary'> | ||
<FaIcon @icon='book' /> | ||
<span class='d-none d-md-inline'>2de kamer</span> | ||
<span class='status-dot label-{{this.overallStatus}}'></span> | ||
|
||
<BsPopover | ||
{{!-- @triggerEvents='focus' --}} | ||
@placement='bottom' | ||
@title='Aanwezig in de 2de Kamer' | ||
@renderInPlace="{{true}}" | ||
> | ||
{{#each this.sortedPresences as |presence|}} | ||
<div class='py-1'> | ||
<div class='d-block'> | ||
<LinkTo @route='users.user' @model={{presence.user.id}}> | ||
<small><b>{{presence.user.fullNameWithNickname}}</b></small> | ||
</LinkTo> | ||
</div> | ||
<span class='presence-label label-{{presence.status}}'> | ||
{{t (concat 'component.tools.studyRoomPresence.' presence.status)}} | ||
van | ||
{{moment-format presence.startTime 'HH:mm'}} | ||
tot | ||
{{moment-format presence.endTime 'HH:mm'}} | ||
</span> | ||
</div> | ||
{{else}} | ||
<div>Er is niemand aanwezig</div> | ||
{{/each}} | ||
|
||
{{#if (can 'create study-room-presences')}} | ||
<span class='d-flex'> | ||
<button | ||
class='btn btn-secondary mb-2 mt-3 update-presence-button' | ||
{{on 'click' (fn this.setPresenceModalState 'open') }} | ||
type='button' | ||
> | ||
Aanwezigheid updaten | ||
</button> | ||
</span> | ||
{{/if}} | ||
</BsPopover> | ||
</BsButton> | ||
</div> | ||
|
||
{{#if presenceModalIsOpen}} | ||
<EmberWormhole @to='ember-wormhole-destination'> | ||
<BasicModal | ||
@title='2de kamer beschikbaarheid opgeven' | ||
@closeModal={{fn this.setPresenceModalState 'closed'}} | ||
@onSubmit={{this.save}} | ||
@submitText='Beschikbaarheid opslaan' | ||
@submitDisabled={{saveButtonDisabled}} | ||
> | ||
{{#if this.sortedPresences}} | ||
<table class='table edit-presence'> | ||
<thead> | ||
<tr> | ||
<th>Persoon</th> | ||
<th>Status</th> | ||
<th>Tot</th> | ||
<th></th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
{{#each this.sortedPresences as |presence|}} | ||
<tr class="edit-presence-row"> | ||
<td>{{presence.user.fullNameWithNickname}}</td> | ||
<td> | ||
{{t | ||
(concat 'component.tools.studyRoomPresence.' presence.status) | ||
}} | ||
</td> | ||
<td> {{moment-format presence.endTime 'HH:mm'}} </td> | ||
<td> | ||
{{#if (can 'destroy study-room-presences')}} | ||
<button | ||
class='btn btn-danger delete-presence-button float-end' | ||
aria-hidden='true' | ||
{{on 'click' this.deletePresence}} | ||
type='button' | ||
> | ||
<FaIcon @icon='trash' @size="xs" /> | ||
</button> | ||
{{/if}} | ||
</td> | ||
</tr> | ||
{{/each}} | ||
</tbody> | ||
</table> | ||
{{else}} | ||
<div class='alert alert-info'>Er zijn geen alphanen aanwezig</div> | ||
{{/if}} | ||
|
||
{{#if (can 'create board-room-presences')}} | ||
{{#if this.currentUserPresence}} | ||
<label for="new-user-presence-status">Status</label> | ||
<Input::SelectInput | ||
@class='form-control col-xs-12 presence-select' | ||
@required={{true}} | ||
@options={{statusOptions}} | ||
@placeholder={{Status}} | ||
@value={{this.currentUserPresence.status}} | ||
@id="new-user-presence-status" | ||
/> | ||
<label for="new-user-presence-starttime" class="mt-2">Van</label> | ||
<Input::TimeInput | ||
@dateValue={{this.currentUserPresence.startTime}} | ||
@class='col-xs-12 presence-time-input' | ||
@inputClass='form-control' | ||
@placeholder={{this.currentUserPresence.startTime}} | ||
@required={{true}} | ||
@id="new-user-presence-starttime" | ||
/> | ||
<label for="new-user-presence-endtime" class="mt-2">Tot</label> | ||
<Input::TimeInput | ||
@dateValue={{this.currentUserPresence.endTime}} | ||
@class='col-xs-12 presence-time-input' | ||
@inputClass='form-control' | ||
@placeholder={{this.currentUserPresence.endTime}} | ||
@required={{true}} | ||
@id="new-user-presence-endtime" | ||
/> | ||
{{else}} | ||
<button | ||
class='btn btn-secondary' | ||
{{on 'click' this.newPresence}} | ||
type='button' | ||
> | ||
Nieuw | ||
</button> | ||
{{/if}} | ||
{{/if}} | ||
</BasicModal> | ||
</EmberWormhole> | ||
{{/if}} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this component is written in the old style, please follow the new octane component style. There are a lot of examples that use glimmer components already specifically, you can take example from https://github.com/csvalpha/amber-ui/pull/635/files#diff-b264f9e9a3db1a61c4d3c4c38a3c454a93a33286c5d2b1e820513bc9d4986084 where I've rewritten the board-room-presence component |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
import { dropTask, restartableTask, timeout } from 'ember-concurrency'; | ||
import Component from '@glimmer/component'; | ||
// import Ember from 'ember'; | ||
import { action } from '@ember/object'; | ||
import moment from 'moment'; | ||
import { inject as service } from '@ember/service'; | ||
import { tracked } from '@glimmer/tracking'; | ||
import Ember from 'ember'; | ||
|
||
export default class BoardRoomPresence extends Component { | ||
@service session; | ||
@service store; | ||
@service abilities; | ||
|
||
@tracked presenceModalIsOpen = false; | ||
@tracked model = []; | ||
@tracked newCurrentUserPresence = null; | ||
|
||
statusOptions = [ | ||
{ | ||
value: 'chilling', | ||
label: 'Chillen', | ||
}, | ||
{ | ||
value: 'studying', | ||
label: 'Studeren', | ||
}, | ||
{ | ||
value: 'banaan', | ||
label: 'Banaan', | ||
}, | ||
]; | ||
|
||
@dropTask({ cancelOn: 'didInsertElement' }) *poll() { | ||
while (!Ember.testing) { | ||
yield this.fetchData.perform(); | ||
yield timeout(1000 * 30); // Wait 30 seconds | ||
} | ||
} | ||
|
||
@restartableTask *fetchData() { | ||
/* eslint-disable camelcase */ | ||
this.model = yield this.store.query('study-room-presence', { | ||
filter: { current_and_future: true }, | ||
}); | ||
/* eslint-enable camelcase */ | ||
} | ||
|
||
constructor() { | ||
super(...arguments); | ||
this.poll.perform(); | ||
} | ||
|
||
get currentUserPresence() { | ||
if (this.newCurrentUserPresence) { | ||
return this.newCurrentUserPresence; | ||
} | ||
return ( | ||
this.model.filter((presence) => presence.user.get('isCurrentUser'))[0] || | ||
null | ||
); | ||
} | ||
|
||
set currentUserPresence(presence) { | ||
this.newCurrentUserPresence = presence; | ||
} | ||
|
||
get sortedPresences() { | ||
return this.model.sortBy('endTime'); | ||
} | ||
|
||
get overallStatus() { | ||
const currentStatusses = this.model | ||
.filter((presence) => { | ||
return moment().isBetween( | ||
moment(presence.get('startTime')), | ||
moment(presence.get('endTime')), | ||
'minute', | ||
'[)' | ||
); | ||
}) | ||
.mapBy('status'); | ||
|
||
if (currentStatusses.includes('chilling')) { | ||
return 'Chillen'; | ||
} | ||
|
||
if (currentStatusses.includes('studeren')) { | ||
return 'Studying'; | ||
} | ||
|
||
return 'banaan'; | ||
} | ||
|
||
get saveButtonDisabled() { | ||
return this.currentUserPresence === null; | ||
} | ||
|
||
@action | ||
setPresenceModalState(state) { | ||
this.presenceModalIsOpen = state === 'open'; | ||
} | ||
|
||
@action | ||
deletePresence() { | ||
this.currentUserPresence.destroyRecord().then(() => { | ||
this.currentUserPresence = null; | ||
}); | ||
} | ||
|
||
@action | ||
newPresence() { | ||
this.currentUserPresence = this.store.createRecord('board-room-presence', { | ||
startTime: moment().startOf('minute').toDate(), | ||
endTime: moment().startOf('minute').add(1, 'hours').toDate(), | ||
status: 'present', | ||
user: this.session.currentUser, | ||
}); | ||
} | ||
|
||
@action | ||
save() { | ||
const presence = this.currentUserPresence; | ||
const fetch = this.fetchData; | ||
presence.save().then(() => fetch.perform()); | ||
this.presenceModalIsOpen = false; | ||
} | ||
} | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import Model, { belongsTo, attr } from '@ember-data/model'; | ||
|
||
export default class StudyRoomPresence extends Model { | ||
// Properties | ||
@attr startTime; | ||
@attr endTime; | ||
@attr status; | ||
|
||
// Relations | ||
@belongsTo user; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please also write this template in octane style. Some quick rules (without regard for whether you followed these or not):
this.
i.e.this.property
orthis.someFunction
@
. So, if the parent component has passed an argument calledsomeArgument
, then we can refer to it in this template with@someArgument
.{{action}}
helper usage #635 and Refactor:{{action}}
helper usage, the sequel #896 for examples of what to write instead.please thoroughly familiarize yourself with #429 and the tutorials/guides/resources mentioned there.