From 69eeb851934ddaf12b48cd19eebb45d03f634a49 Mon Sep 17 00:00:00 2001 From: Brian Marete Date: Sun, 10 Jan 2021 15:42:19 +0300 Subject: [PATCH 1/3] Add pin task functionality I added an action in the index controller that handles the setting of a pinned task. This action handles logic for pinning, unpinning and replacing a pinned task. This action is passed down to the single task component through the task list component and is triggered when the pin/unpin button is clicked. I also added an attribute to the task model and I use this to display or hide the task in the task list. There's probably a better way to do this though as I don't think this attribute belongs to the model. --- app/components/single-task.hbs | 4 +- app/components/single-task.js | 15 + app/components/task-list.hbs | 4 +- app/components/task-list.js | 5 + app/controllers/index.js | 16 + app/models/task.js | 3 + app/templates/index.hbs | 23 +- package-lock.json | 18492 +++++++++++++++++++++++++++++++ package.json | 2 +- 9 files changed, 18540 insertions(+), 24 deletions(-) create mode 100644 package-lock.json diff --git a/app/components/single-task.hbs b/app/components/single-task.hbs index d644ec8..bec6778 100644 --- a/app/components/single-task.hbs +++ b/app/components/single-task.hbs @@ -5,7 +5,9 @@
- Pin + + {{if this.isPinned "Unpin" "Pin"}} + {{#if this.task.isComplete}} Undo {{else}} diff --git a/app/components/single-task.js b/app/components/single-task.js index 30b0515..d69ce09 100644 --- a/app/components/single-task.js +++ b/app/components/single-task.js @@ -1,7 +1,22 @@ import Component from '@ember/component'; import { tagName } from '@ember-decorators/component'; +import { action } from '@ember/object'; +import { tracked } from '@glimmer/tracking'; export default @tagName('') class SingleTaskComponent extends Component { + @tracked isPinned; + + constructor() { + super(...arguments); + this.isPinned = false; + } + + @action + togglePin() { + this.isPinned = !this.isPinned; + this.task.isNotPinned = !this.isPinned; + this.onPinSentUp(this.task); + } } diff --git a/app/components/task-list.hbs b/app/components/task-list.hbs index 41b6c7c..7489d36 100644 --- a/app/components/task-list.hbs +++ b/app/components/task-list.hbs @@ -1,7 +1,9 @@
    {{#each this.tasks as |task|}} - + {{#if task.isNotPinned }} + + {{/if}} {{/each}}
\ No newline at end of file diff --git a/app/components/task-list.js b/app/components/task-list.js index d02703f..9aadbe2 100644 --- a/app/components/task-list.js +++ b/app/components/task-list.js @@ -1,7 +1,12 @@ import Component from '@ember/component'; import { tagName } from '@ember-decorators/component'; +import { action } from '@ember/object'; export default @tagName('') class TaskListComponent extends Component { + @action + receivedPinAction() { + this.onPinSentUp(arguments[0]); + } } diff --git a/app/controllers/index.js b/app/controllers/index.js index 78d8779..8ae7e05 100644 --- a/app/controllers/index.js +++ b/app/controllers/index.js @@ -1,4 +1,20 @@ import Controller from '@ember/controller'; +import { action } from '@ember/object'; +import { tracked } from '@glimmer/tracking'; export default class IndexController extends Controller { + @tracked pinnedTask = null; + + @action + receivedPinAction() { + if(this.pinnedTask == null) { // pin a task if there is no current pinned task + this.pinnedTask = arguments[0]; + } else if(this.pinnedTask.id == arguments[0].id){ // unpinning a task + this.pinnedTask = null; + } else { // replacing the current pinned task + this.pinnedTask.isNotPinned = true; + this.pinnedTask = arguments[0]; + } + } + } diff --git a/app/models/task.js b/app/models/task.js index 41d4ce9..378eaf1 100644 --- a/app/models/task.js +++ b/app/models/task.js @@ -10,4 +10,7 @@ export default class TaskModel extends Model { @attr('boolean') isComplete + + @attr('boolean', { defaultValue: true }) + isNotPinned } diff --git a/app/templates/index.hbs b/app/templates/index.hbs index 13a70b0..9ef229b 100644 --- a/app/templates/index.hbs +++ b/app/templates/index.hbs @@ -1,31 +1,12 @@

Task List

Pinned Task

{{#if this.pinnedTask}} -
-
-
- {{this.pinnedTask.name}} -
-
-
- Unpin - {{#if this.pinnedTask.isComplete}} - Undo - {{else}} - Done - {{/if}} -
-
-
-
- {{this.pinnedTask.description}} -
-
+ {{else}} No Pinned Tasks {{/if}}

Other Tasks

- +
diff --git a/app/components/single-task.js b/app/components/single-task.js index d69ce09..73efb15 100644 --- a/app/components/single-task.js +++ b/app/components/single-task.js @@ -19,4 +19,9 @@ class SingleTaskComponent extends Component { this.task.isNotPinned = !this.isPinned; this.onPinSentUp(this.task); } + + @action + toggleComplete() { + this.task.isComplete = !this.task.isComplete; + } } diff --git a/app/components/toggle-complete.hbs b/app/components/toggle-complete.hbs new file mode 100644 index 0000000..42d0f77 --- /dev/null +++ b/app/components/toggle-complete.hbs @@ -0,0 +1,3 @@ + + {{yield}} + diff --git a/tests/integration/components/toggle-complete-test.js b/tests/integration/components/toggle-complete-test.js new file mode 100644 index 0000000..0ce89c7 --- /dev/null +++ b/tests/integration/components/toggle-complete-test.js @@ -0,0 +1,26 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; + +module('Integration | Component | toggle-complete', function(hooks) { + setupRenderingTest(hooks); + + test('it renders', async function(assert) { + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.set('myAction', function(val) { ... }); + + await render(hbs``); + + assert.equal(this.element.textContent.trim(), ''); + + // Template block usage: + await render(hbs` + + template block text + + `); + + assert.equal(this.element.textContent.trim(), 'template block text'); + }); +});