Skip to content
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

Open
wants to merge 8 commits into
base: staging
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions app/abilities/study-room-presence.js
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');

Check warning on line 5 in app/abilities/study-room-presence.js

View check run for this annotation

Codecov / codecov/patch

app/abilities/study-room-presence.js#L5

Added line #L5 was not covered by tests
}

get canCreate() {
return this.session.hasPermission('study-room-presence.create');

Check warning on line 9 in app/abilities/study-room-presence.js

View check run for this annotation

Codecov / codecov/patch

app/abilities/study-room-presence.js#L9

Added line #L9 was not covered by tests
}

get canDestroy() {
return this.session.hasPermission('study-room-presence.destroy');

Check warning on line 13 in app/abilities/study-room-presence.js

View check run for this annotation

Codecov / codecov/patch

app/abilities/study-room-presence.js#L13

Added line #L13 was not covered by tests
}
}
1 change: 1 addition & 0 deletions app/components/index/authenticated.hbs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<EmberWormhole @to='navbar-wormhole'>
<PageActionsButtons @pageActions={{pageActions}}>
<Tools::StudyRoomPresence />
<Tools::BoardRoomPresence />
</PageActionsButtons>
</EmberWormhole>
Expand Down
2 changes: 1 addition & 1 deletion app/components/tools/board-room-presence.hbs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class='board-room-presence-dropdown page-action'>
<div class='room-presence-dropdown page-action'>
<BsButton @type='primary'>
<FaIcon @icon='mug-saucer' />
<span class='d-none d-md-inline'>Bestuurskamer</span>
Expand Down
137 changes: 137 additions & 0 deletions app/components/tools/study-room-presence.hbs
Copy link
Contributor

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):

  • use angle bracket syntax for inserting components
  • refer to controller properties/functions with this. i.e. this.property or this.someFunction
  • refer to arguments passed to this component using @. So, if the parent component has passed an argument called someArgument, then we can refer to it in this template with @someArgument.
  • do not use the action helper anymore. see Refactor: {{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.

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}}
128 changes: 128 additions & 0 deletions app/components/tools/study-room-presence.js
Copy link
Contributor

Choose a reason for hiding this comment

The 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 = [

Check warning on line 19 in app/components/tools/study-room-presence.js

View check run for this annotation

Codecov / codecov/patch

app/components/tools/study-room-presence.js#L17-L19

Added lines #L17 - L19 were not covered by tests
{
value: 'chilling',

Check warning on line 21 in app/components/tools/study-room-presence.js

View check run for this annotation

Codecov / codecov/patch

app/components/tools/study-room-presence.js#L21

Added line #L21 was not covered by tests
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
}
}

Check warning on line 39 in app/components/tools/study-room-presence.js

View check run for this annotation

Codecov / codecov/patch

app/components/tools/study-room-presence.js#L37-L39

Added lines #L37 - L39 were not covered by tests

@restartableTask *fetchData() {
/* eslint-disable camelcase */
this.model = yield this.store.query('study-room-presence', {
filter: { current_and_future: true },
});

Check warning on line 45 in app/components/tools/study-room-presence.js

View check run for this annotation

Codecov / codecov/patch

app/components/tools/study-room-presence.js#L45

Added line #L45 was not covered by tests
/* eslint-enable camelcase */
}

constructor() {
super(...arguments);
this.poll.perform();
}

Check warning on line 53 in app/components/tools/study-room-presence.js

View check run for this annotation

Codecov / codecov/patch

app/components/tools/study-room-presence.js#L52-L53

Added lines #L52 - L53 were not covered by tests
get currentUserPresence() {
if (this.newCurrentUserPresence) {
return this.newCurrentUserPresence;
}
return (

Check warning on line 58 in app/components/tools/study-room-presence.js

View check run for this annotation

Codecov / codecov/patch

app/components/tools/study-room-presence.js#L57-L58

Added lines #L57 - L58 were not covered by tests
this.model.filter((presence) => presence.user.get('isCurrentUser'))[0] ||
null
);

Check warning on line 61 in app/components/tools/study-room-presence.js

View check run for this annotation

Codecov / codecov/patch

app/components/tools/study-room-presence.js#L60-L61

Added lines #L60 - L61 were not covered by tests
}

set currentUserPresence(presence) {
this.newCurrentUserPresence = presence;
}

Check warning on line 67 in app/components/tools/study-room-presence.js

View check run for this annotation

Codecov / codecov/patch

app/components/tools/study-room-presence.js#L67

Added line #L67 was not covered by tests
get sortedPresences() {
return this.model.sortBy('endTime');
}

Check warning on line 71 in app/components/tools/study-room-presence.js

View check run for this annotation

Codecov / codecov/patch

app/components/tools/study-room-presence.js#L71

Added line #L71 was not covered by tests
get overallStatus() {
const currentStatusses = this.model
.filter((presence) => {
return moment().isBetween(

Check warning on line 75 in app/components/tools/study-room-presence.js

View check run for this annotation

Codecov / codecov/patch

app/components/tools/study-room-presence.js#L75

Added line #L75 was not covered by tests
moment(presence.get('startTime')),
moment(presence.get('endTime')),

Check warning on line 77 in app/components/tools/study-room-presence.js

View check run for this annotation

Codecov / codecov/patch

app/components/tools/study-room-presence.js#L77

Added line #L77 was not covered by tests
'minute',
'[)'
);
})
.mapBy('status');

if (currentStatusses.includes('chilling')) {
return 'Chillen';
}

Check warning on line 87 in app/components/tools/study-room-presence.js

View check run for this annotation

Codecov / codecov/patch

app/components/tools/study-room-presence.js#L86-L87

Added lines #L86 - L87 were not covered by tests
if (currentStatusses.includes('studeren')) {
return 'Studying';
}

Check warning on line 91 in app/components/tools/study-room-presence.js

View check run for this annotation

Codecov / codecov/patch

app/components/tools/study-room-presence.js#L90-L91

Added lines #L90 - L91 were not covered by tests
return 'banaan';
}

Check warning on line 94 in app/components/tools/study-room-presence.js

View check run for this annotation

Codecov / codecov/patch

app/components/tools/study-room-presence.js#L94

Added line #L94 was not covered by tests
get saveButtonDisabled() {
return this.currentUserPresence === null;
}

Check warning on line 98 in app/components/tools/study-room-presence.js

View check run for this annotation

Codecov / codecov/patch

app/components/tools/study-room-presence.js#L98

Added line #L98 was not covered by tests
@action
setPresenceModalState(state) {
this.presenceModalIsOpen = state === 'open';
}

Check warning on line 103 in app/components/tools/study-room-presence.js

View check run for this annotation

Codecov / codecov/patch

app/components/tools/study-room-presence.js#L103

Added line #L103 was not covered by tests
@action
deletePresence() {
this.currentUserPresence.destroyRecord().then(() => {
this.currentUserPresence = null;
});
}

Check warning on line 109 in app/components/tools/study-room-presence.js

View check run for this annotation

Codecov / codecov/patch

app/components/tools/study-room-presence.js#L108-L109

Added lines #L108 - L109 were not covered by tests

@action
newPresence() {
this.currentUserPresence = this.store.createRecord('board-room-presence', {
startTime: moment().startOf('minute').toDate(),
endTime: moment().startOf('minute').add(1, 'hours').toDate(),

Check warning on line 115 in app/components/tools/study-room-presence.js

View check run for this annotation

Codecov / codecov/patch

app/components/tools/study-room-presence.js#L115

Added line #L115 was not covered by tests
status: 'present',
user: this.session.currentUser,
});
}

@action
save() {
const presence = this.currentUserPresence;
const fetch = this.fetchData;
presence.save().then(() => fetch.perform());
this.presenceModalIsOpen = false;
}
}

Check warning on line 128 in app/components/tools/study-room-presence.js

View check run for this annotation

Codecov / codecov/patch

app/components/tools/study-room-presence.js#L125-L128

Added lines #L125 - L128 were not covered by tests
11 changes: 11 additions & 0 deletions app/models/study-room-presence.js
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;
}
2 changes: 1 addition & 1 deletion app/styles/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
@import 'components/quickpost';
@import 'components/sidebar';
@import 'components/social-media-buttons';
@import 'components/tools/board-room-presence';
@import 'components/tools/room-presence';
@import 'components/tools/upcoming-birthdays';
@import 'components/tools/upcoming-activities';
@import 'components/tools/forum-tool';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
font-weight: bold;
}

.board-room-presence-dropdown {
.room-presence-dropdown {
color: $white;
}

Expand All @@ -26,6 +26,18 @@
background-color: $brand-danger;
}

.label-chilling {
background-color: $brand-success;
}

.label-studying {
background-color: $brand-warning;
}

.label-banaan {
background-color: $brand-success;
}

.edit-presence {
.edit-presence-row {
margin: 5px;
Expand Down
1 change: 1 addition & 0 deletions mirage/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export default function () {
this.resource('groups');
this.resource('quickpost_messages');
this.resource('board_room_presences');
this.resource('study_room_presences');
this.resource('photo_albums');
this.resource('photo_comments');
this.resource('photo_tags');
Expand Down
1 change: 1 addition & 0 deletions mirage/scenarios/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export default function (server) {
'article',
'article_comment',
'board_room_presence',
'study_room_presence',
'group',
'membership',
'photo_album',
Expand Down
4 changes: 4 additions & 0 deletions translations/en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,10 @@ component:
present: Present
busy: Busy
absent: Absent
studyRoomPresence:
chilling: Chilling
studying: Studying
banaan: Banaan
userComment:
anonymous: Anonymous user
mixin:
Expand Down
4 changes: 4 additions & 0 deletions translations/nl.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,10 @@ component:
present: Aanwezig
busy: Bezig
absent: Afwezig
studyRoomPresence:
chilling: Chillen
studying: Studeren
banaan: Banaan
userComment:
anonymous: Anonieme gebruiker
mixin:
Expand Down
Loading