Skip to content
Draft
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
1 change: 1 addition & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nodejs 16.13.1
27 changes: 27 additions & 0 deletions app/components/moon.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<div class="flex items-center justify-between">
<div>
{{@index}}:
{{#if this.displayEditor}}
<Input
@type="text"
@value={{this.name}}
id="moon-name"
disabled={{this.create.isRunning}}
class="shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md"
/>
{{else}}
{{@moon.name}}
{{/if}}
</div>

<div>
<button
type='button'
class='inline-flex items-center px-2.5 py-1.5 border border-gray-300 shadow-sm text-xs font-medium rounded text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500'
disabled={{this.toggleEditor.isRunning}}
onClick={{perform this.toggleEditor}}
>
Edit
</button>
</div>
</div>
34 changes: 34 additions & 0 deletions app/components/moon.js
Original file line number Diff line number Diff line change
@@ -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();
}
}
85 changes: 50 additions & 35 deletions app/components/planet-list.hbs
Original file line number Diff line number Diff line change
@@ -1,47 +1,62 @@
<div ...attributes {{did-insert (perform this.refresh)}}>
<div class="font-bold">live query</div>
<div ...attributes>
<div class="flex items-center justify-between">
<div class="font-bold">live query</div>

<button
type='button'
class='inline-flex items-center px-2.5 py-1.5 border border-gray-300 shadow-sm text-xs font-medium rounded text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500'
disabled={{this.reload.isRunning}}
onClick={{perform this.reload}}
>
Reload
</button>
</div>

{{#each this.planets as |planet|}}
<div class="p-2 mb-2 border border gray-100">
<div class="flex items-center justify-between mb-2">
<div>{{planet.name}}</div>

<button
type='button'
class='inline-flex items-center px-2.5 py-1.5 border border-gray-300 shadow-sm text-xs font-medium rounded text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500'
disabled={{this.remove.isRunning}}
onClick={{perform this.remove planet}}
>
Delete
</button>
</div>
{{#each planet.moons as |moon i|}}
<div>{{i}}: {{moon.name}}</div>
{{/each}}
</div>
<Planet @planet={{planet}} @displayMoons={{true}}/>
{{/each}}

<hr class="my-8" />

<div class="flex items-center justify-between mb-2">
<div class="font-bold">static query</div>
<div class="flex items-center justify-between mb-2" {{did-insert this.createFork}}>
<div class="font-bold">Displayed from fork</div>

<button
type='button'
class='inline-flex items-center px-2.5 py-1.5 border border-transparent text-xs font-medium rounded shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500'
disabled={{this.create.isRunning}}
onClick={{perform this.refresh}}
>
Refresh
</button>
<div>
<button
type='button'
class='inline-flex items-center px-2.5 py-1.5 border border-gray-300 shadow-sm text-xs font-medium rounded text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500'
onClick={{this.toggleMoons}}
>
{{if this.displayMoons 'Hide Moons' 'Show Moons'}}
</button>

<button
type='button'
class='inline-flex items-center px-2.5 py-1.5 border border-gray-300 shadow-sm text-xs font-medium rounded text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500'
onClick={{this.destroyFork}}
>
Destroy Fork
</button>

<button
type='button'
class='inline-flex items-center px-2.5 py-1.5 border border-transparent text-xs font-medium rounded shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500'
onClick={{perform this.rebase}}
>
Rebase
</button>

<button
type='button'
class='inline-flex items-center px-2.5 py-1.5 border border-transparent text-xs font-medium rounded shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500'
onClick={{this.requery}}
>
Requery
</button>
</div>
</div>

{{#each this.staticPlanets as |planet|}}
<div class="p-2 mb-2 border border gray-100">
<div>{{planet.name}}</div>
{{#each planet.moons as |moon i|}}
<div>{{i}}: {{moon.name}}</div>
{{/each}}
</div>
<Planet @planet={{planet}} @displayMoons={{this.displayMoons}} />
{{/each}}
</div>
42 changes: 34 additions & 8 deletions app/components/planet-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'] });
}
}
44 changes: 44 additions & 0 deletions app/components/planet.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<div class="p-2 mb-2 border border gray-100">
<div class="flex items-center justify-between mb-2">
<div>
{{#if this.displayEditor}}
<Input
@type="text"
@value={{this.name}}
id="planet-name"
disabled={{this.create.isRunning}}
class="shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md"
/>
{{else}}
{{@planet.name}}
-- {{this.moonNames}}
{{/if}}
</div>

<div>
<button
type='button'
class='inline-flex items-center px-2.5 py-1.5 border border-gray-300 shadow-sm text-xs font-medium rounded text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500'
disabled={{this.toggleEditor.isRunning}}
onClick={{perform this.toggleEditor}}
>
Edit
</button>

<button
type='button'
class='inline-flex items-center px-2.5 py-1.5 border border-gray-300 shadow-sm text-xs font-medium rounded text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500'
disabled={{this.remove.isRunning}}
onClick={{perform this.remove @planet}}
>
Delete
</button>
</div>
</div>

{{#if @displayMoons}}
{{#each @planet.moons as |moon i|}}
<Moon @moon={{moon}} @index={{i}} />
{{/each}}
{{/if}}
</div>
38 changes: 38 additions & 0 deletions app/components/planet.js
Original file line number Diff line number Diff line change
@@ -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();
}
}
6 changes: 6 additions & 0 deletions app/routes/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 4 additions & 7 deletions mirage/scenarios/default.js
Original file line number Diff line number Diff line change
@@ -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' });
}
26 changes: 26 additions & 0 deletions tests/integration/components/planet-test.js
Original file line number Diff line number Diff line change
@@ -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`<Planet />`);

assert.dom(this.element).hasText('');

// Template block usage:
await render(hbs`
<Planet>
template block text
</Planet>
`);

assert.dom(this.element).hasText('template block text');
});
});