#300: custom metadata fields: UI read/write

This commit is contained in:
Benjamin Gamard 2019-05-21 15:44:23 +02:00
parent b4c3e7a928
commit ab8176efcb
9 changed files with 100 additions and 10 deletions

View File

@ -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);

View File

@ -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

View File

@ -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);
} }
@ -93,6 +102,20 @@ 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 {

View File

@ -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;
}); });

View File

@ -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",

View File

@ -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",

View File

@ -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">

View File

@ -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) -->

View File

@ -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>