Last active
February 8, 2021 16:12
-
-
Save neborn/5233c2f6f8b140a009d4af7f8e12235f to your computer and use it in GitHub Desktop.
Employee Search Example - Complete
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
import Component from '@glimmer/component'; | |
import { action } from '@ember/object'; | |
import { inject as service } from '@ember/service'; | |
export default class ActionBarComponent extends Component { | |
@service employeeSearch; | |
} |
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
import Component from '@glimmer/component'; | |
export default class AddEmployeesToGroupModal extends Component { | |
} |
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
import Component from '@glimmer/component'; | |
import { action } from '@ember/object'; | |
import { inject as service } from '@ember/service'; | |
export default class extends Component { | |
@service employeeSearch; | |
_addEmployeesToGroupFlowController; | |
_employeeSearchQuery; | |
get addEmployeesToGroupFlowController() { | |
return this._addEmployeesToGroupFlowController; | |
} | |
get employeeSearchQuery() { | |
return this._employeeSearchQuery; | |
} | |
constructor() { | |
super(...arguments); | |
this._employeeSearchQuery = this.employeeSearch.createEmployeeSearchQuery(); | |
this._addEmployeesToGroupFlowController = | |
this.employeeSearch.createAddEmployeesToGroupFlowController(); | |
} | |
willDestroy() { | |
this.addEmployeesToGroupFlowController.cleanup(); | |
} | |
} |
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
import EmberRouter from '@ember/routing/router'; | |
import config from './config/environment'; | |
const Router = EmberRouter.extend({ | |
location: 'none', | |
rootURL: config.rootURL | |
}); | |
Router.map(function() { | |
this.route('employee-search', { path: '/employee-search' }); | |
}); | |
export default Router; |
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
import Service from '@ember/service'; | |
import { tracked } from '@glimmer/tracking'; | |
export default class ConfigurationService extends Service { | |
@tracked currentEmployerId = 'employer1'; | |
@tracked currentEmployerName = 'Test Employer'; | |
} |
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
import Service, { inject as service } from '@ember/service'; | |
import Object from '@ember/object'; | |
import { action } from '@ember/object'; | |
import EmployeeSearchQuery from '../view-models/employee-search-query'; | |
import AddEmployeesToGroupFlow from '../view-models/add-employees-to-group-flow'; | |
import AddEmployeesToGroupFlowController from '../view-models/add-employees-to-group-flow-controller'; | |
import Evented from '@ember/object/evented'; | |
export const Events = { | |
ADD_EMPLOYEES_TO_GROUP: 'ADD_EMPLOYEES_TO_GROUP' | |
}; | |
class EventBus extends Object.extend(Evented) {} | |
export default class EmployeeSearchService extends Service { | |
@service configuration; | |
_eventBus = EventBus.create(); | |
get eventBus() { | |
return this._eventBus; | |
} | |
@action | |
performEmployeeSearch(params) { | |
// use configuration service to construct the API request | |
const results = []; | |
return new Promise( | |
resolve => setTimeout(() => resolve(results), 500) | |
); | |
} | |
@action | |
performEmployeeTypeaheadSearch(params) { | |
// use configuration service to construct the API request | |
const results = []; | |
return new Promise( | |
resolve => setTimeout(() => resolve(results), 500) | |
); | |
} | |
@action | |
performAddEmployeesToGroup(params) { | |
// use configuration service to construct the API request | |
return new Promise(resolve => setTimeout(resolve, 500)); | |
} | |
@action | |
createEmployeeSearchQuery() { | |
return new EmployeeSearchQuery({ | |
searchService: this | |
}); | |
} | |
@action | |
createAddEmployeesToGroupFlow(group, onSuccess) { | |
return new AddEmployeesToGroupFlow({ | |
group, | |
onSuccess, | |
searchService: this | |
}); | |
} | |
@action | |
createAddEmployeesToGroupFlowController() { | |
return new AddEmployeesToGroupFlowController({ | |
searchService: this | |
}); | |
} | |
@action | |
startAddEmployeesToGroupFlow(group) { | |
this.eventBus.trigger(Events.ADD_EMPLOYEES_TO_GROUP, { group }); | |
} | |
} |
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
{ | |
"version": "0.17.1", | |
"EmberENV": { | |
"FEATURES": {}, | |
"_TEMPLATE_ONLY_GLIMMER_COMPONENTS": false, | |
"_APPLICATION_TEMPLATE_WRAPPER": true, | |
"_JQUERY_INTEGRATION": true | |
}, | |
"options": { | |
"use_pods": false, | |
"enable-testing": false | |
}, | |
"dependencies": { | |
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.js", | |
"ember": "3.18.1", | |
"ember-template-compiler": "3.18.1", | |
"ember-testing": "3.18.1" | |
}, | |
"addons": { | |
"@glimmer/component": "1.0.0", | |
"ember-concurrency": "1.3.0", | |
"tracked-built-ins": "1.0.2", | |
"ember-lifeline": "6.0.1" | |
} | |
} |
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
import { Events } from '../services/employee-search'; | |
import { action } from '@ember/object'; | |
import { tracked } from '@glimmer/tracking'; | |
export default class AddEmployeesToGroupFlowController { | |
_searchService; | |
@tracked | |
_addEmployeesToGroupFlow = null; | |
get addEmployeesToGroupFlow() { | |
return this._addEmployeesToGroupFlow; | |
} | |
get modalIsOpen() { | |
return !!this.addEmployeesToGroupFlow; | |
} | |
constructor({ | |
searchService | |
}) { | |
this._searchService = searchService; | |
this._searchService.eventBus.on( | |
Events.ADD_EMPLOYEES_TO_GROUP, | |
this.openModal | |
); | |
} | |
@action | |
cleanup() { | |
this._searchService.eventBus.off( | |
Events.ADD_EMPLOYEES_TO_GROUP, | |
this, | |
this.openModal | |
); | |
} | |
@action | |
openModal(event) { | |
if (this.addEmployeesToGroupFlow) { | |
return; | |
} | |
const { | |
group | |
} = event; | |
this._addEmployeesToGroupFlow = this._searchService.createAddEmployeesToGroupFlow({ | |
group, | |
onSuccess: this.closeModal | |
}) | |
} | |
@action | |
closeModal() { | |
this._addEmployeesToGroupFlow = null; | |
} | |
} |
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
import { action } from '@ember/object'; | |
import { tracked } from '@glimmer/tracking'; | |
import { task } from 'ember-concurrency'; | |
import { TrackedSet } from 'tracked-built-ins'; | |
export default class AddEmployeesToGroupFlow { | |
_group; | |
_onSuccess; | |
_searchService; | |
@tracked | |
_employeeList = new TrackedSet(); | |
@tracked | |
_typeaheadResults; | |
@tracked | |
_typeaheadSearchQuery = ''; | |
get employeeList() { | |
return this._employeeList; | |
} | |
get group() { | |
return this._group; | |
} | |
get typeaheadResults() { | |
return this._typaheadResults; | |
} | |
get typeaheadSearchQuery() { | |
} | |
constructor({ | |
group, | |
onSuccess, | |
searchService | |
}) { | |
this._group = group; | |
this._onSuccess = onSuccess; | |
this._searchService = searchService; | |
} | |
@action | |
updateTypeaheadSearchQuery() { | |
// update value | |
// trigger search | |
// throttle request | |
} | |
@action | |
selectEmployee(employee) { | |
this._employeeList.delete(employee); | |
} | |
@action | |
unselectEmployee(employee) { | |
this._employeeList.delete(employee); | |
} | |
@action | |
submitEmployees() { | |
// error handling | |
} | |
} |
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
import { action } from '@ember/object'; | |
import { tracked } from '@glimmer/tracking'; | |
import { task } from 'ember-concurrency'; | |
const PAGE_SIZE = 20; | |
const SortOrder = { | |
ASCENDING: 'ASCENDING', | |
DESCENDING: 'DESCENDING' | |
}; | |
export default class EmployeeSearchQuery { | |
_searchService; | |
_pagesLoaded = 0; | |
@tracked | |
_resultsList; | |
@tracked | |
_searchString = ''; | |
@tracked | |
_sortField; | |
@tracked | |
_sortOrder; | |
get resultsList() { | |
return this._resultsList; | |
} | |
get searchString() { | |
return this._searchString; | |
} | |
get sortField() { | |
return this._sortField; | |
} | |
get sortOrder() { | |
return this._sortOrder; | |
} | |
constructor({ searchService }) { | |
this._searchService = searchService; | |
} | |
@action | |
updateSearchString(value) { | |
this._searchString = value; | |
} | |
@action | |
triggerSearch() { | |
this._searchTask.perform(); | |
} | |
@action | |
updateSortField(fieldName) { | |
if (this._fieldName === fieldName) { | |
return; | |
} | |
this._fieldName = fieldName; | |
this._sortOrder = SortOrder.ASCENDING; | |
this._newSearchTask.perform(); | |
} | |
@action | |
toggleSortOrder() { | |
this._sortOrder = this._sortOrder === SortOrder.ASCENDING ? | |
SortOrder.DESCENDING : SortOrder.ASCENDING; | |
this._newSearchTask.perform(); | |
} | |
@action | |
fetchAdditionalPage() { | |
this._fetchPageTask.perform(); | |
} | |
@(task(function * (pageNumber = 0) { | |
const { | |
searchString, | |
sortField, | |
sortOrder | |
} = this; | |
const results = yield this._searchService.performSearchQuery({ | |
pageNumber, | |
pageSize: PAGE_SIZE, | |
searchString, | |
sortField, | |
sortOrder | |
}); | |
return results; | |
}).restartable()) _searchTask; | |
@(task(function * () { | |
if (this._searchTask.isRunning()) { | |
return; | |
} | |
const results = yield this._searchTask.perform(this._pagesLoaded + 1); | |
this._pagesLoaded += 1; | |
this._resultsList = this._resultsList.concat(results); | |
}).drop()) _fetchPageTask; | |
@(task(function * () { | |
this._pagesLoaded = 0; | |
this._resultsList = yield this._searchTask.perform(); | |
}).restartable()) _newSearchTask; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment