Skip to content

Commit

Permalink
Merge pull request #84 from velrest/custom_reload_and_infopage
Browse files Browse the repository at this point in the history
Custom reload and infopage
  • Loading branch information
anehx authored Jul 6, 2018
2 parents 24441d6 + e3bf083 commit 1d952e9
Show file tree
Hide file tree
Showing 9 changed files with 351 additions and 29 deletions.
2 changes: 1 addition & 1 deletion backend/src/sysupport/proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const routes = {
subscriptionOrders: {
path: /^\/subscription-orders$/,
access: {
admin: ['GET', 'DELETE'],
admin: ['GET', 'DELETE', 'POST'],
customer: ['GET', 'POST']
}
},
Expand Down
9 changes: 7 additions & 2 deletions frontend/app/locales/de/translations.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ export default {
error:
'Bei der Verarbeitung Ihrer Bestellung ist ein Fehler aufgetreten. Bitte vergewissern Sie sich ob die Bestellung verarbeitet wurde und falls nicht, versuchen Sie es noch einmal.',
charge: 'Aufladen',
'error-loading':
'Die Bestellungen für dieses Projekt konten nicht geladen werden. Bitte versuchen Sie es erneut.',
noPackage: {
title: 'Es scheint als hätten Sie keine Pakete.',
text:
Expand All @@ -142,7 +144,7 @@ export default {

detail: {
expense: 'Aufwände',
charges: 'Aufladungen',
charges: 'Bestellungen',
effort: 'Aufwand',
employee: 'Mitarbeiter',
description: 'Beschreibung',
Expand All @@ -152,13 +154,16 @@ export default {
admin: {
subscriptions: 'Abonnements',
'confirm-subscription': 'Bestellung bestätigen',
reload: 'Aufladen',
customer: 'Kunde',
project: 'Projekt',
projects: 'Projekte',
billingType: 'Verrechnungs Art',
admin: 'Admin',
confirmSuccess: 'Bestellung akzeptiert.',
confirmDeny: 'Bestellung abgelehnt.'
confirmDeny: 'Bestellung abgelehnt.',
'reload-form-error': 'Bitte geben Sie nur valide Nummern ein.',
form: 'Anzahl Stunden/Minuten:'
}
},

Expand Down
7 changes: 6 additions & 1 deletion frontend/app/locales/en/translations.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ export default {
error:
'An error occured while processing your order. Please check if your order was saved and if not, try again.',
charge: 'Reload',
'error-loading':
"The orders for his project couldn't be loaded. Please try again.",
noPackage: {
title:
"It seems like there aren't any Subscription Packages available.",
Expand All @@ -150,13 +152,16 @@ export default {
admin: {
subscriptions: 'Subscriptions',
'confirm-subscription': 'Confirm subscriptions',
reload: 'Reload',
customer: 'Customer',
project: 'Project',
projects: 'Projects',
billingType: 'Billing Type',
admin: 'Admin',
confirmSuccess: 'Order accepted.',
confirmDeny: 'Order denied.'
confirmDeny: 'Order denied.',
'reload-form-error': 'Please enter only valid numbers',
form: 'Number of hours/minutes:'
}
},

Expand Down
114 changes: 114 additions & 0 deletions frontend/app/sysupport-admin/detail/controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import Controller from '@ember/controller'
import { computed } from '@ember/object'
import { inject as service } from '@ember/service'

import { task } from 'ember-concurrency'
import moment from 'moment'
import { hash } from 'rsvp'
import UIkit from 'UIkit'

export default Controller.extend({
i18n: service(),
notify: service(),

duration: computed('validation.{hour,minute}', 'hour', 'minute', function() {
if (this.get('validation.hour') || this.get('validation.minute')) {
return moment.duration({
hours: this.get('validation.hour') && this.hour,
minutes: this.get('validation.minute') && this.minute
})
}
}),

error: computed('validation.{hour,minute}', 'hour', 'minute', function() {
return (
(this.hour && !this.get('validation.hour')) ||
(this.minute && !this.get('validation.minute'))
)
}),

orders: computed('fetchModels.lastSuccessful.value', function() {
return (
this.get('fetchModels.lastSuccessful.value.orders') ||
this.get('model.orders')
)
}),

previewDuration: computed('duration', 'preview', function() {
return (
this.duration &&
this.preview &&
moment.duration(
this.get('project.purchasedTime') +
this.duration -
this.get('project.spentTime')
)
)
}),

project: computed('fetchModels.lastSuccessful.value', function() {
return (
this.get('fetchModels.lastSuccessful.value.project') ||
this.get('model.project')
)
}),

validation: computed('hour', 'minute', function() {
let validation = {
hour: Boolean(Number(this.hour)),
minute: Boolean(Number(this.minute))
}

if (validation.hour || validation.minute) {
this.set('preview', true)
}

return validation
}),

fetchModels: task(function*() {
try {
return yield hash({
orders: this.store.query('timed-subscription-order', {
project: this.get('model.project.id'),
ordering: '-ordered'
}),
project: this.store.findRecord(
'timed-subscription-project',
this.get('model.project.id'),
{
include: 'billing_type,customer'
}
)
})
} catch (e) {
this.notify.error(this.i18n.t('sysupport.reload.error-loading'))
}
}).drop(),

save: task(function*() {
try {
let order = this.store.createRecord('timed-subscription-order', {
duration: this.duration,
acknowledged: true,
project: this.get('project')
})
yield order.save()

this.notify.success(this.i18n.t('sysupport.reload.success'))
UIkit.accordion('[data-reload-acc]').toggle()
this.setProperties({ hour: null, minute: null })
} catch (e) {
this.notify.error(this.i18n.t('sysupport.reload.error'))
} finally {
this.fetchModels.perform()
this.set('preview', false)
}
}).drop(),

actions: {
saveOrder() {
this.save.perform()
}
}
})
77 changes: 59 additions & 18 deletions frontend/app/sysupport-admin/detail/template.hbs
Original file line number Diff line number Diff line change
@@ -1,35 +1,72 @@
<div class="uk-width-1-1 uk-margin uk-animation-slide-top-small">
<ul uk-accordion data-reload-acc>
<li>
<a data-test-reload-accordion class="uk-accordion-title" href="#">{{t 'sysupport.admin.reload'}} {{model.name}}</a>
<div class="uk-accordion-content">
<div class="uk-margin-left uk-flex uk-flex-middle uk-flex-between uk-flex-wrap">
<div class="uk-flex uk-flex-middle uk-flex-left uk-flex-wrap">
<span class="uk-text-large uk-margin-right">{{t 'sysupport.admin.form'}}</span>

<div class="uk-flex uk-flex-center uk-flex-middle uk-margin-right">
{{input
class=(concat "uk-text-center uk-input uk-form-width-small " (if hour (if validation.hour "uk-form-success" "uk-form-danger")))
type="number"
placeholder="Hours"
value=hour
data-test-hour-input=true}}
<span class="uk-margin-small-right uk-margin-small-left uk-text-large">:</span>
{{input
class=(concat "uk-text-center uk-input uk-form-width-small " (if minute (if validation.minute "uk-form-success" "uk-form-danger")))
type="number"
placeholder="Minutes"
value=minute
data-test-minute-input=true}}
{{#if error}}
<span class="uk-margin-left" data-test-reload-error>{{t 'sysupport.admin.reload-form-error'}}</span>
{{/if}}
</div>
</div>
{{uk-button loading=save.isRunning disabled=(or save.isRunning (or (not duration) error)) on-click=(action "saveOrder") label="Save" class="uk-button-primary" data-test-reload-submit=true}}
</div>
</div>
</li>
</ul>
</div>
<hr>
<div uk-grid class="uk-child-width-1-1 uk-child-width-1-2@m" uk-scrollspy="target: > div; cls:uk-animation-slide-bottom-small; delay: 100">
<div uk-grid class="uk-flex uk-flex-column" uk-scrollspy="target: > div; cls:uk-animation-slide-bottom-small; delay: 100">
<div>
<div uk-grid class="uk-margin-remove-left uk-flex uk-flex-column" uk-scrollspy="target: > div; cls:uk-animation-slide-bottom-small; delay: 100">
<div class="uk-padding-remove-left">
{{#uk-card as |card|}}
{{#card.header}}
{{#card.title}}
{{model.project.name}}
{{project.name}}
{{/card.title}}
{{/card.header}}
{{#card.body}}
<div class="uk-grid uk-grid-divider">
<div class="uk-width-1-2">
<dl class="uk-description-list">
<dt>{{t 'sysupport.admin.customer'}}:</dt>
<dd data-test-customer-name="{{model.project.id}}">{{model.project.customer.name}}</dd>
<dd data-test-customer-name="{{project.id}}">{{project.customer.name}}</dd>
<dt>{{t 'sysupport.admin.billingType'}}:</dt>
<dd data-test-billing-type-name="{{model.project.id}}">{{model.project.billingType.name}}</dd>
<dd data-test-billing-type-name="{{project.id}}">{{project.billingType.name}}</dd>
</dl>
</div>
<div class="uk-width-1-2">
<dl class="uk-description-list">
<dt>{{t 'sysupport.time.total'}}:</dt>
<dd>{{format-duration model.project.purchasedTime}}</dd>
<dt>{{t 'sysupport.time.used'}}:</dt>
<dd>{{format-duration model.project.spentTime}}</dd>
<dd class={{if (and duration preview) "uk-text-success"}} data-test-project-total-time >
{{format-duration (if (and duration preview) previewDuration project.totalTime) }}
</dd>
<dt>{{t 'sysupport.time.unconfirmed'}}:</dt>
<dd>{{format-duration project.unconfirmedTime}}</dd>
</dl>
</div>
</div>
{{/card.body}}
{{/uk-card}}
</div>
<div>
<div class="uk-padding-remove-left">
{{#uk-card as |card|}}
{{#card.header}}
{{#card.title}}
Expand All @@ -46,18 +83,20 @@
</tr>
</thead>
<tbody>
{{#each model.orders as |order index|}}
<tr data-test-project-order="{{index}}">
{{#each orders as |order index|}}
<tr class="uk-animation-fade" data-test-project-order="{{index}}">
<td>{{moment-format order.ordered 'DD.MM.YYYY'}}</td>
<td>{{format-duration order.duration format='hours'}}</td>
<td data-test-order-duration>{{format-duration order.duration format='hours'}}</td>
{{#if order.acknowledged}}
<td>{{uk-icon 'check' scale=2 data-test-acknowledged=index}}</td>
<td>{{uk-icon 'check' scale=2 data-test-acknowledged=index}}</td>
{{else}}
<td>{{uk-icon 'close' scale=2 data-test-unconfirmed=index}}</td>
<td>{{uk-icon 'close' scale=2 data-test-unconfirmed=index}}</td>
{{/if}}
</tr>
{{else}}{{t 'global.empty'}}{{/each}}
</tbody>
{{else}}
{{t 'global.empty'}}
{{/each}}
</tbody>
</table>
{{/card.body}}
{{/uk-card}}
Expand Down Expand Up @@ -88,8 +127,10 @@
<td>{{report.user.fullName}}</td>
<td>{{report.comment}}</td>
</tr>
{{else}}<tr><td colspan="4">{{t 'global.empty'}}</td></tr>{{/each}}
</tbody>
{{else}}
<tr><td colspan="4">{{t 'global.empty'}}</td></tr>
{{/each}}
</tbody>
</table>
{{/card.body}}
{{/uk-card}}
Expand Down
2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,6 @@
"loader.js": "^4.6.0",
"pagination-pager": "^3.1.0",
"prettier": "^1.9.2",
"qunit-dom": "^0.5.0"
"qunit-dom": "^0.6.3"
}
}
49 changes: 46 additions & 3 deletions frontend/tests/acceptance/sysupport-admin-test.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { click, currentURL, visit } from '@ember/test-helpers'
import { module, test } from 'qunit'
import { fillIn, click, currentURL, visit } from '@ember/test-helpers'

import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'
import { setupApplicationTest } from 'ember-qunit'
import {
authenticateSession,
invalidateSession
} from 'ember-simple-auth/test-support'
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'
import moment from 'moment'
import { module, test } from 'qunit'

import DjangoDurationTransform from 'customer-center/transforms/django-duration'

module('Acceptance | Sysupport Admin', function(hooks) {
setupApplicationTest(hooks)
Expand Down Expand Up @@ -43,6 +47,45 @@ module('Acceptance | Sysupport Admin', function(hooks) {
assert.dom('[data-test-project-report]').exists({ count: 5 })
})

test('subscription-admin reload', async function(assert) {
let project = this.server.create('timed-subscription-project', {
spentTime: DjangoDurationTransform.create().serialize(
moment.duration({ hours: 10 })
),
purchasedTime: DjangoDurationTransform.create().serialize(
moment.duration({ hours: 15 })
)
})

await visit('/sysupport-admin')

await click('[data-test-project="0"]')
assert.equal(currentURL(), `/sysupport-admin/${project.id}`)

assert.dom('[data-test-project-total-time]').hasText('5 Hours')

await click('[data-test-reload-accordion]')
await fillIn('[data-test-hour-input]', 10)
await fillIn('[data-test-minute-input]', 30)

assert.dom('[data-test-project-total-time]').hasText('15 Hours 30 Minutes')

assert.dom('[data-test-project-order]').exists({ count: 10 })

await click('[data-test-reload-submit]')

assert.dom('[data-test-project-order]').exists({ count: 11 })

assert
.dom('[data-test-project-order]:last-child > [data-test-order-duration]')
.hasText('10 Hours 30 Minutes')

await click('[data-test-reload-accordion]')
assert.dom('[data-test-reload-submit]').isDisabled()
await fillIn('[data-test-minute-input]', 30)
assert.dom('[data-test-reload-submit]').isNotDisabled()
})

test('subscription-admin confirm-subscriptions accept', async function(assert) {
let project = this.server.create('timed-subscription-project')
await visit('/sysupport-admin/confirm-subscriptions')
Expand Down
Loading

0 comments on commit 1d952e9

Please sign in to comment.