- In the Content setup for 'Dashboard', pretty much moved the actions / list / etc to live under the 'tab'
dashboard: {
id: 'dashboard',
title: 'Dashboard',
tabs: [{
label: 'Analytics',
tab: 'analytics',
goTo: 'app.page.list({_contentType: \'dashboard\', tab: \'analytics\'})',
filterHeaders: ['Dashboard', 'State']
}, {
label: 'Enterprises',
tab: 'enterprises',
goTo: 'app.page.list({_contentType: \'dashboard\', tab: \'enterprises\'})',
listHeaders: ['ID', 'Enterprise Name', 'Services', 'Agreed EULA'],
listAction: function (item) {
Router.gotoEnterprise(item.id);
},
actions: [{
label: 'Create Enterprise',
icon: 'ion-wrench',
action: function () {
$modal.open({
templateUrl: 'app/components/modal/create-enterprise-modal/' +
'create-enterprise-tpl.html',
controller: 'CreateEnterpriseCtrl as ctrl',
size: 'lg'
});
},
className: 'btn-success'
}]
}]In the list component, and similar thing was done in the subheader component. I check to see if the content has a tab, then switch around where we load things from. This is a little messy right now and can be cleaned up to not feel so hackey, but I think the general idea is ok.
var tab;
if (response.tabs) {
tab = R.filter(R.propEq('tab', Router.getActiveTab()))(response.tabs)[0];
try {
listProvider = $injector.get(tab.tab + 'List'); // <--- see notes on this below
} catch (e) {
console.log('unable to find list provider');
}
}
angular.extend(vm, {
filterHeaders: tab ? tab.filterHeaders : response.filterHeaders,
filterCount: response.filterCount,
filterAction: response.filterAction,
filterContent: response.filterItemMock,
listHeaders: tab ? tab.listHeaders : response.listHeaders,
listCount: response.listCount,
listContent: response.listItemMock,
listAction: tab ? tab.listAction : response.listAction,
tabs: response.tabs
});
```javascript
This controller now takes an $injector - although this could/should be pulled out into a helper service.
Right now, it's only taking it for the tab - although should change it to account for contentType if there is no tab, so like
```javascript
else {
// no tabs
try {
listProvider = $injector.get(router.getContentType() + 'List'); // <--- see notes on this below
} catch (e) {
console.log('unable to find list provider');
}
}The idea being - each contentType that needs to have a list, would have a service that followed the naming convention of contenttypeList, and would have a method called getList.
It is upto that service to fetch the data, and format the list properly.
My example enterprisesList
var formatList = R.map(function (item) {
return {
id: item.id,
labels: [item.id, item.enterpriseName, item.services ? item.services.join(',') : '', item.agreedEula]
};
});
return {
getList: function()
{
return enterprise.get().then(formatList)
}
}getList should probably take an object called like searchParams or something so we can pass searching/paging/filtering data. But the idea is that each list provider should have the same contract/interface.
Was also playing around a little bit with loading up the details. This is a little hard-coded right now, but can be expanded/cleaned up:
.state('app.page.list.detail', {
url: '/:_id',
views: {
detail: {
controller: 'DetailCtrl as detail',
templateUrl: 'app/sections/detail/detail.html'
},
'[email protected]': {
templateProvider: function ($templateRequest, $stateParams) {
// TODO: Create a service for this?
// Have a convention of how to find the correct view
var path = 'app/sections/detail/default.html';
if ($stateParams._contentType === 'dashboard' && $stateParams.tab === 'enterprises') {
path = 'app/sections/detail/dashboard/enterprises/enterprises.html';
}
return $templateRequest(path);
}
}
}
});
});The 'detail.html' is now smaller than it was before
<div class="detail-view">
<div class="detail-view--mask" ng-click="detail.closeDetails()"></div>
<div class="detail-view--container">
<div ui-view="detail-view-content"></div>
</div>
</div>
so similar to having a convention for xyzList - we could try and have a contention for finding templates for the details on the fly.
Currently in the enterprise.html I'm using:
<div ng-controller='EnterpriseDetailCtrl as ctrl'>
<!-- the rest -->
</div>to get the controller for it - although similar to templateProvider, you could use a controllerProvider function to dynamically return the controller name - although in this case, sort of fine with using the ng-controller in the template.
Theres a few things I'm not happy about with a bit of my file organization - sort of don't like having my create-enterprise stuff tucked under app/components/modal/create, and then list shoved under list, and details tucked under details. Feesls like there is quite a bit of jumping around
Even though we are having this fairly generic routing, still think it'd make sense to have it
- sections
-- enterprise
---- list
---- details
---- create
---- update
There is also quite a bit repetition between my create controller, and my update controller - would like to try and clean it up and pull out the reusable code to an appropiate place.
I'm not a big fan of always re-using the same controller for create,update,view - as almost every time I've tried that because 'they are exactly the same (at the start)' - sure enough things crop up that start being specific to each thing and you get a whole bunch of
if(editMode)
{ then this }
else if (createMode)
{ then this }
else if (viewMode)
{ then this }