Add lib stepper and integration

This commit is contained in:
Vladyslav_Prykhodko 2019-05-24 15:58:13 +03:00
parent 07cd8b9978
commit 3f30e3d74f
5 changed files with 246 additions and 177 deletions

View File

@ -64,6 +64,7 @@
"jstree-bootstrap-theme": "^1.0.1", "jstree-bootstrap-theme": "^1.0.1",
"leaflet": "^1.0.3", "leaflet": "^1.0.3",
"leaflet-providers": "^1.1.17", "leaflet-providers": "^1.1.17",
"material-steppers": "^2.0.0",
"material-ui": "^0.16.1", "material-ui": "^0.16.1",
"material-ui-number-input": "^5.0.16", "material-ui-number-input": "^5.0.16",
"md-color-picker": "0.2.6", "md-color-picker": "0.2.6",

View File

@ -179,15 +179,15 @@ function DeviceService($http, $q, $window, userService, attributeService, custom
let promise = ""; let promise = "";
let statisticalInfo = {}; let statisticalInfo = {};
for (let i = 0; i < attributesType.length; i++) { for (let i = 0; i < attributesType.length; i++) {
let attrribute = attributesType[i]; let attribute = attributesType[i];
if (deviceRelation.attributes[attrribute] && deviceRelation.attributes[attrribute].length !== 0) { if (deviceRelation.attributes[attribute] && deviceRelation.attributes[attribute].length !== 0) {
promise = attributeService.saveEntityAttributes(types.entityType.device, deviceId, types.attributesScope[attrribute].value, deviceRelation.attributes[attrribute], config).then(function () { promise = attributeService.saveEntityAttributes(types.entityType.device, deviceId, types.attributesScope[attribute].value, deviceRelation.attributes[attribute], config).then(function () {
statisticalInfo.create = { statisticalInfo.create = {
[attrribute]: deviceRelation.attributes[attributesType[i]].length [attribute]: deviceRelation.attributes[attribute].length
}; };
}, function () { }, function () {
statisticalInfo.error = { statisticalInfo.error = {
[attrribute]: deviceRelation.attributes[attributesType[i]].length [attribute]: deviceRelation.attributes[attribute].length
}; };
}); });
allPromise.push(promise); allPromise.push(promise);
@ -234,7 +234,9 @@ function DeviceService($http, $q, $window, userService, attributeService, custom
device: 1 device: 1
}; };
saveDeviceRelarion(response.id.id, deviceParameters, config).then(function success(response) { saveDeviceRelarion(response.id.id, deviceParameters, config).then(function success(response) {
if(response.create) {
delete Object.assign(response, {update: response.create}).create; delete Object.assign(response, {update: response.create}).create;
}
angular.merge(statisticalInfo, response); angular.merge(statisticalInfo, response);
deferred.resolve(statisticalInfo); deferred.resolve(statisticalInfo);
}); });

View File

@ -54,6 +54,8 @@ import react from 'ngreact';
import '@flowjs/ng-flow/dist/ng-flow-standalone.min'; import '@flowjs/ng-flow/dist/ng-flow-standalone.min';
import 'ngFlowchart/dist/ngFlowchart'; import 'ngFlowchart/dist/ngFlowchart';
import 'jstree/dist/jstree.min'; import 'jstree/dist/jstree.min';
import 'material-steppers/dist/material-steppers';
import 'material-steppers/dist/material-steppers.css'
import 'jstree-bootstrap-theme/dist/themes/proton/style.min.css'; import 'jstree-bootstrap-theme/dist/themes/proton/style.min.css';
import 'typeface-roboto'; import 'typeface-roboto';
import 'font-awesome/css/font-awesome.min.css'; import 'font-awesome/css/font-awesome.min.css';
@ -127,6 +129,7 @@ angular.module('thingsboard', [
react.name, react.name,
'flow', 'flow',
'flowchart', 'flowchart',
'mdSteppers',
thingsboardThirdpartyFix, thingsboardThirdpartyFix,
thingsboardTranslateHandler, thingsboardTranslateHandler,
thingsboardLogin, thingsboardLogin,

View File

@ -16,14 +16,16 @@
import './import-dialog.scss'; import './import-dialog.scss';
/*@ngInject*/ /*@ngInject*/
export default function ImportDialogCsvController($scope, $mdDialog, toast, importTitle, importFileLabel, entityType, importExport, types, $timeout, $q) { export default function ImportDialogCsvController($scope, $mdDialog, toast, importTitle, importFileLabel, entityType, importExport, types, $mdStepper) {
var vm = this; var vm = this;
vm.cancel = cancel; vm.cancel = cancel;
vm.importFromJson = importFromJson; vm.finishExport = finishExport;
vm.fileAdded = fileAdded; vm.fileAdded = fileAdded;
vm.clearFile = clearFile; vm.clearFile = clearFile;
vm.nextStep = nextStep;
vm.previousStep = previousStep;
vm.addDevices = addDevices; vm.addDevices = addDevices;
vm.importParams = { vm.importParams = {
@ -32,56 +34,15 @@ export default function ImportDialogCsvController($scope, $mdDialog, toast, impo
isHeader: true isHeader: true
}; };
vm.selectedStep = 0;
vm.stepProgress = 1;
vm.maxStep = 3;
vm.showBusyText = false;
vm.stepData = [
{ step: 1, completed: false, optional: false, data: {} },
{ step: 2, completed: false, optional: false, data: {} },
{ step: 3, completed: false, optional: false, data: {} },
];
vm.enableNextStep = function nextStep() {
//do not exceed into max step
if (vm.selectedStep >= vm.maxStep) {
return;
}
//do not increment vm.stepProgress when submitting from previously completed step
if (vm.selectedStep === vm.stepProgress - 1) {
vm.stepProgress = vm.stepProgress + 1;
}
vm.selectedStep = vm.selectedStep + 1;
};
vm.moveToPreviousStep = function moveToPreviousStep() {
if (vm.selectedStep > 0) {
vm.selectedStep = vm.selectedStep - 1;
}
};
vm.submitCurrentStep = function submitCurrentStep(stepData, isSkip) {
var deferred = $q.defer();
vm.showBusyText = true;
if (!stepData.completed && !isSkip) {
//simulate $http
$timeout(function () {
vm.showBusyText = false;
deferred.resolve({ status: 200, statusText: 'success', data: {} });
//move to next step when success
stepData.completed = true;
vm.enableNextStep();
}, 1000)
} else {
vm.showBusyText = false;
vm.enableNextStep();
}
};
vm.importTitle = importTitle; vm.importTitle = importTitle;
vm.importFileLabel = importFileLabel; vm.importFileLabel = importFileLabel;
vm.entityType = entityType; vm.entityType = entityType;
vm.isVertical = true;
vm.isLinear = true;
vm.isAlternative = false;
vm.isMobileStepText = true;
vm.columnsParam = []; vm.columnsParam = [];
vm.parseData = []; vm.parseData = [];
@ -107,11 +68,11 @@ export default function ImportDialogCsvController($scope, $mdDialog, toast, impo
reader.onload = function (event) { reader.onload = function (event) {
$scope.$apply(function () { $scope.$apply(function () {
if (event.target.result) { if (event.target.result) {
$scope.theForm.$setDirty(); vm.theFormStep1.$setDirty();
var importCSV = event.target.result; var importCSV = event.target.result;
if (importCSV && importCSV.length > 0) { if (importCSV && importCSV.length > 0) {
try { try {
parseCSV(importCSV); vm.importData = importCSV;
vm.fileName = $file.name; vm.fileName = $file.name;
} catch (err) { } catch (err) {
vm.fileName = null; vm.fileName = null;
@ -126,12 +87,15 @@ export default function ImportDialogCsvController($scope, $mdDialog, toast, impo
} }
function parseCSV(importData) { function parseCSV(importData) {
var columnParam = {};
var config = { var config = {
delim: vm.importParams.delim, delim: vm.importParams.delim,
header: vm.importParams.isHeader header: vm.importParams.isHeader
}; };
parseData = importExport.convertCSVToJson(importData, config); return importExport.convertCSVToJson(importData, config);
}
function createColumnsData(parseData) {
var columnParam = {};
for (var i = 0; i < parseData.headers.length; i++) { for (var i = 0; i < parseData.headers.length; i++) {
if (vm.importParams.isHeader && parseData.headers[i].search(/^(name|type)$/im) === 0) { if (vm.importParams.isHeader && parseData.headers[i].search(/^(name|type)$/im) === 0) {
columnParam = { columnParam = {
@ -150,24 +114,14 @@ export default function ImportDialogCsvController($scope, $mdDialog, toast, impo
} }
} }
function addDevices () { function addDevices(importData, parameterColumns) {
var arrayParam = [{type: "ENTITY_FIELD", key: "name", sampleData: "Device 1"}, {type: "ENTITY_FIELD", key: "type", sampleData: "test"}, {type: "SERVER_ATTRIBUTE", key: "test", sampleData: "test"}, {type: "TIMESERIES", key: "testBoolean", sampleData: false}, {type: "SHARED_ATTRIBUTE", key: "testNumber", sampleData: 123}]; // eslint-disable-line var entitysData = [];
var data = {headers: ["Device 1", "test", "test", "FALSE", "123"],
rows:[["Device 1", "test", "test", false, 123.5]]};
// rows:[["Device 1", "test", "test", false, 123],
// ["Device 2", "test", "test", false, 124],
// ["Device 3", "test", "test", false, 125],
// ["Device 4", "test", "test", false, 126],
// ["Device 5", "test", "test", false, 127]]};
arrayParam = vm.columnsParam;
data = parseData;
var arrayData = [];
var config = { var config = {
ignoreErrors: true, ignoreErrors: true,
resendRequest: true resendRequest: true
}; };
for (var i = 0; i < data.rows.length; i ++) { for (var i = 0; i < importData.rows.length; i++) {
var obj = { var entityData = {
name: "", name: "",
type: "", type: "",
attributes: { attributes: {
@ -176,58 +130,86 @@ export default function ImportDialogCsvController($scope, $mdDialog, toast, impo
}, },
timeseries: [] timeseries: []
}; };
for(var j = 0; j < arrayParam.length; j++){ for (var j = 0; j < parameterColumns.length; j++) {
switch (arrayParam[j].type) { switch (parameterColumns[j].type) {
case types.entityGroup.columnType.serverAttribute.value: case types.entityGroup.columnType.serverAttribute.value:
obj.attributes.server.push({ entityData.attributes.server.push({
key: arrayParam[j].key, key: parameterColumns[j].key,
value: data.rows[i][j] value: importData.rows[i][j]
}); });
break; break;
case types.entityGroup.columnType.sharedAttribute.value: case types.entityGroup.columnType.sharedAttribute.value:
obj.attributes.shared.push({ entityData.attributes.shared.push({
key: arrayParam[j].key, key: parameterColumns[j].key,
value: data.rows[i][j] value: importData.rows[i][j]
}); });
break; break;
case types.entityGroup.columnType.timeseries.value: case types.entityGroup.columnType.timeseries.value:
obj.timeseries.push({ entityData.timeseries.push({
key: arrayParam[j].key, key: parameterColumns[j].key,
value: data.rows[i][j] value: importData.rows[i][j]
}); });
break; break;
case types.entityGroup.columnType.entityField.value: case types.entityGroup.columnType.entityField.value:
switch (arrayParam[j].key) { switch (parameterColumns[j].key) {
case types.entityGroup.entityField.name.value: case types.entityGroup.entityField.name.value:
obj.name = data.rows[i][j]; entityData.name = importData.rows[i][j];
break; break;
case types.entityGroup.entityField.type.value: case types.entityGroup.entityField.type.value:
obj.type = data.rows[i][j]; entityData.type = importData.rows[i][j];
break; break;
} }
break; break;
} }
} }
arrayData.push(obj); entitysData.push(entityData);
} }
importExport.createMultiEntity(arrayData, vm.entityType, vm.importParams.isUpdate, config).then(function () { importExport.createMultiEntity(entitysData, vm.entityType, vm.importParams.isUpdate, config).then(function (response) {
$mdDialog.hide(); vm.statistical = response;
$mdStepper('import-stepper').next();
}); });
} }
function clearFile() { function clearFile() {
$scope.theForm.$setDirty(); vm.theFormStep1.$setDirty();
vm.fileName = null; vm.fileName = null;
parseData = null; vm.importData = null;
vm.columnsParam = []; }
function previousStep() {
let steppers = $mdStepper('import-stepper');
steppers.back();
}
function nextStep(step) {
let steppers = $mdStepper('import-stepper');
switch (step) {
case 2:
steppers.next();
break;
case 3:
parseData = parseCSV(vm.importData);
if (parseData === -1) {
clearFile();
steppers.back();
} else {
createColumnsData(parseData);
steppers.next();
}
break;
case 4:
steppers.next();
addDevices(parseData, vm.columnsParam)
break;
}
} }
function cancel() { function cancel() {
$mdDialog.cancel(); $mdDialog.cancel();
} }
function importFromJson() { function finishExport() {
$scope.theForm.$setPristine(); $mdDialog.hide();
$mdDialog.hide(vm.importData);
} }
} }

View File

@ -16,7 +16,6 @@
--> -->
<md-dialog aria-label="{{ vm.importTitle | translate }}"> <md-dialog aria-label="{{ vm.importTitle | translate }}">
<form name="theForm" ng-submit="vm.importFromJson()">
<md-toolbar> <md-toolbar>
<div class="md-toolbar-tools"> <div class="md-toolbar-tools">
<h2 translate>{{ vm.importTitle }}</h2> <h2 translate>{{ vm.importTitle }}</h2>
@ -30,7 +29,11 @@
ng-show="$root.loading"></md-progress-linear> ng-show="$root.loading"></md-progress-linear>
<span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span>
<md-dialog-content> <md-dialog-content>
<div class="md-dialog-content"> <md-stepper id="import-stepper" md-mobile-step-text="vm.isMobileStepText" md-vertical="vm.isVertical"
md-linear="vm.isLinear" md-alternative="vm.isAlternative">
<md-step md-label="Select a file">
<md-step-body>
<form name="vm.theFormStep1">
<fieldset ng-disabled="$root.loading"> <fieldset ng-disabled="$root.loading">
<div layout="column" layout-padding> <div layout="column" layout-padding>
<div class="tb-container"> <div class="tb-container">
@ -44,7 +47,8 @@
<md-tooltip md-direction="top"> <md-tooltip md-direction="top">
{{ 'action.remove' | translate }} {{ 'action.remove' | translate }}
</md-tooltip> </md-tooltip>
<md-icon aria-label="{{ 'action.remove' | translate }}" class="material-icons"> <md-icon aria-label="{{ 'action.remove' | translate }}"
class="material-icons">
close close
</md-icon> </md-icon>
</md-button> </md-button>
@ -52,7 +56,8 @@
<div class="alert tb-flow-drop" flow-drop> <div class="alert tb-flow-drop" flow-drop>
<label for="select" translate>import.drop-file-csv</label> <label for="select" translate>import.drop-file-csv</label>
<input class="file-input" flow-btn <input class="file-input" flow-btn
flow-attrs="{accept:'.csv,application/csv,text/csv'}" id="select"> flow-attrs="{accept:'.csv,application/csv,text/csv'}"
id="select">
</div> </div>
</div> </div>
</div> </div>
@ -62,7 +67,25 @@
</div> </div>
</div> </div>
</fieldset> </fieldset>
<div flex layout="row"> </form>
</md-step-body>
<md-step-actions layout="row">
<span flex></span>
<md-button ng-disabled="$root.loading" ng-click="vm.cancel()">
{{ 'action.cancel' | translate }}
</md-button>
<md-button class="md-primary md-raised"
ng-disabled="$root.loading || !vm.theFormStep1.$dirty || !vm.theFormStep1.$valid || !vm.importData"
ng-click="vm.nextStep(2);">
Continue
</md-button>
</md-step-actions>
</md-step>
<md-step md-label="Select config import">
<md-step-body>
<div flex layout="row" layout-xs="column">
<md-input-container class="md-block" style="min-width: 120px"> <md-input-container class="md-block" style="min-width: 120px">
<label translate>CSV delimiter</label> <label translate>CSV delimiter</label>
<md-select ng-model="vm.importParams.delim"> <md-select ng-model="vm.importParams.delim">
@ -82,21 +105,79 @@
</md-checkbox> </md-checkbox>
</md-input-container> </md-input-container>
</div> </div>
<tb-table-columns-assignment the-form="theForm" columns="vm.columnsParam" entityType="vm.entityType"></tb-table-columns-assignment> </md-step-body>
</div>
</md-dialog-content> <md-step-actions layout="row">
<md-dialog-actions layout="row"> <md-button ng-disabled="$root.loading" ng-click="vm.previousStep();">Back
</md-button>
<span flex></span> <span flex></span>
<md-button ng-disabled="$root.loading" ng-click="vm.addDevices()" style="margin-right:20px;"> <md-button ng-disabled="$root.loading" ng-click="vm.cancel()">
Add Device {{ 'action.cancel' | translate }}
</md-button> </md-button>
<md-button ng-disabled="$root.loading || !theForm.$dirty || !theForm.$valid || !vm.importData" type="submit" <md-button class="md-primary md-raised" ng-disabled="$root.loading" ng-click="vm.nextStep(3);">
class="md-raised md-primary"> Continue
{{ 'action.import' | translate }}
</md-button> </md-button>
<md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' </md-step-actions>
| translate }} </md-step>
<md-step md-label="Select columns type">
<md-step-body>
<tb-table-columns-assignment columns="vm.columnsParam"
entity-type="vm.entityType"></tb-table-columns-assignment>
</md-step-body>
<md-step-actions layout="row">
<md-button ng-disabled="$root.loading" ng-click="vm.previousStep();">Back
</md-button> </md-button>
</md-dialog-actions> <span flex></span>
</form> <md-button ng-disabled="$root.loading" ng-click="vm.cancel()">
{{ 'action.cancel' | translate }}
</md-button>
<md-button class="md-primary md-raised" ng-disabled="$root.loading" ng-click="vm.nextStep(4);">
Continue
</md-button>
</md-step-actions>
</md-step>
<md-step md-label="Creat new device">
<md-step-body>
<md-progress-linear md-mode="determinate" value="{{vm.determinateValue}}"></md-progress-linear>
</md-step-body>
</md-step>
<md-step md-label="Creat new Entitys">
<md-step-body>
<div flex layout="row" ng-repeat="(key, value) in vm.statistical">
<md-list flex layout="column">
<md-subheader class="md-no-sticky">{{key}}</md-subheader>
<md-list-item class="md-2-line" ng-repeat="(info, infoValue) in vm.statistical[key]" ng-click="null">
<div class="md-list-item-text">
<p>{{ info }}: {{ infoValue }}</p>
</div>
</md-list-item>
</md-list>
</div>
</md-step-body>
<md-step-actions>
<span flex></span>
<md-button ng-disabled="$root.loading" ng-click="vm.cancel()">
{{ 'action.cancel' | translate }}
</md-button>
<md-button class="md-primary md-raised" ng-disabled="$root.loading" ng-click="vm.finishExport();">
Ok
</md-button>
</md-step-actions>
</md-step>
</md-stepper>
</md-dialog-content>
<!--<md-dialog-actions layout="row">-->
<!--<span flex></span>-->
<!--<md-button ng-disabled="$root.loading || !theForm.$dirty || !theForm.$valid || !vm.importData" type="submit"-->
<!--class="md-raised md-primary">-->
<!--{{ 'action.import' | translate }}-->
<!--</md-button>-->
<!--<md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel'-->
<!--| translate }}-->
<!--</md-button>-->
<!--</md-dialog-actions>-->
</md-dialog> </md-dialog>