in ui-modules/catalog/app/views/bundle/type/type.state.js [54:289]
export function typeController($scope, $state, $stateParams, $q, $uibModal, brBrandInfo, brUtilsGeneral, brSnackbar, catalogApi, mdHelper, quickLaunchOverrides) {
const quickLaunchHelper = {}
quickLaunchOverrides.configureQuickLaunch(quickLaunchHelper, $scope);
$scope.state = {
default: 2,
limit: 2
};
$scope.toggleSupertypes = () => {
$scope.state.limit = $scope.state.limit === $scope.state.default ? $scope.type.supertypes.length : $scope.state.default;
};
$scope.isEditable = () => $scope.type && $scope.type.containingBundle.startsWith('catalog-bom');
$scope.isDeployable = () => {
return $scope.type && $scope.type.supertypes.some(supertype =>
['org.apache.brooklyn.api.entity.Application', 'org.apache.brooklyn.api.entity.Entity'].includes(supertype)
);
};
$scope.isNonNull = (o) => typeof o !== 'undefined' && o!=null;
$scope.isNonEmpty = (o) => brUtilsGeneral.isNonEmpty(o);
$scope.composerUrl = brBrandInfo.blueprintComposerBaseUrl;
// needed to avoid bug cause by object-based constraints
$scope.hasEntry = (list, v) => list.find((entry) => (typeof entry === 'string') && entry.toUpperCase() === v.toUpperCase());
$scope.deploy = (event) => {
const instance = $uibModal.open({
template: modalTemplate,
controller: ['$scope', '$location', 'entitySpec', 'locations', 'quickLaunchOverrides', modalController],
size: 'lg',
backdrop: 'static',
windowClass: 'quick-launch-modal',
resolve: {
entitySpec: ()=> $scope.type,
locations: ['locationApi', (locationApi) => locationApi.getLocations()],
},
scope: $scope
});
// If modal resolve fails, it means that we cannot open the deployment modal => inform the user
instance.opened.catch((reason)=> {
brSnackbar.create('Cannot load deployment information for ' + item.symbolicName + ':' + item.version);
});
// `instance.result` is resolved when the modal is closed, it means that we have successfully deployed our app
instance.result
.then(({ data }) => {
brSnackbar.create('Application deployed', {
label: 'View',
callback: () => {
window.location.href = brBrandInfo.getAppDeployedUrl(data.entityId, data.entityId);
},
});
})
.catch(event => { /* prevents console errors on close */ });
function modalController($scope, $location, entitySpec, locations) {
$scope.app = entitySpec;
$scope.locations = locations;
$scope.args = $location.search();
}
event.preventDefault();
event.stopPropagation();
};
$q.all([
catalogApi.getBundle($stateParams.bundleId, $stateParams.bundleVersion),
catalogApi.getBundleType($stateParams.bundleId, $stateParams.bundleVersion, $stateParams.typeId, $stateParams.typeVersion),
catalogApi.getTypeVersions($stateParams.typeId),
])
.then(async responses => {
$scope.bundle = responses[0];
$scope.type = responses[1];
const entitySpec = $scope.type;
// update entity spec to keep the right format (repeated in home deploy.controller.js)
const specItem = entitySpec.specList[0];
// if the implementation plan does not declare its format but the first spec list item does
// then we should replace the low-level implementation plan (probably auto-generated) with
// the first spec list item (which is what the user created)
var preferredContents = entitySpec.plan && entitySpec.plan.data;
const { parsedPlan } = await quickLaunchHelper.getAsCampPlan(entitySpec.plan);
$scope.templateConfigValues =
(parsedPlan && parsedPlan['brooklyn.config']) ||
(parsedPlan && parsedPlan.services && parsedPlan.services.length==1 && parsedPlan.services[0]['brooklyn.config']) ||
{};
var preferredFormat = entitySpec.plan && entitySpec.plan.format;
if (!preferredFormat) {
if (specItem && specItem.format && specItem.contents) {
preferredFormat = specItem.format;
// also take those contents
preferredContents = specItem.contents;
entitySpec.plan = { data: preferredContents, format: preferredFormat };
}
}
// save this as the initially selected item in the dropdown of the definition
this.specItem = specItem;
// this is used to link to the right editor in composer, preserve the format used to define the item being quick-launched
$scope.typeFormat = preferredFormat ? 'format=' + preferredFormat + '&' : '';
$scope.versions = responses[2].map(typeVersion => ({
bundleSymbolicName: typeVersion.containingBundle.split(':')[0],
bundleVersion: typeVersion.containingBundle.split(':')[1],
typeVersion: typeVersion.version,
}));
$scope.typeDescription = mdHelper.analyze( ($scope.type || {}).description );
$scope.$emit(HIDE_INTERSTITIAL_SPINNER_EVENT);
})
.catch(error => {
brSnackbar.create(`Could not load type ${$stateParams.bundleId}:${$stateParams.bundleVersion}: ${error.status === 404 ? 'Not found' : error.message}`);
$state.go(catalogState);
});
$scope.tables = { config: [], sensors: [], effectors: []};
$scope.markdown = mdHelper.analyze;
function addColumn(tables, base={}) {
Object.entries(tables).forEach(([tableKey, props]) => {
$scope.tables[tableKey].push({ ...base, ...props });
});
};
addColumn( {
config: { header: 'Config Key' },
sensors: { header: 'Sensor' },
effectors: { header: 'Effector' },
}, {
field: 'name',
template: '<div class="mozilla-td-scroll-fix"><samp>{{ item.name }}</samp></div>',
width: 100,
colspan: 3,
});
addColumn({
config: {
field: 'label',
colspan: 3,
hidden: true,
},
});
addColumn( {
config: {},
sensors: {},
effectors: { field: 'returnType' },
}, {
field: 'type',
template: '<div class="mozilla-td-scroll-fix"><span class="label-color column-for-type oneline label label-success">{{ item[column.field] }}</span></div>',
colspan: 3,
} );
addColumn( {
config: {},
sensors: {},
effectors: {},
}, {
field: 'description',
width: 150,
colspan: 6,
template: '<div class="mozilla-td-scroll-fix"><md-field raw-data="item[column.field]"></md-field></div>',
tdClass: 'column-for-description',
});
addColumn({
config: {
field: 'defaultValue',
colspan: 5,
template: '<div class="mozilla-td-scroll-fix">' +
'<p ng-if="isNonNull(templateConfigValues[item.name])"><samp>{{ templateConfigValues[item.name] }}</samp>' +
'<span class="label-color oneline label label-info" style="margin-left: 1em;">template</span></p>' +
'<p ng-if="isNonNull(item.defaultValue)"><samp>{{ item.defaultValue }}</samp></span>' +
'<span ng-if="isNonNull(templateConfigValues[item.name])" class="label-color oneline label label-supertype" style="margin-left: 1em;">parameter</span></div>',
},
});
addColumn({
config: {
field: 'priority',
template: '<div style="display: flex; justify-content: flex-end;">{{ item.priority }}</div>',
width: 75,
hidden: true,
},
});
addColumn({
config: {
field: 'pinned',
width: 75,
tdClass: 'center',
template: '<i class="fa fa-check" ng-if="item.pinned"/>',
}
});
addColumn({
config:
{
field: 'reconfigurable',
width: 120,
tdClass: 'center',
hidden: true,
template: '<i class="fa fa-check" ng-if="item.reconfigurable"/>',
}
});
addColumn({
config:
{
field: 'required',
width: 85,
tdClass: 'center',
orderBy: null,
template: '<i class="fa fa-check" ng-if="hasEntry(item.constraints, \'required\')"/>',
}
});
addColumn({
config: {
field: 'constraints',
width: 120,
colspan: 2,
hidden: true,
template: '<div class="mozilla-td-scroll-fix"><samp>{{ item.constraints }}</samp></div>',
}
});
addColumn({
effectors: {
field: 'parameters',
width: 100,
colspan: 4,
templateUrl: 'catalog/type/effector/parameters.html',
}
});
}