Skip to content

Commit 33763b9

Browse files
committed
Add data browser base on Meta model
1 parent e78b420 commit 33763b9

13 files changed

Lines changed: 513 additions & 153 deletions

File tree

client/app/js/app.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ var app = angular.module('loopbackApp', [
3838
'ui.select',
3939
'com.module.core',
4040
'com.module.about',
41+
'com.module.browser',
4142
'com.module.events',
4243
'com.module.files',
4344
'com.module.notes',
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
'use strict';
2+
angular.module('com.module.browser', []);
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
'use strict';
2+
angular.module('com.module.browser')
3+
.run(function ($rootScope, Event, gettextCatalog) {
4+
$rootScope.addMenu(gettextCatalog.getString('Browser'), 'app.browser.models',
5+
'fa-globe');
6+
});
Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
'use strict';
2+
var app = angular.module('com.module.browser');
3+
4+
app.config(function ($stateProvider) {
5+
$stateProvider.state('app.browser', {
6+
abstract: true,
7+
url: '/browser',
8+
templateUrl: 'modules/browser/views/main.html'
9+
}).state('app.browser.models', {
10+
url: '',
11+
templateUrl: 'modules/browser/views/models.html',
12+
controllerAs: 'ctrl',
13+
controller: ['Meta', 'models',
14+
function (Meta, models) {
15+
this.models = models;
16+
}
17+
],
18+
resolve: {
19+
models: ['Meta', function (Meta) {
20+
return Meta.getModels().$promise;
21+
}]
22+
}
23+
}).state('app.browser.models.items', {
24+
url: '/:modelName',
25+
templateUrl: 'modules/browser/views/models.items.html',
26+
controllerAs: 'items',
27+
controller: ['model', 'items', function (model, items) {
28+
this.model = model;
29+
this.items = items;
30+
this.itemKeys = [];
31+
if (this.items[0] !== undefined) {
32+
this.itemKeys = Object.keys(this.items[0]);
33+
}
34+
}],
35+
resolve: {
36+
model: ['$stateParams', 'Meta', function ($stateParams, Meta) {
37+
return Meta.getModelById({
38+
name: $stateParams.modelName
39+
}).$promise;
40+
}],
41+
items: ['$stateParams', '$injector', 'Meta', function ($stateParams, $injector, Meta) {
42+
var Model = $injector.get($stateParams.modelName);
43+
if (typeof Model.find !== 'function') {
44+
return false;
45+
} else {
46+
return Model.find().$promise;
47+
}
48+
}]
49+
}
50+
})
51+
.state('app.browser.models.items.view', {
52+
url: '/:modelId/view',
53+
templateUrl: 'modules/browser/views/models.items.view.html',
54+
controllerAs: 'view',
55+
controller: ['item', function (item) {
56+
this.item = item;
57+
this.itemKeys = Object.keys(this.item);
58+
}],
59+
resolve: {
60+
item: ['$stateParams', '$injector', function ($stateParams, $injector) {
61+
var Model = $injector.get($stateParams.modelName);
62+
if (typeof Model.find !== 'function') {
63+
return false;
64+
} else {
65+
return Model.findOne({
66+
filter: {
67+
where: {
68+
id: $stateParams.modelId
69+
}
70+
}
71+
}).$promise;
72+
}
73+
}]
74+
}
75+
})
76+
.state('app.browser.models.items.edit', {
77+
url: '/:modelId/edit',
78+
templateUrl: 'modules/browser/views/models.items.edit.html',
79+
controllerAs: 'edit',
80+
controller: ['$state', 'SweetAlert', 'Model', 'model', 'item', 'itemFields',
81+
function ($state, SweetAlert, Model, model, item, itemFields) {
82+
this.item = item;
83+
this.itemFields = itemFields;
84+
this.submit = function () {
85+
Model.upsert(this.item).$promise.then(function (res) {
86+
SweetAlert.swal('Saved!', 'The item is saved.', 'success');
87+
$state.go('app.browser.models.items.view', {modelName: model.name, modelId: res.id}, {reload: true});
88+
});
89+
}
90+
}],
91+
resolve: {
92+
Model: ['$stateParams', '$injector',
93+
function ($stateParams, $injector) {
94+
return $injector.get($stateParams.modelName);
95+
}],
96+
item: ['$stateParams', 'Model',
97+
function ($stateParams, Model) {
98+
if (typeof Model.find !== 'function') {
99+
return false;
100+
} else {
101+
return Model.findOne({
102+
filter: {
103+
where: {
104+
id: $stateParams.modelId
105+
}
106+
}
107+
}).$promise;
108+
}
109+
}],
110+
itemFields: ['model',
111+
function (model) {
112+
var result = [];
113+
angular.forEach(model.properties, function (value, property) {
114+
if (property !== 'id') {
115+
var itemField = {
116+
key: property,
117+
type: 'input',
118+
templateOptions: {
119+
label: property
120+
}
121+
};
122+
result.push(itemField);
123+
}
124+
});
125+
return result;
126+
}]
127+
}
128+
})
129+
.state('app.browser.models.items.add', {
130+
url: '/add',
131+
templateUrl: 'modules/browser/views/models.items.add.html',
132+
controllerAs: 'add',
133+
controller: ['$state', 'SweetAlert', 'Model', 'model', 'itemFields',
134+
function ($state, SweetAlert, Model, model, itemFields) {
135+
this.item = {};
136+
this.itemFields = itemFields;
137+
this.submit = function () {
138+
Model.upsert(this.item).$promise.then(function (res) {
139+
SweetAlert.swal('Saved!', 'The item is saved.', 'success');
140+
$state.go('app.browser.models.items.view', {modelName: model.name, modelId: res.id}, {reload: true});
141+
});
142+
}
143+
}],
144+
resolve: {
145+
Model: ['$stateParams', '$injector',
146+
function ($stateParams, $injector) {
147+
return $injector.get($stateParams.modelName);
148+
}],
149+
itemFields: ['model', function (model) {
150+
var result = [];
151+
angular.forEach(model.properties, function (value, property) {
152+
if (property !== 'id') {
153+
var itemField = {
154+
key: property,
155+
type: 'input',
156+
templateOptions: {
157+
label: property
158+
}
159+
};
160+
result.push(itemField);
161+
}
162+
});
163+
return result;
164+
}]
165+
}
166+
})
167+
.state('app.browser.models.items.delete', {
168+
url: '/:modelId/delete',
169+
template: '',
170+
controller: ['$state', 'SweetAlert', 'Model', 'model', 'item',
171+
function ($state, SweetAlert, Model, model, item) {
172+
SweetAlert.swal({
173+
title: 'Are you sure?',
174+
text: 'Your will not be able to recover this item!',
175+
type: 'warning',
176+
showCancelButton: true,
177+
confirmButtonColor: '#DD6B55', confirmButtonText: 'Yes',
178+
cancelButtonText: 'No',
179+
closeOnConfirm: false,
180+
closeOnCancel: true
181+
},
182+
function (isConfirm) {
183+
if (isConfirm) {
184+
Model.deleteById({id: item.id}).$promise.then(function () {
185+
SweetAlert.swal('Deleted!', 'The item is deleted.', 'success');
186+
$state.go('app.browser.models.items', {modelName: model.name}, {reload: true});
187+
});
188+
} else {
189+
$state.go('app.browser.models.items.view', {modelName: model.name, modelId: item.id}, {reload: true});
190+
}
191+
}
192+
);
193+
}
194+
],
195+
resolve: {
196+
Model: ['$stateParams', '$injector',
197+
function ($stateParams, $injector) {
198+
return $injector.get($stateParams.modelName);
199+
}],
200+
item: ['$stateParams', 'Model',
201+
function ($stateParams, Model) {
202+
if (typeof Model.find !== 'function') {
203+
return false;
204+
} else {
205+
return Model.findOne({
206+
filter: {
207+
where: {
208+
id: $stateParams.modelId
209+
}
210+
}
211+
}).$promise;
212+
}
213+
}
214+
]
215+
}
216+
}
217+
);
218+
});
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
'use strict';
2+
var app = angular.module('com.module.browser');
3+
4+
app.service('BrowserService', ['$state', 'CoreService', 'gettextCatalog',
5+
function ($state, CoreService, gettextCatalog) {
6+
7+
8+
}
9+
]);
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<section admin-header class="content-header"
2+
title="{{ 'Browser' | translate }}"
3+
sub-title="{{ 'Browse your data here!' | translate }}">
4+
</section>
5+
<section ui-view class="content"></section>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<div class="row">
2+
<div class="col-md-3">
3+
<div class="panel panel-default">
4+
<div class="panel-heading">Models</div>
5+
<table class="table">
6+
<tr ng-repeat="model in ctrl.models">
7+
<td>
8+
<a ui-sref="app.browser.models.items({ modelName: model.name })">{{model.name}}</a>
9+
<span ng-if="model.base" class="pull-right text-muted"><small>{{model.base}}</small></span>
10+
</td>
11+
</tr>
12+
</table>
13+
</div>
14+
</div>
15+
<div class="col-md-9">
16+
<ui-view></ui-view>
17+
</div>
18+
</div>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<div class="panel panel-default">
2+
<div class="panel-heading">
3+
Add Item
4+
<span class="pull-right">
5+
<a ui-sref="app.browser.models.items({ modelName: items.model.name })" class="btn btn-xs btn-default">Close</a>
6+
</span>
7+
</div>
8+
<div class="panel-body">
9+
<form ng-submit="add.submit()">
10+
<formly-form model="add.item" fields="add.itemFields">
11+
<button type="submit" class="btn btn-default">Submit</button>
12+
<a ui-sref="app.browser.models.items({ modelName: items.model.name})" class="btn btn-default">Cancel</a>
13+
14+
</formly-form>
15+
</form>
16+
</div>
17+
</div>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<div class="panel panel-default">
2+
<div class="panel-heading">
3+
Edit Item
4+
<span class="pull-right">
5+
<a ui-sref="app.browser.models.items.view({ modelName: items.model.name, modelId: edit.item.id})" class="btn btn-xs btn-default">View</a>
6+
<a ui-sref="app.browser.models.items({ modelName: items.model.name })" class="btn btn-xs btn-default">Close</a>
7+
</span>
8+
</div>
9+
<div class="panel-body">
10+
<form ng-submit="edit.submit()">
11+
<formly-form model="edit.item" fields="edit.itemFields">
12+
<button type="submit" class="btn btn-default">Submit</button>
13+
<a ui-sref="app.browser.models.items.view({ modelName: items.model.name, modelId: edit.item.id})" class="btn btn-default">Cancel</a>
14+
15+
</formly-form>
16+
</form>
17+
</div>
18+
</div>
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<div class="col-lg-8">
2+
<div class="panel panel-default">
3+
<div class="panel-heading">
4+
{{items.model.name}}
5+
6+
<span class="pull-right">
7+
<a ui-sref="app.browser.models.items.add({ modelName: items.model.name})" class="btn btn-xs btn-default">Add</a>
8+
</span>
9+
10+
</div>
11+
12+
<alert ng-if="!items.items || !items.items.length" type="alert alert-info">
13+
No items found
14+
<span ng-if="items.model.name">for {{items.model.name}}</span>
15+
</alert>
16+
17+
<div class="table-responsive" ng-if="items.items && items.items.length" style="overflow: auto">
18+
<table class="table table-striped" ng-if="items.itemKeys">
19+
<tr>
20+
<th class="col-md-1">&nbsp;</th>
21+
<th ng-repeat="itemKey in items.itemKeys">{{itemKey}}</th>
22+
</tr>
23+
<tr ng-repeat="item in items.items">
24+
<td class="text-nowrap">
25+
<a ui-sref="app.browser.models.items.view({ modelName: items.model.name, modelId: item.id })" class="btn btn-default btn-xs">
26+
<i class="fa fa-eye"></i>
27+
</a>
28+
<a ui-sref="app.browser.models.items.edit({ modelName: items.model.name, modelId: item.id })" class="btn btn-default btn-xs">
29+
<i class="fa fa-pencil"></i>
30+
</a>
31+
<a ui-sref="app.browser.models.items.delete({ modelName: items.model.name, modelId: item.id })" class="btn btn-default btn-xs">
32+
<i class="fa fa-trash-o"></i>
33+
</a>
34+
</td>
35+
<td ng-repeat="itemKey in items.itemKeys" class="text-nowrap">
36+
<span ng-if="itemKey == 'id' || itemKey == 'name' || itemKey == 'title' ">
37+
<a ui-sref="app.browser.models.items.view({ modelName: items.model.name, modelId: item.id })">
38+
{{item[itemKey]}}
39+
</a>
40+
</span>
41+
<span ng-if="itemKey != 'id' && itemKey != 'name' && itemKey != 'title' ">
42+
{{item[itemKey]}}
43+
</span>
44+
</td>
45+
</tr>
46+
</table>
47+
</div>
48+
</div>
49+
</div>
50+
<div class="col-lg-4">
51+
52+
<ui-view></ui-view>
53+
54+
<div class="panel panel-default">
55+
<div class="panel-heading">Model Properties</div>
56+
<pre>{{items.model|json}}</pre>
57+
</div>
58+
</div>

0 commit comments

Comments
 (0)