forked from projectcaluma/ember-emeis
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: tree view for scopes (projectcaluma#328)
* feat: tree view for scopes (wip) * feat: tree view as explicit component * test: add tests for tree view * fix: revert removal of settled() helpers * chore: minor refactoring, fix tests * chore: fix minor navigation issues, refactoring * chore: fix tests (wip) * feat: let datatable make use ember-resources * fix: redirect logic, avoid duplicate request for relationship * fix: tests Co-authored-by: Christian Zosel <[email protected]>
- Loading branch information
1 parent
f3fd796
commit 36e5976
Showing
35 changed files
with
528 additions
and
93 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<li class="{{if (and (not @flat) @item.children.length 0) 'childless'}}"> | ||
{{#if (and (not @flat) @item.children)}} | ||
<UkButton class="tree-node-icon" @color="link" {{on "click" this.toggle}}> | ||
<UkIcon @icon={{if this.expanded "chevron-down" "chevron-right"}} /> | ||
</UkButton> | ||
{{/if}} | ||
<LinkTo @route={{@itemRoute}} @model={{@item}} class="uk-link-text" data-test-node-id={{@item.id}}> | ||
{{@item.name}}{{#if @item.children}} ({{@item.children.length}}){{/if}} | ||
</LinkTo> | ||
{{#if this.expanded}} | ||
<ul class="tree"> | ||
{{#each (sort-by "name" @item.children) as |child|}} | ||
<TreeNode | ||
@item={{child}} | ||
@itemRoute={{@itemRoute}} | ||
@activeItem={{@activeItem}} | ||
@expandedItems={{@expandedItems}}/> | ||
{{/each}} | ||
</ul> | ||
{{/if}} | ||
</li> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
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 TreeNodeComponent extends Component { | ||
@tracked expandedByUser = null; | ||
@service router; | ||
|
||
@action | ||
toggle() { | ||
if (this.expandedByUser === null) { | ||
this.expandedByUser = !this.expanded; | ||
} else { | ||
this.expandedByUser = !this.expandedByUser; | ||
} | ||
|
||
if ( | ||
this.args.activeItem | ||
?.findParents() | ||
.find((parent) => parent.id === this.args.item.id) | ||
) { | ||
this.router.transitionTo(this.args.itemRoute, this.args.item.id); | ||
} | ||
} | ||
|
||
get expandedDefault() { | ||
return ( | ||
this.args.item.level === 0 || | ||
this.args.activeItem?.id === this.args.item.id | ||
); | ||
} | ||
|
||
get expanded() { | ||
return ( | ||
!this.args.flat && | ||
this.args.item.children && | ||
(this.args.expandedItems?.find((item) => item.id === this.args.item.id) || | ||
(this.expandedByUser !== null | ||
? this.expandedByUser | ||
: this.expandedDefault)) | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<div ...attributes> | ||
<div class="uk-inline uk-margin-small-bottom uk-width-1-1"> | ||
<span class="uk-form-icon" uk-icon="icon: search"></span> | ||
<Input | ||
class="uk-input tree-search" | ||
aira-label="search" | ||
@type="search" | ||
@value={{this.filterValue}} | ||
placeholder={{t "emeis.search.placeholder"}} | ||
data-test-tree-search | ||
{{on "input" this.filter}} | ||
/> | ||
</div> | ||
<ul class="tree"> | ||
{{#each (sort-by "name" this.items) as |item|}} | ||
<TreeNode | ||
@item={{item}} | ||
@itemRoute={{@itemRoute}} | ||
@activeItem={{@activeItem}} | ||
@expandedItems={{this.expandedItems}} | ||
@flat={{this.hasFilter}}/> | ||
{{/each}} | ||
</ul> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import { isArray } from "@ember/array"; | ||
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 TreeComponent extends Component { | ||
@service store; | ||
|
||
@tracked filterValue; | ||
|
||
@tracked filtered; | ||
|
||
get items() { | ||
if (!this.filterValue) return this.args.items; | ||
return this.filtered; | ||
} | ||
|
||
get hasFilter() { | ||
return !!this.filterValue; | ||
} | ||
|
||
get expandedItems() { | ||
return this.args.activeItem?.findParents | ||
? this.args.activeItem?.findParents() | ||
: []; | ||
} | ||
|
||
@action | ||
filter(event) { | ||
const filterItems = ( | ||
items, | ||
searchTerm = this.filterValue, | ||
includedKeys = ["name", "description"] | ||
) => { | ||
if (!searchTerm || !items || !isArray(items)) { | ||
return []; | ||
} | ||
const ownMatches = items.filter((item) => | ||
includedKeys.find((key) => | ||
item[key]?.toLowerCase().includes(searchTerm.toLowerCase()) | ||
) | ||
); | ||
|
||
const childMatches = items | ||
.filter((item) => item.children) | ||
.flatMap((item) => | ||
filterItems(item.children, searchTerm, includedKeys) | ||
); | ||
return [...ownMatches, ...childMatches]; | ||
}; | ||
|
||
this.filtered = filterItems(this.args.items, event.target.value); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import Controller from "@ember/controller"; | ||
import { inject as service } from "@ember/service"; | ||
|
||
export default class ScopesController extends Controller { | ||
@service router; | ||
|
||
get activeScope() { | ||
if (!this.router.currentRouteName.includes("ember-emeis.scopes.edit")) { | ||
return null; | ||
} | ||
return this.router.currentRoute.attributes; | ||
} | ||
|
||
get rootScopes() { | ||
return this.model?.filter((scope) => !scope.parent); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,20 @@ | ||
import Route from "@ember/routing/route"; | ||
import { inject as service } from "@ember/service"; | ||
|
||
export default class ScopesRoute extends Route {} | ||
export default class ScopesRoute extends Route { | ||
@service store; | ||
@service router; | ||
|
||
model() { | ||
return this.store.findAll("scope"); | ||
} | ||
|
||
redirect(scopes, transition) { | ||
if ( | ||
transition.targetName === "ember-emeis.scopes.index" && | ||
scopes.firstObject | ||
) { | ||
this.router.replaceWith("ember-emeis.scopes.edit", scopes.firstObject); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
import Route from "@ember/routing/route"; | ||
|
||
export default class ScopesEditIndexRoute extends Route { | ||
async model() { | ||
model() { | ||
return this.modelFor("scopes.edit"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,15 @@ | ||
<SectionTitle @model="scopes" /> | ||
|
||
{{outlet}} | ||
<div class="uk-grid"> | ||
<div class="uk-width-1-4 uk-first-column tree-wrapper"> | ||
<Tree | ||
class="uk-margin-small-left" | ||
@items={{this.rootScopes}} | ||
@itemRoute="scopes.edit" | ||
@activeItem={{this.activeScope}} | ||
/> | ||
</div> | ||
<div class="uk-width-3-4"> | ||
{{outlet}} | ||
</div> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.