diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 0000000..ba4cc25 --- /dev/null +++ b/.tool-versions @@ -0,0 +1 @@ +nodejs 16.13.1 diff --git a/app/components/moon.hbs b/app/components/moon.hbs new file mode 100644 index 0000000..b745917 --- /dev/null +++ b/app/components/moon.hbs @@ -0,0 +1,27 @@ +
+
+ {{@index}}: + {{#if this.displayEditor}} + + {{else}} + {{@moon.name}} + {{/if}} +
+ +
+ +
+
diff --git a/app/components/moon.js b/app/components/moon.js new file mode 100644 index 0000000..a78f308 --- /dev/null +++ b/app/components/moon.js @@ -0,0 +1,34 @@ +import Component from '@glimmer/component'; +import { inject as service } from '@ember/service'; +import { dropTask } from 'ember-concurrency'; +import { tracked } from '@glimmer/tracking'; + +export default class PlanetComponent extends Component { + @service store; + + @tracked displayEditor = false; + @tracked name = ''; + + @dropTask + *toggleEditor() { + if (this.displayEditor) { + let fork = this.store.fork(); + let moon = fork.cache.findRecord(this.args.moon); + moon.name = this.name; + yield this.store.merge(fork); + fork.destroy(); + } else { + this.name = this.args.moon.name; + } + + this.displayEditor = !this.displayEditor; + } + + @dropTask + *remove(planet) { + let fork = this.store.fork(); + yield fork.removeRecord(planet); + yield this.store.merge(fork); + fork.destroy(); + } +} diff --git a/app/components/planet-list.hbs b/app/components/planet-list.hbs index 4f72565..479a378 100644 --- a/app/components/planet-list.hbs +++ b/app/components/planet-list.hbs @@ -1,47 +1,62 @@ -
-
live query
+
+
+
live query
+ + +
{{#each this.planets as |planet|}} -
-
-
{{planet.name}}
- - -
- {{#each planet.moons as |moon i|}} -
{{i}}: {{moon.name}}
- {{/each}} -
+ {{/each}}
-
-
static query
+
+
Displayed from fork
- +
+ + + + + + + +
{{#each this.staticPlanets as |planet|}} -
-
{{planet.name}}
- {{#each planet.moons as |moon i|}} -
{{i}}: {{moon.name}}
- {{/each}} -
+ {{/each}}
diff --git a/app/components/planet-list.js b/app/components/planet-list.js index 1163324..d94d654 100644 --- a/app/components/planet-list.js +++ b/app/components/planet-list.js @@ -2,26 +2,52 @@ import Component from '@glimmer/component'; import { inject as service } from '@ember/service'; import { tracked } from '@glimmer/tracking'; import { dropTask } from 'ember-concurrency'; +import { action } from '@ember/object'; export default class PlanetListComponent extends Component { @service store; @tracked staticPlanets = []; + @tracked displayMoons = false; get planets() { return this.store.cache.liveQuery((q) => q.findRecords('planet')); } - /* eslint require-yield: off */ + @action + toggleMoons() { + this.displayMoons = !this.displayMoons; + } + + @action + destroyFork() { + this.fork.destroy(); + } + + @action + createFork() { + this.fork = this.store.fork(); + this.requery(); + } + + @action + requery() { + this.staticPlanets = this.fork.cache.findRecords('planet'); + } + @dropTask - *refresh() { - this.staticPlanets = this.store.cache.findRecords('planet'); + *rebase() { + let oldFork = this.fork; + let newFork = this.store.fork(); + yield newFork.merge(oldFork); + this.fork = newFork; + yield oldFork.destroy(); + + // This would fix the issue as it updates references to the new fork + // this.staticPlanets = this.fork.cache.findRecords('planet'); } @dropTask - *remove(planet) { - let fork = this.store.fork(); - yield fork.removeRecord(planet); - yield this.store.merge(fork); - fork.destroy(); + *reload() { + yield this.store.findRecords('planet', { include: ['moons'] }); } } diff --git a/app/components/planet.hbs b/app/components/planet.hbs new file mode 100644 index 0000000..f437f8c --- /dev/null +++ b/app/components/planet.hbs @@ -0,0 +1,44 @@ +
+
+
+ {{#if this.displayEditor}} + + {{else}} + {{@planet.name}} + -- {{this.moonNames}} + {{/if}} +
+ +
+ + + +
+
+ + {{#if @displayMoons}} + {{#each @planet.moons as |moon i|}} + + {{/each}} + {{/if}} +
diff --git a/app/components/planet.js b/app/components/planet.js new file mode 100644 index 0000000..6dc5fc7 --- /dev/null +++ b/app/components/planet.js @@ -0,0 +1,38 @@ +import Component from '@glimmer/component'; +import { inject as service } from '@ember/service'; +import { dropTask } from 'ember-concurrency'; +import { tracked } from '@glimmer/tracking'; + +export default class PlanetComponent extends Component { + @service store; + + @tracked displayEditor = false; + @tracked name = ''; + + get moonNames() { + return this.args.planet.moons.mapBy('name').join(', '); + } + + @dropTask + *toggleEditor() { + if (this.displayEditor) { + let fork = this.store.fork(); + let planet = fork.cache.findRecord(this.args.planet); + planet.name = this.name; + yield this.store.merge(fork); + fork.destroy(); + } else { + this.name = this.args.planet.name; + } + + this.displayEditor = !this.displayEditor; + } + + @dropTask + *remove(planet) { + let fork = this.store.fork(); + yield fork.removeRecord(planet); + yield this.store.merge(fork); + fork.destroy(); + } +} diff --git a/app/routes/application.js b/app/routes/application.js index b5c65b8..d6c71f7 100644 --- a/app/routes/application.js +++ b/app/routes/application.js @@ -5,6 +5,12 @@ export default class ApplicationRoute extends Route { @service dataCoordinator; @service store; + async model() { + // return this.store.findRecords('planet', { include: ['moons'] }); + let planet = await this.store.findRecords('planet'); + return this.store.findRecords('moon'); + } + async beforeModel() { // Populate the store from backup prior to activating the coordinator // As users browse more data this way of loading the store would diff --git a/mirage/scenarios/default.js b/mirage/scenarios/default.js index adb3af4..35db98b 100644 --- a/mirage/scenarios/default.js +++ b/mirage/scenarios/default.js @@ -1,9 +1,6 @@ -export default function(/* server */) { +export default function (server) { + window.mirage = { server: server }; - /* - Seed your development database using your factories. - This data will not be loaded in your tests. - */ - - // server.createList('post', 10); + let planet = server.create('planet', { name: 'Earth' }); + server.create('moon', { planet: planet, name: 'moon' }); } diff --git a/tests/integration/components/planet-test.js b/tests/integration/components/planet-test.js new file mode 100644 index 0000000..388fc09 --- /dev/null +++ b/tests/integration/components/planet-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 | planet', 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.dom(this.element).hasText(''); + + // Template block usage: + await render(hbs` + + template block text + + `); + + assert.dom(this.element).hasText('template block text'); + }); +});