mirror of
https://github.com/sismics/docs.git
synced 2024-11-22 05:57:57 +01:00
#300: custom metadata fields: UI read/write
This commit is contained in:
parent
b4c3e7a928
commit
ab8176efcb
@ -9,7 +9,6 @@ import com.sismics.docs.core.dao.dto.DocumentMetadataDto;
|
|||||||
import com.sismics.docs.core.dao.dto.MetadataDto;
|
import com.sismics.docs.core.dao.dto.MetadataDto;
|
||||||
import com.sismics.docs.core.model.jpa.DocumentMetadata;
|
import com.sismics.docs.core.model.jpa.DocumentMetadata;
|
||||||
import com.sismics.docs.core.util.jpa.SortCriteria;
|
import com.sismics.docs.core.util.jpa.SortCriteria;
|
||||||
import com.sismics.util.JsonUtil;
|
|
||||||
|
|
||||||
import javax.json.Json;
|
import javax.json.Json;
|
||||||
import javax.json.JsonArrayBuilder;
|
import javax.json.JsonArrayBuilder;
|
||||||
@ -105,7 +104,7 @@ public class MetadataUtil {
|
|||||||
break;
|
break;
|
||||||
case FLOAT:
|
case FLOAT:
|
||||||
try {
|
try {
|
||||||
Float.parseFloat(value);
|
Double.parseDouble(value);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
throw new Exception("Float value not parsable");
|
throw new Exception("Float value not parsable");
|
||||||
}
|
}
|
||||||
@ -169,7 +168,25 @@ public class MetadataUtil {
|
|||||||
.add("type", metadataDto.getType().name());
|
.add("type", metadataDto.getType().name());
|
||||||
for (DocumentMetadataDto documentMetadataDto : documentMetadataDtoList) {
|
for (DocumentMetadataDto documentMetadataDto : documentMetadataDtoList) {
|
||||||
if (documentMetadataDto.getMetadataId().equals(metadataDto.getId())) {
|
if (documentMetadataDto.getMetadataId().equals(metadataDto.getId())) {
|
||||||
meta.add("value", JsonUtil.nullable(documentMetadataDto.getValue()));
|
if (documentMetadataDto.getValue() != null) {
|
||||||
|
switch (metadataDto.getType()) {
|
||||||
|
case STRING:
|
||||||
|
meta.add("value", documentMetadataDto.getValue());
|
||||||
|
break;
|
||||||
|
case BOOLEAN:
|
||||||
|
meta.add("value", Boolean.parseBoolean(documentMetadataDto.getValue()));
|
||||||
|
break;
|
||||||
|
case DATE:
|
||||||
|
meta.add("value", Long.parseLong(documentMetadataDto.getValue()));
|
||||||
|
break;
|
||||||
|
case FLOAT:
|
||||||
|
meta.add("value", Double.parseDouble(documentMetadataDto.getValue()));
|
||||||
|
break;
|
||||||
|
case INTEGER:
|
||||||
|
meta.add("value", Integer.parseInt(documentMetadataDto.getValue()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
metadata.add(meta);
|
metadata.add(meta);
|
||||||
|
@ -37,7 +37,7 @@ public class MetadataResource extends BaseResource {
|
|||||||
* @apiSuccess {String} metadata.name Name
|
* @apiSuccess {String} metadata.name Name
|
||||||
* @apiSuccess {String="STRING","INTEGER","FLOAT","DATE","BOOLEAN"} metadata.type Type
|
* @apiSuccess {String="STRING","INTEGER","FLOAT","DATE","BOOLEAN"} metadata.type Type
|
||||||
* @apiError (client) ForbiddenError Access denied
|
* @apiError (client) ForbiddenError Access denied
|
||||||
* @apiPermission admin
|
* @apiPermission user
|
||||||
* @apiVersion 1.7.0
|
* @apiVersion 1.7.0
|
||||||
*
|
*
|
||||||
* @return Response
|
* @return Response
|
||||||
|
@ -59,9 +59,18 @@ angular.module('docs').controller('DocumentEdit', function($rootScope, $scope, $
|
|||||||
$scope.document = {
|
$scope.document = {
|
||||||
tags: [],
|
tags: [],
|
||||||
relations: [],
|
relations: [],
|
||||||
language: language
|
language: language,
|
||||||
|
metadata: []
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Get custom metadata list
|
||||||
|
Restangular.one('metadata').get({
|
||||||
|
sort_column: 1,
|
||||||
|
asc: true
|
||||||
|
}).then(function(data) {
|
||||||
|
$scope.document.metadata = data.metadata;
|
||||||
|
});
|
||||||
|
|
||||||
if ($scope.navigatedTag) {
|
if ($scope.navigatedTag) {
|
||||||
$scope.document.tags.push($scope.navigatedTag);
|
$scope.document.tags.push($scope.navigatedTag);
|
||||||
}
|
}
|
||||||
@ -92,7 +101,21 @@ angular.module('docs').controller('DocumentEdit', function($rootScope, $scope, $
|
|||||||
|
|
||||||
// Extract ids from relations (only when our document is the source)
|
// Extract ids from relations (only when our document is the source)
|
||||||
document.relations = _.pluck(_.where(document.relations, { source: true }), 'id');
|
document.relations = _.pluck(_.where(document.relations, { source: true }), 'id');
|
||||||
|
|
||||||
|
// Extract custom metadata values
|
||||||
|
var metadata = _.reject(document.metadata, function (meta) {
|
||||||
|
return _.isUndefined(meta.value) || meta.value === '' || meta.value == null;
|
||||||
|
});
|
||||||
|
document.metadata_id = _.pluck(metadata, 'id');
|
||||||
|
document.metadata_value = _.pluck(metadata, 'value');
|
||||||
|
document.metadata_value = _.map(document.metadata_value, function (val) {
|
||||||
|
if (val instanceof Date) {
|
||||||
|
return val.getTime();
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Send to server
|
||||||
if ($scope.isEdit()) {
|
if ($scope.isEdit()) {
|
||||||
promise = Restangular.one('document', $stateParams.id).post('', document);
|
promise = Restangular.one('document', $stateParams.id).post('', document);
|
||||||
} else {
|
} else {
|
||||||
|
@ -5,7 +5,10 @@
|
|||||||
*/
|
*/
|
||||||
angular.module('docs').controller('SettingsMetadata', function($scope, Restangular) {
|
angular.module('docs').controller('SettingsMetadata', function($scope, Restangular) {
|
||||||
// Load metadata
|
// Load metadata
|
||||||
Restangular.one('metadata').get().then(function(data) {
|
Restangular.one('metadata').get({
|
||||||
|
sort_column: 1,
|
||||||
|
asc: true
|
||||||
|
}).then(function(data) {
|
||||||
$scope.metadata = data.metadata;
|
$scope.metadata = data.metadata;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -597,6 +597,8 @@
|
|||||||
"description": "Documents can be organized in tags (which are like super-folders). Create them here."
|
"description": "Documents can be organized in tags (which are like super-folders). Create them here."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"yes": "Yes",
|
||||||
|
"no": "No",
|
||||||
"ok": "OK",
|
"ok": "OK",
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
"share": "Share",
|
"share": "Share",
|
||||||
|
@ -586,6 +586,8 @@
|
|||||||
"description": "Les documents peuvent être organisés en tags (qui sont comme des super-dossiers). Créez-les ici."
|
"description": "Les documents peuvent être organisés en tags (qui sont comme des super-dossiers). Créez-les ici."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"yes": "Oui",
|
||||||
|
"no": "Non",
|
||||||
"ok": "OK",
|
"ok": "OK",
|
||||||
"cancel": "Annuler",
|
"cancel": "Annuler",
|
||||||
"share": "Partager",
|
"share": "Partager",
|
||||||
|
@ -44,7 +44,7 @@
|
|||||||
clear-text="{{ 'directive.datepicker.clear' | translate }}"
|
clear-text="{{ 'directive.datepicker.clear' | translate }}"
|
||||||
close-text="{{ 'directive.datepicker.close' | translate }}"
|
close-text="{{ 'directive.datepicker.close' | translate }}"
|
||||||
ng-readonly="true" uib-datepicker-popup="{{ dateFormat }}" class="form-control"
|
ng-readonly="true" uib-datepicker-popup="{{ dateFormat }}" class="form-control"
|
||||||
ng-model="document.create_date" datepicker-options="{ startingDay:1, showWeeks: false }"
|
ng-model="document.create_date" datepicker-options="{ startingDay: 1, showWeeks: false }"
|
||||||
ng-click="datepickerOpened = true" is-open="datepickerOpened" ng-disabled="fileIsUploading" />
|
ng-click="datepickerOpened = true" is-open="datepickerOpened" ng-disabled="fileIsUploading" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -72,6 +72,42 @@
|
|||||||
<select-tag tags="document.tags" ref="inputTags" ng-disabled="fileIsUploading"></select-tag>
|
<select-tag tags="document.tags" ref="inputTags" ng-disabled="fileIsUploading"></select-tag>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Custom metadata -->
|
||||||
|
<div class="form-group"
|
||||||
|
ng ng-repeat="meta in document.metadata"
|
||||||
|
ng-class="{ 'has-error': !documentForm[meta.id].$valid && documentForm.$dirty }">
|
||||||
|
<label class="col-sm-2 control-label" for="inputTitle">{{ meta.name }}</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input ng-if="meta.type == 'STRING'"
|
||||||
|
ng-maxlength="4000" class="form-control" type="text" id="input{{ meta.id }}"
|
||||||
|
name="{{ meta.id }}" ng-model="meta.value" autocomplete="off"
|
||||||
|
ng-disabled="fileIsUploading" />
|
||||||
|
|
||||||
|
<input ng-if="meta.type == 'DATE'"
|
||||||
|
type="text" id="input{{ meta.id }}" name="{{ meta.id }}"
|
||||||
|
current-text="{{ 'directive.datepicker.current' | translate }}"
|
||||||
|
clear-text="{{ 'directive.datepicker.clear' | translate }}"
|
||||||
|
close-text="{{ 'directive.datepicker.close' | translate }}"
|
||||||
|
ng-readonly="true" uib-datepicker-popup="{{ dateFormat }}" class="form-control"
|
||||||
|
ng-model="meta.value" datepicker-options="{ startingDay: 1, showWeeks: false }"
|
||||||
|
ng-click="datepickerOpenedMeta[meta.id] = true" is-open="datepickerOpenedMeta[meta.id]" ng-disabled="fileIsUploading" />
|
||||||
|
|
||||||
|
<input ng-if="meta.type == 'INTEGER'"
|
||||||
|
ng-pattern="/^[0-9]*$/" class="form-control" type="text" id="input{{ meta.id }}"
|
||||||
|
name="{{ meta.id }}" ng-model="meta.value" autocomplete="off"
|
||||||
|
ng-disabled="fileIsUploading" />
|
||||||
|
|
||||||
|
<input ng-if="meta.type == 'FLOAT'"
|
||||||
|
ng-pattern="/^-?[0-9]*\.?[0-9]*$/" class="form-control" type="text" id="input{{ meta.id }}"
|
||||||
|
name="{{ meta.id }}" ng-model="meta.value" autocomplete="off"
|
||||||
|
ng-disabled="fileIsUploading" />
|
||||||
|
|
||||||
|
<input type="checkbox" ng-if="meta.type == 'BOOLEAN'"
|
||||||
|
id="input{{ meta.id }}" name="{{ meta.id }}"
|
||||||
|
ng-model="meta.value" ng-disabled="fileIsUploading" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<fieldset ng-init="additionalMetadataCollapsed = true">
|
<fieldset ng-init="additionalMetadataCollapsed = true">
|
||||||
|
@ -35,6 +35,13 @@
|
|||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
||||||
|
<dt ng-if="false" ng-repeat-start="meta in document.metadata"></dt>
|
||||||
|
<dt ng-if="meta.value != null">{{ meta.name }}</dt>
|
||||||
|
<dd ng-if="meta.value != null && (meta.type == 'STRING' || meta.type == 'INTEGER' || meta.type == 'FLOAT')">{{ meta.value }}</dd>
|
||||||
|
<dd ng-if="meta.value != null && meta.type == 'DATE'">{{ meta.value | date: dateFormat }}</dd>
|
||||||
|
<dd ng-if="meta.value != null && meta.type == 'BOOLEAN'">{{ meta.value ? 'yes' : 'no' | translate }}</dd>
|
||||||
|
<dd ng-if="false" ng-repeat-end></dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<!-- Display mode (list or grid) -->
|
<!-- Display mode (list or grid) -->
|
||||||
|
@ -48,8 +48,8 @@
|
|||||||
<label class="col-sm-2 control-label" for="inputQuota">{{ 'settings.user.edit.storage_quota' | translate }}</label>
|
<label class="col-sm-2 control-label" for="inputQuota">{{ 'settings.user.edit.storage_quota' | translate }}</label>
|
||||||
<div class="col-sm-7">
|
<div class="col-sm-7">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input name="storage_quota" type="number" id="inputQuota" required class="form-control"
|
<input name="storage_quota" type="text" id="inputQuota" required class="form-control"
|
||||||
ng-pattern="/[0-9]*/" ng-attr-placeholder="{{ 'settings.user.edit.storage_quota_placeholder' | translate }}" ng-model="user.storage_quota"/>
|
ng-pattern="/^[0-9]*$/" ng-attr-placeholder="{{ 'settings.user.edit.storage_quota_placeholder' | translate }}" ng-model="user.storage_quota"/>
|
||||||
<div class="input-group-addon">{{ 'filter.filesize.mb' | translate }}</div>
|
<div class="input-group-addon">{{ 'filter.filesize.mb' | translate }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user