Modified tags in metadata dialog and moved column right to name

This commit is contained in:
xseris 2017-12-07 00:59:36 +01:00
parent f21230804b
commit b16941777e
8 changed files with 320 additions and 142 deletions

View File

@ -139,6 +139,7 @@ public abstract class ProjectManager {
_projectsMetadata.put(project.id, projectMetadata);
if (_projectsTags == null) {
_projectsTags = new HashMap<String, Integer>();
<<<<<<< Upstream, based on origin/master
}
String[] tags = projectMetadata.getTags();
if (tags != null) {
@ -148,6 +149,16 @@ public abstract class ProjectManager {
} else {
_projectsTags.put(tag, 1);
}
=======
String[] tags = projectMetadata.getTags();
if (tags != null) {
for (String tag : tags) {
if (_projectsTags.containsKey(tag)) {
_projectsTags.put(tag, _projectsTags.get(tag) + 1);
} else {
_projectsTags.put(tag, 1);
}
>>>>>>> 529b6bd Modified tags in metadata dialog and moved column right to name
}
}
}

View File

@ -57,31 +57,32 @@ import com.google.refine.util.JSONUtilities;
import com.google.refine.util.ParsingUtilities;
public class ProjectMetadata implements Jsonizable {
private final Date _created;
private Date _modified;
private Date written = null;
private String _name = "";
private String _password = "";
private String _encoding = "";
private int _encodingConfidence;
private final Date _created;
private Date _modified;
private Date written = null;
private String _name = "";
private String _password = "";
private String _encoding = "";
private int _encodingConfidence;
private String[] _tags = new String[0];
private String _creator = "";
private String _contributors = "";
private String _subject = ""; // Several refine projects may be linked
private String _description = ""; // free form of comment
private int _rowCount; // at the creation. Essential for cleaning old projects too heavy
private String _subject = ""; // Several refine projects may be linked
private String _description = ""; // free form of comment
private int _rowCount; // at the creation. Essential for cleaning old projects too heavy
// import options is an array for 1-n data sources
private JSONArray _importOptionMetadata = new JSONArray();
// user metadata
private JSONArray _userMetadata = new JSONArray();;
private Map<String, Serializable> _customMetadata = new HashMap<String, Serializable>();
private PreferenceStore _preferenceStore = new PreferenceStore();
private JSONArray _userMetadata = new JSONArray();;
private Map<String, Serializable> _customMetadata = new HashMap<String, Serializable>();
private PreferenceStore _preferenceStore = new PreferenceStore();
private final static Logger logger = LoggerFactory.getLogger("project_metadata");
@ -100,70 +101,81 @@ public class ProjectMetadata implements Jsonizable {
_modified = modified;
_name = name;
}
@Override
public void write(JSONWriter writer, Properties options)
throws JSONException {
writer.object();
writer.key("name"); writer.value(_name);
writer.key("created"); writer.value(ParsingUtilities.dateToString(_created));
writer.key("modified"); writer.value(ParsingUtilities.dateToString(_modified));
writer.key("creator"); writer.value(_creator);
writer.key("contributors"); writer.value(_contributors);
writer.key("subject"); writer.value(_subject);
writer.key("description"); writer.value(_description);
writer.key("rowCount"); writer.value(_rowCount);
writer.key("customMetadata"); writer.object();
writer.key("name");
writer.value(_name);
writer.key("tags");
writer.array();
for (String tag : _tags) {
writer.value(tag);
}
writer.endArray();
writer.key("created");
writer.value(ParsingUtilities.dateToString(_created));
writer.key("modified");
writer.value(ParsingUtilities.dateToString(_modified));
writer.key("creator");
writer.value(_creator);
writer.key("contributors");
writer.value(_contributors);
writer.key("subject");
writer.value(_subject);
writer.key("description");
writer.value(_description);
writer.key("rowCount");
writer.value(_rowCount);
writer.key("customMetadata");
writer.object();
for (String key : _customMetadata.keySet()) {
Serializable value = _customMetadata.get(key);
writer.key(key);
writer.value(value);
}
writer.endObject();
writer.key("tags");
writer.array();
for (String tag : _tags) {
writer.value(tag);
}
writer.endArray();
// write JSONArray directly
if (_importOptionMetadata.length() > 0 ) {
writer.key("importOptionMetadata");
// write JSONArray directly
if (_importOptionMetadata.length() > 0) {
writer.key("importOptionMetadata");
writer.value(_importOptionMetadata);
}
// write user metadata in {name, value, display} form:
if (_userMetadata.length() > 0) {
writer.key(PreferenceStore.USER_METADATA_KEY);
writer.value(_userMetadata);
}
if (isSaveMode(options)) {
writer.key("password"); writer.value(_password);
writer.key("password");
writer.value(_password);
writer.key("encoding"); writer.value(_encoding);
writer.key("encodingConfidence"); writer.value(_encodingConfidence);
writer.key("encoding");
writer.value(_encoding);
writer.key("encodingConfidence");
writer.value(_encodingConfidence);
writer.key("preferences"); _preferenceStore.write(writer, options);
writer.key("preferences");
_preferenceStore.write(writer, options);
}
writer.endObject();
if (isSaveMode(options)) {
written = new Date();
}
}
public void writeWithoutOption(JSONWriter writer)
throws JSONException {
write(writer,
new Properties());
write(writer, new Properties());
}
private boolean isSaveMode(Properties options) {
return "save".equals(options.getProperty("mode"));
}
@ -171,17 +183,21 @@ public class ProjectMetadata implements Jsonizable {
public boolean isDirty() {
return written == null || _modified.after(written);
}
public void write(JSONWriter jsonWriter) throws JSONException {
public void write(JSONWriter jsonWriter)
throws JSONException {
write(jsonWriter, false);
}
/**
* @param jsonWriter writer to save metadatea to
* @param onlyIfDirty true to not write unchanged metadata
* @param jsonWriter
* writer to save metadatea to
* @param onlyIfDirty
* true to not write unchanged metadata
* @throws JSONException
*/
public void write(JSONWriter jsonWriter, boolean onlyIfDirty) throws JSONException {
public void write(JSONWriter jsonWriter, boolean onlyIfDirty)
throws JSONException {
if (!onlyIfDirty || isDirty()) {
Properties options = new Properties();
options.setProperty("mode", "save");
@ -189,9 +205,9 @@ public class ProjectMetadata implements Jsonizable {
write(jsonWriter, options);
}
}
static public ProjectMetadata loadFromJSON(JSONObject obj) {
// TODO: Is this correct? It's using modified date for creation date
// TODO: Is this correct? It's using modified date for creation date
ProjectMetadata pm = new ProjectMetadata(JSONUtilities.getDate(obj, "modified", new Date()));
pm._modified = JSONUtilities.getDate(obj, "modified", new Date());
@ -200,15 +216,15 @@ public class ProjectMetadata implements Jsonizable {
pm._encoding = JSONUtilities.getString(obj, "encoding", "");
pm._encodingConfidence = JSONUtilities.getInt(obj, "encodingConfidence", 0);
pm._creator = JSONUtilities.getString(obj, "creator", "");
pm._contributors = JSONUtilities.getString(obj, "contributors", "");
pm._subject = JSONUtilities.getString(obj, "subject", "");
pm._description = JSONUtilities.getString(obj, "description", "");
pm._rowCount = JSONUtilities.getInt(obj, "rowCount", 0);
pm._tags = JSONUtilities.getStringArray(obj, "tags");
if (obj.has("preferences") && !obj.isNull("preferences")) {
try {
pm._preferenceStore.load(obj.getJSONObject("preferences"));
@ -216,20 +232,19 @@ public class ProjectMetadata implements Jsonizable {
logger.error(ExceptionUtils.getFullStackTrace(e));
}
}
if (obj.has("expressions") && !obj.isNull("expressions")) { // backward compatibility
try {
((TopList) pm._preferenceStore.get("scripting.expressions"))
.load(obj.getJSONArray("expressions"));
((TopList) pm._preferenceStore.get("scripting.expressions")).load(obj.getJSONArray("expressions"));
} catch (JSONException e) {
logger.error(ExceptionUtils.getFullStackTrace(e));
}
}
if (obj.has("customMetadata") && !obj.isNull("customMetadata")) {
try {
JSONObject obj2 = obj.getJSONObject("customMetadata");
@SuppressWarnings("unchecked")
Iterator<String> keys = obj2.keys();
while (keys.hasNext()) {
@ -243,7 +258,7 @@ public class ProjectMetadata implements Jsonizable {
logger.error(ExceptionUtils.getFullStackTrace(e));
}
}
if (obj.has("importOptionMetadata") && !obj.isNull("importOptionMetadata")) {
try {
JSONArray jsonArray = obj.getJSONArray("importOptionMetadata");
@ -252,7 +267,7 @@ public class ProjectMetadata implements Jsonizable {
logger.error(ExceptionUtils.getFullStackTrace(e));
}
}
if (obj.has(PreferenceStore.USER_METADATA_KEY) && !obj.isNull(PreferenceStore.USER_METADATA_KEY)) {
try {
JSONArray jsonArray = obj.getJSONArray(PreferenceStore.USER_METADATA_KEY);
@ -260,13 +275,13 @@ public class ProjectMetadata implements Jsonizable {
} catch (JSONException e) {
logger.error(ExceptionUtils.getFullStackTrace(e));
}
}
}
pm.written = new Date(); // Mark it as not needing writing until modified
return pm;
}
static protected void preparePreferenceStore(PreferenceStore ps) {
ProjectManager.preparePreferenceStore(ps);
// Any project specific preferences?
@ -308,30 +323,29 @@ public class ProjectMetadata implements Jsonizable {
public int getEncodingConfidence() {
return _encodingConfidence;
}
public void setTags(String[] tags) {
if (tags != null) {
List<String> tmpTags = new ArrayList<String>(tags.length);
for (String tag : tags) {
if (tag != null) {
String trimmedTag = tag.trim();
List<String> tmpTags = new ArrayList<String>(tags.length);
for (String tag : tags) {
if (tag != null) {
String trimmedTag = tag.trim();
if (!trimmedTag.isEmpty()) {
tmpTags.add(trimmedTag);
}
if (!trimmedTag.isEmpty()) {
tmpTags.add(trimmedTag);
}
}
}
}
this._tags = tmpTags.toArray(new String[tmpTags.size()]);
this._tags = tmpTags.toArray(new String[tmpTags.size()]);
} else {
this._tags = tags;
this._tags = tags;
}
updateModified();
}
}
public String[] getTags() {
if (_tags == null)
this._tags = new String[0];
public String[] getTags() {
if (_tags == null) this._tags = new String[0];
return _tags;
}
@ -355,11 +369,11 @@ public class ProjectMetadata implements Jsonizable {
public PreferenceStore getPreferenceStore() {
return _preferenceStore;
}
public Serializable getCustomMetadata(String key) {
return _customMetadata.get(key);
}
public void setCustomMetadata(String key, Serializable value) {
if (value == null) {
_customMetadata.remove(key);
@ -368,87 +382,75 @@ public class ProjectMetadata implements Jsonizable {
}
updateModified();
}
public JSONArray getImportOptionMetadata() {
return _importOptionMetadata;
}
public void setImportOptionMetadata(JSONArray jsonArray) {
_importOptionMetadata = jsonArray;
updateModified();
}
public void appendImportOptionMetadata(JSONObject obj) {
_importOptionMetadata.put(obj);
updateModified();
}
public String getCreator() {
return _creator;
}
public void setCreator(String creator) {
this._creator = creator;
updateModified();
}
public String getContributors() {
return _contributors;
}
public void setContributors(String contributors) {
this._contributors = contributors;
updateModified();
}
public String getSubject() {
return _subject;
}
public void setSubject(String subject) {
this._subject = subject;
updateModified();
}
public String getDescription() {
return _description;
}
public void setDescription(String description) {
this._description = description;
updateModified();
}
public int getRowCount() {
return _rowCount;
}
public void setRowCount(int rowCount) {
this._rowCount = rowCount;
updateModified();
}
public JSONArray getUserMetadata() {
return _userMetadata;
}
public void setUserMetadata(JSONArray userMetadata) {
this._userMetadata = userMetadata;
}
private void updateUserMetadata(String metaName, String valueString) {
private void updateUserMetadata(String metaName, String valueString) {
for (int i = 0; i < _userMetadata.length(); i++) {
try {
JSONObject obj = _userMetadata.getJSONObject(i);
@ -460,18 +462,21 @@ public class ProjectMetadata implements Jsonizable {
}
}
}
public void setAnyField(String metaName, String valueString) {
public void setAnyField(String metaName, String valueString) {
Class<? extends ProjectMetadata> metaClass = this.getClass();
try {
Field metaField = metaClass.getDeclaredField("_" + metaName);
metaField.set(this, valueString);
if (metaName.equals("tags")) {
metaField.set(this, valueString.split(","));
} else {
metaField.set(this, valueString);
}
} catch (NoSuchFieldException e) {
updateUserMetadata(metaName, valueString);
} catch (SecurityException | IllegalArgumentException | IllegalAccessException e) {
logger.error(ExceptionUtils.getFullStackTrace(e));
}
}
}

View File

@ -94,9 +94,15 @@ public class ProjectManagerTests extends RefineTest {
SUT.registerProject(project, metadata);
<<<<<<< Upstream, based on origin/master
AssertProjectRegistered();
verify(metadata, times(1)).getTags();
=======
AssertProjectRegistered();
verify(metadata, times(1)).getTags();
>>>>>>> 529b6bd Modified tags in metadata dialog and moved column right to name
verifyNoMoreInteractions(project);
verifyNoMoreInteractions(metadata);
}
@ -121,7 +127,11 @@ public class ProjectManagerTests extends RefineTest {
this.verifySaveTimeCompared(1);
verify(SUT, times(1)).saveProject(project);
verify(metadata, times(1)).getTags();
<<<<<<< Upstream, based on origin/master
=======
>>>>>>> 529b6bd Modified tags in metadata dialog and moved column right to name
//ensure end
verifyNoMoreInteractions(project);
verifyNoMoreInteractions(metadata);

View File

@ -31,7 +31,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.google.refine.tests.model;
package com.google.refine.tests.browsing.facets;
import static org.mockito.Mockito.mock;

View File

@ -31,7 +31,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.google.refine.tests.model;
package com.google.refine.tests.operations.cell;
import static org.mockito.Mockito.mock;

View File

@ -351,7 +351,14 @@ Refine.TagsManager._getAllProjectTags = function() {
});
array.map(function(item){
<<<<<<< Upstream, based on origin/master
self.allProjectTags.push(item);
=======
self.allProjectTags.push(item);
});
},
async : false
>>>>>>> 529b6bd Modified tags in metadata dialog and moved column right to name
});
},
async : false

View File

@ -21,11 +21,38 @@ function EditMetadataDialog(metaData, targetRowElem) {
var td2 = tr.insertCell(2);
if(key==="tags"){
$('<button class="button">').text($.i18n._('core-index')["edit"]).appendTo(td2).click(function() {
var oldTags = $(td1).text().replace("\"","").replace("[","").replace("]","");
oldTags = replaceAll(oldTags,"\"","");
var newTags = window.prompt($.i18n._('core-index')["change-metadata-value"]+" " + key, value);
newTags = newTags.replace("\"","").replace("[","").replace("]","");
newTags = replaceAll(newTags,"\"","");
if (newTags !== null) {
$(td1).text(newTags);
metaData[key] = newTags;
$.ajax({
type : "POST",
url : "command/core/set-project-tags",
data : {
"project" : project,
"old" : oldTags,
"new" : newTags
},
dataType : "json",
});
}
Refine.OpenProjectUI.refreshProject(targetRowElem, metaData);
});
}
if (key !== "created" &&
key !== "modified" &&
key !== "rowCount" &&
key !== "importOptionMetadata" &&
key !== "id") {
key !== "id" &&
key !== "tags") {
$('<button class="button">').text($.i18n._('core-index')["edit"]).appendTo(td2).click(function() {
var newValue = window.prompt($.i18n._('core-index')["change-metadata-value"]+" " + key, value);
if (newValue !== null) {
@ -63,7 +90,7 @@ EditMetadataDialog.prototype._createDialog = function() {
this._level = DialogSystem.showDialog(frame);
this._elmts.closeButton.html($.i18n._('core-buttons')["close"]);
this._elmts.closeButton.click(function() { self._dismiss(); });
this._elmts.closeButton.click(function() { self._dismiss();Refine.OpenProjectUI.prototype._addTagFilter()});
var body = $("#metadata-body");
@ -111,3 +138,11 @@ EditMetadataDialog.prototype._dismiss = function() {
DialogSystem.dismissUntil(this._level - 1);
};
function escapeRegExp(str) {
return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
}
function replaceAll(str, find, replace) {
return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}

View File

@ -192,11 +192,11 @@ Refine.OpenProjectUI.prototype._renderProjects = function(data) {
'<th></th>' +
'<th>'+$.i18n._('core-index-open')["last-mod"]+'</th>' +
'<th>'+$.i18n._('core-index-open')["name"]+'</th>' +
'<th>'+$.i18n._('core-index-open')["tags"]+'</th>' +
'<th>'+$.i18n._('core-index-open')["creator"]+'</th>' +
'<th>'+$.i18n._('core-index-open')["subject"]+'</th>' +
'<th>'+$.i18n._('core-index-open')["description"]+'</th>' +
'<th>'+$.i18n._('core-index-open')["row-count"]+'</th>' +
'<th>'+$.i18n._('core-index-open')["tags"]+'</th>' +
(function() {
var htmlDisplay = "";
for (var n in data.customMetadataColumns) {
@ -261,36 +261,18 @@ Refine.OpenProjectUI.prototype._renderProjects = function(data) {
.attr("href", "project?project=" + project.id)
.appendTo($(tr.insertCell(tr.cells.length)));
var appendMetaField = function(data) {
$('<div></div>')
.html(data)
.appendTo($(tr.insertCell(tr.cells.length)));
};
appendMetaField(project.creator);
appendMetaField(project.subject);
appendMetaField(project.description, '20%');
appendMetaField(project.rowCount);
var data = project.userMetadata;
for(var i in data)
{
if (data[i].display === true) {
appendMetaField(data[i].value);
}
}
$(tr.insertCell(tr.cells.length));
var tagsCell = $(tr.insertCell(tr.cells.length));
var tags = project.tags;
for (var index = 0; index < tags.length; index++) {
var tag = tags[index];
tags.map(function(tag){
$("<span/>")
.addClass("project-tag")
.text(tag)
.attr("title", $.i18n._('core-index-open')["edit-tags"])
.appendTo($(tr.cells[tr.cells.length - 1]));
.appendTo(tagsCell);
$(tr).addClass(tag);
}
});
var editTagsLink = $('<a></a>')
@ -326,7 +308,26 @@ Refine.OpenProjectUI.prototype._renderProjects = function(data) {
}
});
return false;
}).appendTo($(tr.cells[tr.cells.length - 1]));
}).appendTo(tagsCell);
var appendMetaField = function(data) {
$('<div></div>')
.html(data)
.appendTo($(tr.insertCell(tr.cells.length)));
};
appendMetaField(project.creator);
appendMetaField(project.subject);
appendMetaField(project.description, '20%');
appendMetaField(project.rowCount);
var data = project.userMetadata;
for(var i in data)
{
if (data[i].display === true) {
appendMetaField(data[i].value);
}
}
$(tr).mouseenter(function() {
editTagsLink.css("visibility", "visible");
@ -388,18 +389,113 @@ Refine.OpenProjectUI.prototype._onClickUploadFileButton = function(evt) {
};
Refine.OpenProjectUI.refreshProject = function(tr, metaData) {
var refreshMetaField = function(data, index) {
if (index === 3) {
$('a', $('td', tr).eq(index))
.text(data);
} else {
$('td', tr).eq(index)
$('td', tr).eq(index).find('div')
.text(data);
}
};
var refreshMetaTags = function(data, index) {
var tagCol = $('td', tr).eq(index).empty();
if(data.constructor === Array){
data.map(function(tag){
var tagsCell = $("<span/>")
.addClass("project-tag")
.text(tag)
.attr("title", $.i18n._('core-index-open')["edit-tags"])
.appendTo(tagCol);
var editTagsLink = $('<a></a>')
.text($.i18n._('core-index-open')["rename"])
.addClass("secondary")
.addClass("edit-project-tags")
.css("visibility", "hidden")
.attr("href", "")
.attr("title", $.i18n._('core-index-open')["edit-tags"])
.html('<img src="images/edit.png" />')
.click(function() {
var oldTags = project.tags.join(",");
var newTags = window.prompt($.i18n._('core-index-open')["edit-tags-desc"],oldTags);
if (newTags === null || newTags === oldTags) {
return false;
}
$.ajax({
type : "POST",
url : "command/core/set-project-tags",
data : {
"project" : project.id,
"old" : oldTags,
"new" : newTags
},
dataType : "json",
success : function(data) {
if (data && typeof data.code != 'undefined' && data.code == "ok") {
Refine.TagsManager.allProjectTags = [];
self._buildTagsAndFetchProjects();
} else {
alert($.i18n._('core-index-open')["warning-tags-update"]+ " "+ data.message);
}
}
});
return false;
}).appendTo(tagCol);
tagCol.parent().addClass(tag);
});
} else{
data.split(",").map(function(tag){
var tagsCell = $("<span/>")
.addClass("project-tag")
.text(tag)
.attr("title", $.i18n._('core-index-open')["edit-tags"])
.appendTo(tagCol);
var editTagsLink = $('<a></a>')
.text($.i18n._('core-index-open')["rename"])
.addClass("secondary")
.addClass("edit-project-tags")
.css("visibility", "hidden")
.attr("href", "")
.attr("title", $.i18n._('core-index-open')["edit-tags"])
.html('<img src="images/edit.png" />')
.click(function() {
var oldTags = project.tags.join(",");
var newTags = window.prompt($.i18n._('core-index-open')["edit-tags-desc"],oldTags);
if (newTags === null || newTags === oldTags) {
return false;
}
$.ajax({
type : "POST",
url : "command/core/set-project-tags",
data : {
"project" : project.id,
"old" : oldTags,
"new" : newTags
},
dataType : "json",
success : function(data) {
if (data && typeof data.code != 'undefined' && data.code == "ok") {
Refine.TagsManager.allProjectTags = [];
self._buildTagsAndFetchProjects();
} else {
alert($.i18n._('core-index-open')["warning-tags-update"]+ " "+ data.message);
}
}
});
return false;
}).appendTo(tagCol);
tagCol.parent().addClass(tag);
});
}
};
var index = 3;
refreshMetaField(metaData.name, index); index++;
refreshMetaTags(metaData.tags, index); index++;
refreshMetaField(metaData.creator, index); index++;
refreshMetaField(metaData.subject,index); index++;
refreshMetaField(metaData.description,index); index++;
@ -427,7 +523,21 @@ Refine.OpenProjectUI.refreshProject = function(tr, metaData) {
refreshMetaField(data[i].value,index); index++;
}
}
Refine.TagsManager.allProjectTags = [];
var self = this;
var list = $("#tagsUl").empty();
self._allTags = Refine.TagsManager._getAllProjectTags();
var li = $('<li/>').addClass("active").appendTo(list);
$('<a/>').attr('href',
'#all').addClass("current").text('All').appendTo(li);
$.each(self._allTags, function(i) {
var li = $('<li/>').appendTo(list);
$('<a/>').attr('href', '#' + self._allTags[i]).text(self._allTags[i])
.appendTo(li);
});
};
Refine.actionAreas.push({