blob: fcb9e00abd13999d32d147fce8997ebff8fdece6 [file] [log] [blame]
Matteo Scandolofb46ae62017-08-08 09:10:50 -07001
2/*
3 * Copyright 2017-present Open Networking Foundation
4
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8
9 * http://www.apache.org/licenses/LICENSE-2.0
10
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18
Matteo Scandolod58d5042016-12-16 16:59:21 -080019import * as _ from 'lodash';
20import * as pluralize from 'pluralize';
Matteo Scandolocb466ed2017-01-04 17:16:24 -080021import {IXosTableColumn, IXosTableCfg} from '../../table/table';
Matteo Scandolo1aee1982017-02-17 08:33:23 -080022import {IXosModeldef} from '../../../datasources/rest/modeldefs.rest';
Matteo Scandoloe7e052d2017-07-31 19:54:31 -070023import {IXosFormCfg, IXosFormInput, IXosFormInputValidator, IXosFormInputOptions} from '../../form/form';
Matteo Scandolo47860fe2017-02-02 12:05:55 -080024import {IXosModelStoreService} from '../../../datasources/stores/model.store';
Matteo Scandolo1aee1982017-02-17 08:33:23 -080025import {IXosState} from '../runtime-states';
Matteo Scandolo63498472017-09-26 17:21:41 -070026import {IXosFormHelpersService} from '../../form/form-helpers';
Matteo Scandolo1aee1982017-02-17 08:33:23 -080027
28export interface IXosModelDefsFieldValidators {
29 name: string;
30 bool_value?: boolean;
31 int_value?: number;
32}
Matteo Scandolod58d5042016-12-16 16:59:21 -080033
34export interface IXosModelDefsField {
35 name: string;
36 type: string;
Matteo Scandolod67adee2018-03-08 16:27:05 -080037 read_only: boolean;
Matteo Scandolo1aee1982017-02-17 08:33:23 -080038 validators?: IXosModelDefsFieldValidators[];
Matteo Scandolo04964232017-01-07 12:53:46 -080039 hint?: string;
40 relation?: {
41 model: string;
42 type: string;
43 };
Matteo Scandoloe7e052d2017-07-31 19:54:31 -070044 options?: IXosFormInputOptions[];
45 default?: any | null;
Matteo Scandolod58d5042016-12-16 16:59:21 -080046}
47
48export interface IXosConfigHelpersService {
Matteo Scandolob310f3c2019-06-20 13:50:31 -070049 base_excluded_fields: string[];
Matteo Scandoloee655a12016-12-19 15:38:43 -080050 excluded_fields: string[];
Matteo Scandoloc8a58c82017-08-17 17:14:38 -070051 form_excluded_fields: string[];
Matteo Scandolo1aee1982017-02-17 08:33:23 -080052 modelFieldsToColumnsCfg(model: IXosModeldef): IXosTableColumn[];
53 modelToTableCfg(model: IXosModeldef, modelName: string): IXosTableCfg;
Matteo Scandolo80c3a652017-01-06 10:48:31 -080054 modelFieldToInputCfg(fields: IXosModelDefsField[]): IXosFormInput[];
Matteo Scandolo1aee1982017-02-17 08:33:23 -080055 modelToFormCfg(model: IXosModeldef): IXosFormCfg;
Matteo Scandolod58d5042016-12-16 16:59:21 -080056 pluralize(string: string, quantity?: number, count?: boolean): string;
57 toLabel(string: string, pluralize?: boolean): string;
Matteo Scandoloe0d71ea2016-12-19 11:56:12 -080058 toLabels(string: string[], pluralize?: boolean): string[];
Matteo Scandoloa242c872017-01-12 15:13:00 -080059 stateFromCoreModel(name: string): string;
60 stateWithParams(name: string, model: any): string;
Matteo Scandolo8248bca2017-08-09 13:46:04 -070061 relatedStateWithParams(name: string, id: string): string;
Matteo Scandolo86bc26a2017-01-18 11:06:47 -080062 stateWithParamsForJs(name: string, model: any): any;
Matteo Scandolod58d5042016-12-16 16:59:21 -080063}
64
Matteo Scandolo8b2370c2017-02-02 17:19:07 -080065export class ConfigHelpers implements IXosConfigHelpersService {
Matteo Scandolo1aee1982017-02-17 08:33:23 -080066 static $inject = [
Matteo Scandolo63498472017-09-26 17:21:41 -070067 '$q',
Matteo Scandolo1aee1982017-02-17 08:33:23 -080068 '$state',
69 'toastr',
Matteo Scandolo63498472017-09-26 17:21:41 -070070 'XosModelStore',
71 'XosFormHelpers'
72 ];
Matteo Scandolod58d5042016-12-16 16:59:21 -080073
Matteo Scandolob310f3c2019-06-20 13:50:31 -070074 public base_excluded_fields = [
Matteo Scandoloee655a12016-12-19 15:38:43 -080075 'created',
76 'updated',
77 'enacted',
78 'policed',
79 'backend_register',
80 'deleted',
81 'write_protect',
82 'lazy_blocked',
83 'no_sync',
84 'no_policy',
85 'omf_friendly',
86 'enabled',
Matteo Scandolod62ea792016-12-22 14:02:28 -080087 'validators',
Matteo Scandolo80c3a652017-01-06 10:48:31 -080088 'password',
89 'backend_need_delete',
Scott Bakere5dcb9a2017-09-07 10:18:06 -070090 'backend_need_delete_policy',
Matteo Scandolod53ac1d2017-08-01 15:06:09 -070091 'backend_need_reap',
Scott Bakere5dcb9a2017-09-07 10:18:06 -070092 'leaf_model_name',
93 'link_deleted_count',
Matteo Scandolo8cd21b02017-09-20 10:13:13 +090094 'policy_code',
vigneshethiraj98b2b892019-05-25 16:43:08 +053095 'backend_code'
Matteo Scandoloee655a12016-12-19 15:38:43 -080096 ];
97
Matteo Scandolob310f3c2019-06-20 13:50:31 -070098 public excluded_fields = angular.copy(this.base_excluded_fields);
99
Matteo Scandolod53ac1d2017-08-01 15:06:09 -0700100 public form_excluded_fields = this.excluded_fields.concat([
101 'id',
102 'policy_status',
Matteo Scandoloa9fe46b2018-07-16 14:58:19 -0400103 'backend_status'
Matteo Scandolod53ac1d2017-08-01 15:06:09 -0700104 ]);
105
Matteo Scandolocb466ed2017-01-04 17:16:24 -0800106 constructor(
Matteo Scandolo63498472017-09-26 17:21:41 -0700107 private $q: ng.IQService,
Matteo Scandoloa242c872017-01-12 15:13:00 -0800108 private $state: ng.ui.IStateService,
Matteo Scandolo0a8b02e2017-01-06 14:43:36 -0800109 private toastr: ng.toastr.IToastrService,
Matteo Scandolo63498472017-09-26 17:21:41 -0700110 private XosModelStore: IXosModelStoreService,
111 private XosFormHelpers: IXosFormHelpersService
Matteo Scandolocb466ed2017-01-04 17:16:24 -0800112 ) {
Matteo Scandolo08464e52017-01-17 13:35:27 -0800113 pluralize.addIrregularRule('xos', 'xoses');
Matteo Scandolod58d5042016-12-16 16:59:21 -0800114 pluralize.addPluralRule(/slice$/i, 'slices');
Matteo Scandolo8bd01ad2018-05-14 13:26:35 -0700115 pluralize.addPluralRule(/data/i, 'datas');
Matteo Scandolo80c3a652017-01-06 10:48:31 -0800116 pluralize.addSingularRule(/slice$/i, 'slice');
Matteo Scandolo5d962a32017-08-01 18:16:14 -0700117 pluralize.addPluralRule(/imagedeployments/i, 'imagedeploymentss');
Scott Baker0d4c34e2018-10-05 10:45:09 -0700118 pluralize.addPluralRule(/controllerimages/i, 'controllerimageses');
Matteo Scandolo5d962a32017-08-01 18:16:14 -0700119 pluralize.addPluralRule(/servicedependency/i, 'servicedependencys');
Matteo Scandolod58d5042016-12-16 16:59:21 -0800120 }
121
Matteo Scandolo1c5905f2017-01-04 17:41:15 -0800122 public pluralize(string: string, quantity?: number, count?: boolean): string {
Matteo Scandolod58d5042016-12-16 16:59:21 -0800123 return pluralize(string, quantity, count);
124 }
125
Matteo Scandolo1c5905f2017-01-04 17:41:15 -0800126 public toLabels(strings: string[], pluralize?: boolean): string[] {
Matteo Scandoloe0d71ea2016-12-19 11:56:12 -0800127 if (angular.isArray(strings)) {
128 return _.map(strings, s => {
Matteo Scandolod58d5042016-12-16 16:59:21 -0800129 return this.toLabel(s, pluralize);
130 });
131 }
Matteo Scandoloe0d71ea2016-12-19 11:56:12 -0800132 }
133
Matteo Scandolo1c5905f2017-01-04 17:41:15 -0800134 public toLabel(string: string, pluralize?: boolean): string {
Matteo Scandolod58d5042016-12-16 16:59:21 -0800135
136 if (pluralize) {
137 string = this.pluralize(string);
138 }
139
140 string = this.fromCamelCase(string);
141 string = this.fromSnakeCase(string);
142 string = this.fromKebabCase(string);
143
144 return this.capitalizeFirst(string);
145 }
146
Matteo Scandolo1aee1982017-02-17 08:33:23 -0800147 public modelToTableCfg(model: IXosModeldef, baseUrl: string): IXosTableCfg {
Matteo Scandolob310f3c2019-06-20 13:50:31 -0700148 this.reset_excluded_fields();
Matteo Scandolocb466ed2017-01-04 17:16:24 -0800149 const cfg = {
Matteo Scandolo1aee1982017-02-17 08:33:23 -0800150 columns: this.modelFieldsToColumnsCfg(model),
Matteo Scandolocb466ed2017-01-04 17:16:24 -0800151 filter: 'fulltext',
152 order: {field: 'id', reverse: false},
Matteo Scandolo8b2370c2017-02-02 17:19:07 -0800153 pagination: {
154 pageSize: 10
155 },
Matteo Scandolocb466ed2017-01-04 17:16:24 -0800156 actions: [
157 {
Matteo Scandolocc4bce82017-08-07 13:11:47 -0700158 label: 'details',
159 icon: 'search',
160 cb: (item) => {
Matteo Scandoloe6f87d32019-05-24 15:59:16 -0700161 const state = this.stateWithParamsForJs(item.leaf_model_name, item.id);
162 this.$state.go(state.name, state.params);
Matteo Scandolocc4bce82017-08-07 13:11:47 -0700163 }
164 },
165 {
Matteo Scandolocb466ed2017-01-04 17:16:24 -0800166 label: 'delete',
167 icon: 'remove',
168 color: 'red',
169 cb: (item) => {
170 let obj = angular.copy(item);
Max Chubab0a582017-09-06 08:32:34 -0700171 const objName = (angular.isUndefined(obj.name)) ? 'instance' : obj.name;
Matteo Scandolocb466ed2017-01-04 17:16:24 -0800172
173 item.$delete()
174 .then((res) => {
175 if (res.status === 404) {
176 // TODO understand why it does not go directly in catch
177 throw new Error();
178 }
Matteo Scandoloe9cdf9a2017-11-21 10:41:28 -0800179 this.toastr.info(`Requested removal for ${model.name} ${objName}`);
Matteo Scandolocb466ed2017-01-04 17:16:24 -0800180 })
181 .catch(() => {
Max Chubab0a582017-09-06 08:32:34 -0700182 this.toastr.error(`Error while deleting ${objName}`);
Matteo Scandolocb466ed2017-01-04 17:16:24 -0800183 });
184 }
185 }
186 ]
187 };
188 return cfg;
189 }
190
Matteo Scandolo1aee1982017-02-17 08:33:23 -0800191 public modelFieldsToColumnsCfg(model: IXosModeldef): IXosTableColumn[] {
192 const fields: IXosModelDefsField[] = model.fields;
193 const modelName: string = model.name;
Matteo Scandolo231de262017-01-04 16:33:14 -0800194 const columns = _.map(fields, (f) => {
vigneshethiraj98b2b892019-05-25 16:43:08 +0530195 if (model.sync_implemented !== 'True') {
196 this.excluded_fields.push('backend_status');
197 }
198
199 if (model.policy_implemented !== 'True') {
200 this.excluded_fields.push('policy_status');
201 }
202
Matteo Scandolob310f3c2019-06-20 13:50:31 -0700203 if (!angular.isDefined(f) || this.excluded_fields.indexOf(f.name) > -1) {
204 return;
205 }
206 const col: IXosTableColumn = {
207 label: this.toLabel(f.name),
208 prop: f.name
209 };
210
Matteo Scandoloa8a6fbb2016-12-21 16:59:08 -0800211 if (f.name === 'id' || f.name === 'name') {
Matteo Scandolo1888b2a2018-01-08 16:49:06 -0800212 col.link = item => this.stateWithParamsForJs(modelName, item.id);
Matteo Scandoloee655a12016-12-19 15:38:43 -0800213 }
214
Matteo Scandolo04964232017-01-07 12:53:46 -0800215 // if the field identify a relation, create a link
Matteo Scandolo18975142017-08-01 14:48:04 -0700216 if (f.relation && f.relation.type === 'manytoone') {
Matteo Scandolo04964232017-01-07 12:53:46 -0800217 col.type = 'custom';
218 col.formatter = item => {
219 this.populateRelated(item, item[f.name], f);
220 return item[f.name];
221 };
Matteo Scandolo1888b2a2018-01-08 16:49:06 -0800222 col.link = item => this.stateWithParamsForJs(f.relation.model, item[col.prop]);
Matteo Scandolo04964232017-01-07 12:53:46 -0800223 }
224
Matteo Scandolod53ac1d2017-08-01 15:06:09 -0700225 if (f.name === 'backend_status' || f.name === 'policy_status') {
Matteo Scandolo8cd21b02017-09-20 10:13:13 +0900226
227 const statusCol = f.name === 'backend_status' ? 'backend_code' : 'policy_code';
228
Matteo Scandolod58d5042016-12-16 16:59:21 -0800229 col.type = 'icon';
Matteo Scandolo8b2370c2017-02-02 17:19:07 -0800230 col.hover = (item) => {
231 return item[f.name];
232 };
Matteo Scandolod58d5042016-12-16 16:59:21 -0800233 col.formatter = (item) => {
Matteo Scandolo8cd21b02017-09-20 10:13:13 +0900234 if (parseInt(item[statusCol], 10) === 1) {
Matteo Scandolod58d5042016-12-16 16:59:21 -0800235 return 'check';
236 }
Matteo Scandolo8cd21b02017-09-20 10:13:13 +0900237 if (parseInt(item[statusCol], 10) === 2) {
Matteo Scandolod58d5042016-12-16 16:59:21 -0800238 return 'exclamation-circle';
239 }
Matteo Scandolo8cd21b02017-09-20 10:13:13 +0900240 if (parseInt(item[statusCol], 10) === 0) {
Matteo Scandolod58d5042016-12-16 16:59:21 -0800241 return 'clock-o';
242 }
243 };
244 }
Matteo Scandoloa8a6fbb2016-12-21 16:59:08 -0800245
Matteo Scandolod58d5042016-12-16 16:59:21 -0800246 return col;
247 })
248 .filter(v => angular.isDefined(v));
249
Matteo Scandolo231de262017-01-04 16:33:14 -0800250 return columns;
Matteo Scandolod58d5042016-12-16 16:59:21 -0800251 };
252
Matteo Scandoloa242c872017-01-12 15:13:00 -0800253 public stateFromCoreModel(name: string): string {
254 const state: ng.ui.IState = _.find(this.$state.get(), (s: IXosState) => {
255 if (s.data) {
256 return s.data.model === name;
257 }
258 return false;
259 });
Matteo Scandolo1aee1982017-02-17 08:33:23 -0800260 return state ? state.name : null;
Matteo Scandoloa242c872017-01-12 15:13:00 -0800261 }
262
263 public stateWithParams(name: string, model: any): string {
264 const state = this.stateFromCoreModel(name);
265 return `${state}({id: ${model['id']}})`;
266 }
267
Matteo Scandolo8248bca2017-08-09 13:46:04 -0700268 public relatedStateWithParams(name: string, id: string): string {
269 const state = this.stateFromCoreModel(name);
270 return `${state}({id: ${id}})`;
271 }
272
Matteo Scandolo1888b2a2018-01-08 16:49:06 -0800273 public stateWithParamsForJs(name: string, id: number): any {
Matteo Scandolo86bc26a2017-01-18 11:06:47 -0800274 const state = this.stateFromCoreModel(name);
Matteo Scandolo1888b2a2018-01-08 16:49:06 -0800275 return {name: state, params: {id: id}};
Matteo Scandolo86bc26a2017-01-18 11:06:47 -0800276 }
277
Matteo Scandolo80c3a652017-01-06 10:48:31 -0800278 public modelFieldToInputCfg(fields: IXosModelDefsField[]): IXosFormInput[] {
279
Matteo Scandolo6f45e262017-01-09 14:47:26 -0800280 return _.map(fields, (f: IXosModelDefsField) => {
Matteo Scandolo1aee1982017-02-17 08:33:23 -0800281 const input: IXosFormInput = {
Matteo Scandolo80c3a652017-01-06 10:48:31 -0800282 name: f.name,
283 label: this.toLabel(f.name),
284 type: f.type,
Matteo Scandolo1aee1982017-02-17 08:33:23 -0800285 validators: this.formatValidators(f.validators),
Matteo Scandoloe7e052d2017-07-31 19:54:31 -0700286 hint: f.hint,
Matteo Scandolod67adee2018-03-08 16:27:05 -0800287 default: this.formatDefaultValues(f.default),
288 read_only: f.read_only
Matteo Scandolo80c3a652017-01-06 10:48:31 -0800289 };
Matteo Scandoloe7e052d2017-07-31 19:54:31 -0700290
291 // NOTE populate drop-downs based on relation
Matteo Scandolo1aee1982017-02-17 08:33:23 -0800292 if (f.relation) {
293 input.type = 'select';
294 this.populateSelectField(f, input);
Matteo Scandoloe7e052d2017-07-31 19:54:31 -0700295 }
296 // NOTE if static options are defined in modeldefs
297 // the f.options field is already populated,
298 // we just need to move it to the input
299 else if (f.options && f.options.length > 0) {
300 input.options = f.options;
Matteo Scandolo1aee1982017-02-17 08:33:23 -0800301 }
302 return input;
Matteo Scandolo80c3a652017-01-06 10:48:31 -0800303 })
Matteo Scandolod53ac1d2017-08-01 15:06:09 -0700304 .filter(f => this.form_excluded_fields.indexOf(f.name) === -1);
Matteo Scandolo80c3a652017-01-06 10:48:31 -0800305 }
306
Matteo Scandolo1aee1982017-02-17 08:33:23 -0800307 public modelToFormCfg(model: IXosModeldef): IXosFormCfg {
Matteo Scandolof1e68cd2017-09-05 17:30:34 -0700308
Matteo Scandolo1aee1982017-02-17 08:33:23 -0800309 const formCfg: IXosFormCfg = {
Matteo Scandolo80c3a652017-01-06 10:48:31 -0800310 formName: `${model.name}Form`,
Matteo Scandolod53ac1d2017-08-01 15:06:09 -0700311 exclude: this.form_excluded_fields,
Matteo Scandolo80c3a652017-01-06 10:48:31 -0800312 actions: [{
313 label: 'Save',
314 class: 'success',
315 icon: 'ok',
Matteo Scandolo6f45e262017-01-09 14:47:26 -0800316 cb: null
Matteo Scandolo80c3a652017-01-06 10:48:31 -0800317 }],
318 inputs: this.modelFieldToInputCfg(model.fields)
319 };
Matteo Scandolo6f45e262017-01-09 14:47:26 -0800320
321 formCfg.actions[0].cb = (item, form: angular.IFormController) => {
Matteo Scandolo63498472017-09-26 17:21:41 -0700322 const d = this.$q.defer();
Matteo Scandolo6f45e262017-01-09 14:47:26 -0800323 if (!form.$valid) {
324 formCfg.feedback = {
325 show: true,
326 message: 'Form is invalid',
327 type: 'danger',
328 closeBtn: true
329 };
Matteo Scandoloac8c8c22017-01-09 15:04:32 -0800330
Matteo Scandolo6f45e262017-01-09 14:47:26 -0800331 return;
332 }
Matteo Scandolo6f64a742018-06-22 14:25:59 -0700333 // remove fields that are not part of the model
Matteo Scandolo620cb492017-11-27 16:56:36 -0800334 item = this.removeExtraFields(item, model);
Matteo Scandolo6f45e262017-01-09 14:47:26 -0800335
Matteo Scandolo620cb492017-11-27 16:56:36 -0800336 const itemCopy = angular.copy(item);
Max Chubab0a582017-09-06 08:32:34 -0700337 const itemName = (angular.isUndefined(itemCopy.name)) ? model.name : itemCopy.name;
338
Matteo Scandolo6f45e262017-01-09 14:47:26 -0800339 item.$save()
340 .then((res) => {
Matteo Scandoloac8c8c22017-01-09 15:04:32 -0800341 formCfg.feedback = {
342 show: true,
Max Chubab0a582017-09-06 08:32:34 -0700343 message: `${itemName} successfully saved`,
Matteo Scandoloac8c8c22017-01-09 15:04:32 -0800344 type: 'success',
345 closeBtn: true
346 };
Max Chubab0a582017-09-06 08:32:34 -0700347 this.toastr.success(`${itemName} successfully saved`);
Matteo Scandolo63498472017-09-26 17:21:41 -0700348 d.resolve(res);
Matteo Scandolo6f45e262017-01-09 14:47:26 -0800349 })
350 .catch(err => {
Matteo Scandolo39e04152017-11-29 14:24:45 -0800351 const errorMsg = err.specific_error || err.error || 'Internal Server Error';
Matteo Scandolo42c66922017-05-01 17:24:59 -0700352 formCfg.feedback = {
353 show: true,
Matteo Scandolo39e04152017-11-29 14:24:45 -0800354 message: `Error while saving ${itemName}: ${errorMsg}.`,
Matteo Scandolo42c66922017-05-01 17:24:59 -0700355 type: 'danger',
356 closeBtn: true
357 };
Matteo Scandolo39e04152017-11-29 14:24:45 -0800358 this.toastr.error(err.specific_error || '', `Error while saving ${itemName}: ${errorMsg}`);
Matteo Scandolo63498472017-09-26 17:21:41 -0700359 d.reject(err);
Matteo Scandolo6f45e262017-01-09 14:47:26 -0800360 });
Matteo Scandolo63498472017-09-26 17:21:41 -0700361
362 return d.promise;
Matteo Scandolo6f45e262017-01-09 14:47:26 -0800363 };
364
365 return formCfg;
Matteo Scandolo80c3a652017-01-06 10:48:31 -0800366 }
367
Matteo Scandolo620cb492017-11-27 16:56:36 -0800368 private removeExtraFields(item: any, modelDef: IXosModeldef) {
369 _.forEach(Object.keys(item), prop => {
Matteo Scandolo6f64a742018-06-22 14:25:59 -0700370 const field = _.find(modelDef.fields, {name: prop});
371 const hasField = angular.isDefined(field);
372 if (!hasField || field.read_only) {
Matteo Scandolo620cb492017-11-27 16:56:36 -0800373 delete item[prop];
374 }
375 });
376 return item;
377 }
378
Matteo Scandolof1e68cd2017-09-05 17:30:34 -0700379 private formatDefaultValues(val: any): any {
380
381 if (angular.isString(val)) {
382 const unquoted = val.split('"').join('').toLowerCase();
383 if (unquoted === 'true') {
384 return true;
385 }
386 else if (unquoted === 'false') {
387 return false;
388 }
389 }
390
391 return val || undefined;
392 }
393
Matteo Scandolo1aee1982017-02-17 08:33:23 -0800394 private formatValidators(validators: IXosModelDefsFieldValidators[]): IXosFormInputValidator {
395 // convert validators as expressed from modelDefs,
396 // to the object required by xosForm
397 return _.reduce(validators, (formValidators: IXosFormInputValidator, v: IXosModelDefsFieldValidators) => {
398 formValidators[v.name] = v.bool_value ? v.bool_value : v.int_value;
399 return formValidators;
400 }, {});
401 }
402
Matteo Scandolod58d5042016-12-16 16:59:21 -0800403 private fromCamelCase(string: string): string {
404 return string.split(/(?=[A-Z])/).map(w => w.toLowerCase()).join(' ');
405 }
406
407 private fromSnakeCase(string: string): string {
408 return string.split('_').join(' ').trim();
409 }
410
411 private fromKebabCase(string: string): string {
412 return string.split('-').join(' ').trim();
413 }
414
415 private capitalizeFirst(string: string): string {
416 return string.slice(0, 1).toUpperCase() + string.slice(1);
417 }
Matteo Scandolo04964232017-01-07 12:53:46 -0800418
419 private populateRelated(item: any, fk: string, field: IXosModelDefsField): any {
420 // if the relation is not defined return
421 if (!fk || angular.isUndefined(fk) || fk === null) {
422 return;
423 }
Matteo Scandolo1aee1982017-02-17 08:33:23 -0800424 this.XosModelStore.query(field.relation.model)
Matteo Scandolo04964232017-01-07 12:53:46 -0800425 .subscribe(res => {
426 if (angular.isDefined(res) && angular.isDefined(fk)) {
427 let ri = _.find(res, {id: fk});
428 if (angular.isDefined(ri)) {
Matteo Scandolo1aee1982017-02-17 08:33:23 -0800429 if (angular.isDefined(ri.name)) {
430 item[`${field.name}-formatted`] = ri.name;
431 }
432 else if (angular.isDefined(ri.humanReadableName)) {
433 item[`${field.name}-formatted`] = ri.humanReadableName;
434 }
435 else {
436 item[`${field.name}-formatted`] = ri.id;
437 }
Matteo Scandolo04964232017-01-07 12:53:46 -0800438 }
439 }
440 });
441 }
Matteo Scandolo07e2f622017-01-09 10:54:13 -0800442
443 // augment a select field with related model informations
444 private populateSelectField(field: IXosModelDefsField, input: IXosFormInput): void {
Matteo Scandolo1aee1982017-02-17 08:33:23 -0800445 this.XosModelStore.query(field.relation.model)
Matteo Scandolo07e2f622017-01-09 10:54:13 -0800446 .subscribe(res => {
447 input.options = _.map(res, item => {
Matteo Scandolo1aee1982017-02-17 08:33:23 -0800448 let opt = {id: item.id, label: item.humanReadableName ? item.humanReadableName : item.name};
449 if (!angular.isDefined(item.humanReadableName) && !angular.isDefined(item.name)) {
450 opt.label = item.id;
451 }
452 return opt;
Matteo Scandolo07e2f622017-01-09 10:54:13 -0800453 });
454 });
455 }
Matteo Scandolob310f3c2019-06-20 13:50:31 -0700456
457 private reset_excluded_fields() {
458 this.excluded_fields = angular.copy(this.base_excluded_fields);
459 }
Matteo Scandolod58d5042016-12-16 16:59:21 -0800460}