Skip to content
This repository has been archived by the owner on May 13, 2024. It is now read-only.

Commit

Permalink
feat: add magic link component to create a magic link that can be sen…
Browse files Browse the repository at this point in the history
…t to another user (#1022)
  • Loading branch information
StephanH90 committed Jul 24, 2023
1 parent cc5cce9 commit 4096c58
Show file tree
Hide file tree
Showing 12 changed files with 385 additions and 2 deletions.
3 changes: 3 additions & 0 deletions app/components/date-navigation/template.hbs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<div class="date-navigation btn-toolbar" ...attributes>
<div class="btn-group">
<MagicLinkBtn />
</div>
<div class="btn-group">
<button
type="button"
Expand Down
6 changes: 6 additions & 0 deletions app/components/magic-link-btn/component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";

export default class MagicLinkBtn extends Component {
@tracked isModalVisible = false;
}
13 changes: 13 additions & 0 deletions app/components/magic-link-btn/template.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<button
type="button"
data-test-magic-link-btn
title="Create a magic link"
class="btn btn-default"
{{on "click" (toggle "isModalVisible" this)}}
>
<FaIcon @icon="magic" @prefix="fas" />
</button>

{{#if this.isModalVisible}}
<MagicLinkModal @isVisible={{this.isModalVisible}} @onClose={{toggle "isModalVisible" this}} />
{{/if}}
47 changes: 47 additions & 0 deletions app/components/magic-link-modal/component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { action } from "@ember/object";
import { inject as service } from "@ember/service";
import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";

export default class MagicLinkModal extends Component {
@tracked task;
@tracked duration;
@tracked comment;
@tracked review;
@tracked notBillable;
@tracked statusMsg;
@tracked errorMsg;

@service router;

@action
onSetTask(task) {
this.task = task;
}

get magicLinkString() {
const url = this.router.urlFor("index.reports", {
queryParams: {
task: this.task?.id,
comment: this.comment,
duration: this.duration,
review: this.review,
notBillable: this.notBillable,
},
});

return `${window.location.origin}${url}`;
}

@action
copyToClipboard() {
try {
navigator.clipboard.writeText(this.magicLinkString);
this.statusMsg =
"Magic link copied to clipboard. You can now send it to a friendly coworker!";
} catch {
/* istanbul ignore next */
this.errorMsg = "Could not copy to clipboard";
}
}
}
118 changes: 118 additions & 0 deletions app/components/magic-link-modal/template.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<SyModal
@size="auto"
@visible={{@isVisible}}
@onClose={{@onClose}}
data-test-magic-link-modal
as |modal|
>
<div
class="magic-link-modal"
data-test-magic-link-form
>
<modal.header>
Create a magic link
</modal.header>
<modal.body>
<div data-test-task-selector>
<TaskSelection
@disabled={{false}}
@task={{this.task}}
@on-set-task={{this.onSetTask}}
as |t|
>
<div
class="form-list-cell form-group"
>{{t.customer}}</div>
<div
class="form-list-cell form-group"
>{{t.project}}</div>
<div
class="form-list-cell form-group"
>{{t.task}}</div>
</TaskSelection>
</div>

<div class="margin-medium-bottom">
<Input
@value={{this.comment}}
class="ember-text-field form-control"
placeholder="Comment"
aria-label="Comment for the timed entry"
data-test-magic-link-comment
/>
</div>

<div class="margin-medium-bottom">
<div class="flex">
<SyDurationpickerDay
@disabled={{false}}
@value={{this.duration}}
@onChange={{fn (mut this.duration)}}
@title="Task duration"
data-test-magic-link-duration
class="flex-grow"
/>
<SyToggle
class="margin-small-right form-control flex-shrink"
data-test-magic-link-review
@hint="Needs review"
@onToggle={{toggle "review" this}}
@value={{this.review}}
>
<span class="fa-layers fa-fw">
<FaIcon @icon="user" />
<FaIcon
@icon="question"
@prefix="fas"
@transform="shrink-6 up-7 right-8"
/>
</span>
</SyToggle>
<SyToggle
class="form-control flex-shrink"
data-test-magic-link-not-billable
@hint="Not billable"
@onToggle={{toggle "notBillable" this}}
@value={{this.notBillable}}
>
<span class="fa-layers fa-fw">
<FaIcon @icon="dollar-sign" @prefix="fas" />
<FaIcon @icon="slash" @prefix="fas" />
</span>
</SyToggle>
</div>
</div>

<div class="flex">
<Input
@value={{this.magicLinkString}}
disabled={{true}}
class="flex-grow form-control"
aria-label="magic link string"
data-test-magic-link-string
/>
</div>
{{#if this.statusMsg}}
<div class="alert alert-success margin-medium-top">
{{this.statusMsg}}
</div>
{{/if}}
{{#if this.errorMsg}}
<div class="alert alert-warning margin-medium-top">
{{this.errorMsg}}
</div>
{{/if}}
</modal.body>
<modal.footer>
<button
class="btn btn-default margin-small-left"
{{on "click" this.copyToClipboard}}
disabled={{not this.magicLinkString}}
type="button"
data-test-create-magic-link-btn
>
Copy to clippy
</button>
</modal.footer>
</div>
</SyModal>
2 changes: 1 addition & 1 deletion app/components/report-row/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
type="submit"
data-test-save-report
class="btn btn-primary"
disabled={{or (not cs.isDirty) (not cs.isValid)}}
disabled={{and (not cs.isNew) (or (not cs.isDirty) (not cs.isValid))}}
{{on "click" (prevent-default (fn (optional @onSave) cs))}}
><FaIcon @icon="floppy-disk" /></button>
{{/if}}
Expand Down
7 changes: 7 additions & 0 deletions app/index/reports/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ import { cached } from "tracked-toolbox";
* @public
*/
export default class IndexReportController extends Controller {
queryParams = ["task", "duration", "comment", "review", "notBillable"];
@tracked task;
@tracked duration;
@tracked comment;
@tracked review;
@tracked notBillable;

@service notify;
@service router;

Expand Down
32 changes: 31 additions & 1 deletion app/index/reports/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* @public
*/
import Route from "@ember/routing/route";
import moment from "moment";
import RouteAutostartTourMixin from "timed/mixins/route-autostart-tour";

/**
Expand All @@ -29,10 +30,39 @@ export default class IndexReportsRoute extends Route.extend(
return this.store.findAll("absence-type");
}

setupController(controller, model, ...args) {
async setupController(controller, model, ...args) {
super.setupController(controller, model, ...args);

controller.set("user", this.modelFor("protected"));
controller.set("rescheduleDate", model);

if (controller.task) {
try {
await this.store.createRecord("report", {
task: await this.store.findRecord("task", controller.task),
duration: controller.duration
? moment.duration(controller.duration)
: "",
date: model,
comment: controller.comment ?? "",
user: this.modelFor("protected"),
review: controller.review ?? false,
notBillable: controller.notBillable ?? false,
});

controller.task = null;
controller.comment = null;
controller.duration = null;
controller.review = null;
controller.notBillable = null;

this.notify.success(
"Temporary report was created. Please amend it and save it or delete it."
);
} catch {
/* istanbul ignore next */
this.notify.error("Could not create report");
}
}
}
}
31 changes: 31 additions & 0 deletions app/styles/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
@import "components/sy-toggle";
@import "components/progress-tooltip";
@import "components/welcome-modal";
@import "components/magic-link-btn.scss";

html {
hyphens: auto;
Expand All @@ -62,6 +63,36 @@ strong {
.flex {
display: flex;
}
.margin-small-left {
margin-left: 0.5rem;
}
.margin-small-right {
margin-left: 0.5rem;
}
.margin-small-top {
margin-top: 0.5rem;
}
.margin-small-bottom {
margin-bottom: 0.5rem;
}
.margin-medium-left {
margin-left: 1rem;
}
.margin-medium-right {
margin-left: 1rem;
}
.margin-medium-top {
margin-top: 1rem;
}
.margin-medium-bottom {
margin-bottom: 1rem;
}
.flex-grow {
flex: 1;
}
.flex-shrink {
flex: 0;
}

.height-100 {
height: 100%;
Expand Down
7 changes: 7 additions & 0 deletions app/styles/components/magic-link-btn.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.ember-basic-dropdown-content {
z-index: 1002;
}

.magic-link-modal {
min-width: 500px;
}
1 change: 1 addition & 0 deletions config/icons.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ module.exports = function () {
"plus",
"users",
"question",
"magic",
],
};
};
Loading

0 comments on commit 4096c58

Please sign in to comment.