commit
3c5a9b0754
@ -74,6 +74,7 @@ public abstract class ProjectManager {
|
|||||||
|
|
||||||
|
|
||||||
protected Map<Long, ProjectMetadata> _projectsMetadata;
|
protected Map<Long, ProjectMetadata> _projectsMetadata;
|
||||||
|
protected Map<String, Integer> _projectsTags;// TagName, number of projects having that tag
|
||||||
protected PreferenceStore _preferenceStore;
|
protected PreferenceStore _preferenceStore;
|
||||||
|
|
||||||
final static Logger logger = LoggerFactory.getLogger("ProjectManager");
|
final static Logger logger = LoggerFactory.getLogger("ProjectManager");
|
||||||
@ -102,6 +103,7 @@ public abstract class ProjectManager {
|
|||||||
_projectsMetadata = new HashMap<Long, ProjectMetadata>();
|
_projectsMetadata = new HashMap<Long, ProjectMetadata>();
|
||||||
_preferenceStore = new PreferenceStore();
|
_preferenceStore = new PreferenceStore();
|
||||||
_projects = new HashMap<Long, Project>();
|
_projects = new HashMap<Long, Project>();
|
||||||
|
_projectsTags = new HashMap<String, Integer>();
|
||||||
|
|
||||||
preparePreferenceStore(_preferenceStore);
|
preparePreferenceStore(_preferenceStore);
|
||||||
}
|
}
|
||||||
@ -128,6 +130,18 @@ public abstract class ProjectManager {
|
|||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
_projects.put(project.id, project);
|
_projects.put(project.id, project);
|
||||||
_projectsMetadata.put(project.id, projectMetadata);
|
_projectsMetadata.put(project.id, projectMetadata);
|
||||||
|
if (_projectsTags == null)
|
||||||
|
_projectsTags = new HashMap<String, Integer>();
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,6 +479,15 @@ public abstract class ProjectManager {
|
|||||||
|
|
||||||
return _projectsMetadata;
|
return _projectsMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all the project tags currently held in memory
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Map<String, Integer> getAllProjectTags() {
|
||||||
|
return _projectsTags;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the required project from the data store
|
* Gets the required project from the data store
|
||||||
|
@ -35,9 +35,11 @@ package com.google.refine;
|
|||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
@ -55,29 +57,32 @@ import com.google.refine.util.JSONUtilities;
|
|||||||
import com.google.refine.util.ParsingUtilities;
|
import com.google.refine.util.ParsingUtilities;
|
||||||
|
|
||||||
public class ProjectMetadata implements Jsonizable {
|
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 final Date _created;
|
||||||
private int _encodingConfidence;
|
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 _creator = "";
|
||||||
private String _contributors = "";
|
private String _contributors = "";
|
||||||
private String _subject = ""; // Several refine projects may be linked
|
private String _subject = ""; // Several refine projects may be linked
|
||||||
private String _description = ""; // free form of comment
|
private String _description = ""; // free form of comment
|
||||||
private int _rowCount; // at the creation. Essential for cleaning old projects too heavy
|
private int _rowCount; // at the creation. Essential for cleaning old projects too heavy
|
||||||
|
|
||||||
// import options is an array for 1-n data sources
|
// import options is an array for 1-n data sources
|
||||||
private JSONArray _importOptionMetadata = new JSONArray();
|
private JSONArray _importOptionMetadata = new JSONArray();
|
||||||
|
|
||||||
// user metadata
|
// user metadata
|
||||||
private JSONArray _userMetadata = new JSONArray();;
|
private JSONArray _userMetadata = new JSONArray();;
|
||||||
|
|
||||||
private Map<String, Serializable> _customMetadata = new HashMap<String, Serializable>();
|
private Map<String, Serializable> _customMetadata = new HashMap<String, Serializable>();
|
||||||
private PreferenceStore _preferenceStore = new PreferenceStore();
|
private PreferenceStore _preferenceStore = new PreferenceStore();
|
||||||
|
|
||||||
private final static Logger logger = LoggerFactory.getLogger("project_metadata");
|
private final static Logger logger = LoggerFactory.getLogger("project_metadata");
|
||||||
|
|
||||||
@ -96,63 +101,81 @@ public class ProjectMetadata implements Jsonizable {
|
|||||||
_modified = modified;
|
_modified = modified;
|
||||||
_name = name;
|
_name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(JSONWriter writer, Properties options)
|
public void write(JSONWriter writer, Properties options)
|
||||||
throws JSONException {
|
throws JSONException {
|
||||||
|
|
||||||
writer.object();
|
writer.object();
|
||||||
writer.key("name"); writer.value(_name);
|
writer.key("name");
|
||||||
writer.key("created"); writer.value(ParsingUtilities.dateToString(_created));
|
writer.value(_name);
|
||||||
writer.key("modified"); writer.value(ParsingUtilities.dateToString(_modified));
|
writer.key("tags");
|
||||||
writer.key("creator"); writer.value(_creator);
|
writer.array();
|
||||||
writer.key("contributors"); writer.value(_contributors);
|
for (String tag : _tags) {
|
||||||
writer.key("subject"); writer.value(_subject);
|
writer.value(tag);
|
||||||
writer.key("description"); writer.value(_description);
|
}
|
||||||
writer.key("rowCount"); writer.value(_rowCount);
|
writer.endArray();
|
||||||
|
writer.key("created");
|
||||||
writer.key("customMetadata"); writer.object();
|
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()) {
|
for (String key : _customMetadata.keySet()) {
|
||||||
Serializable value = _customMetadata.get(key);
|
Serializable value = _customMetadata.get(key);
|
||||||
writer.key(key);
|
writer.key(key);
|
||||||
writer.value(value);
|
writer.value(value);
|
||||||
}
|
}
|
||||||
writer.endObject();
|
writer.endObject();
|
||||||
|
|
||||||
// write JSONArray directly
|
// write JSONArray directly
|
||||||
if (_importOptionMetadata.length() > 0 ) {
|
if (_importOptionMetadata.length() > 0) {
|
||||||
writer.key("importOptionMetadata");
|
writer.key("importOptionMetadata");
|
||||||
writer.value(_importOptionMetadata);
|
writer.value(_importOptionMetadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
// write user metadata in {name, value, display} form:
|
// write user metadata in {name, value, display} form:
|
||||||
if (_userMetadata.length() > 0) {
|
if (_userMetadata.length() > 0) {
|
||||||
writer.key(PreferenceStore.USER_METADATA_KEY);
|
writer.key(PreferenceStore.USER_METADATA_KEY);
|
||||||
writer.value(_userMetadata);
|
writer.value(_userMetadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSaveMode(options)) {
|
if (isSaveMode(options)) {
|
||||||
writer.key("password"); writer.value(_password);
|
writer.key("password");
|
||||||
|
writer.value(_password);
|
||||||
|
|
||||||
writer.key("encoding"); writer.value(_encoding);
|
writer.key("encoding");
|
||||||
writer.key("encodingConfidence"); writer.value(_encodingConfidence);
|
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();
|
writer.endObject();
|
||||||
|
|
||||||
if (isSaveMode(options)) {
|
if (isSaveMode(options)) {
|
||||||
written = new Date();
|
written = new Date();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeWithoutOption(JSONWriter writer)
|
public void writeWithoutOption(JSONWriter writer)
|
||||||
throws JSONException {
|
throws JSONException {
|
||||||
write(writer,
|
write(writer, new Properties());
|
||||||
new Properties());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isSaveMode(Properties options) {
|
private boolean isSaveMode(Properties options) {
|
||||||
return "save".equals(options.getProperty("mode"));
|
return "save".equals(options.getProperty("mode"));
|
||||||
}
|
}
|
||||||
@ -160,17 +183,21 @@ public class ProjectMetadata implements Jsonizable {
|
|||||||
public boolean isDirty() {
|
public boolean isDirty() {
|
||||||
return written == null || _modified.after(written);
|
return written == null || _modified.after(written);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void write(JSONWriter jsonWriter) throws JSONException {
|
public void write(JSONWriter jsonWriter)
|
||||||
|
throws JSONException {
|
||||||
write(jsonWriter, false);
|
write(jsonWriter, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param jsonWriter writer to save metadatea to
|
* @param jsonWriter
|
||||||
* @param onlyIfDirty true to not write unchanged metadata
|
* writer to save metadatea to
|
||||||
|
* @param onlyIfDirty
|
||||||
|
* true to not write unchanged metadata
|
||||||
* @throws JSONException
|
* @throws JSONException
|
||||||
*/
|
*/
|
||||||
public void write(JSONWriter jsonWriter, boolean onlyIfDirty) throws JSONException {
|
public void write(JSONWriter jsonWriter, boolean onlyIfDirty)
|
||||||
|
throws JSONException {
|
||||||
if (!onlyIfDirty || isDirty()) {
|
if (!onlyIfDirty || isDirty()) {
|
||||||
Properties options = new Properties();
|
Properties options = new Properties();
|
||||||
options.setProperty("mode", "save");
|
options.setProperty("mode", "save");
|
||||||
@ -178,9 +205,9 @@ public class ProjectMetadata implements Jsonizable {
|
|||||||
write(jsonWriter, options);
|
write(jsonWriter, options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static public ProjectMetadata loadFromJSON(JSONObject obj) {
|
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()));
|
ProjectMetadata pm = new ProjectMetadata(JSONUtilities.getDate(obj, "modified", new Date()));
|
||||||
|
|
||||||
pm._modified = JSONUtilities.getDate(obj, "modified", new Date());
|
pm._modified = JSONUtilities.getDate(obj, "modified", new Date());
|
||||||
@ -189,13 +216,15 @@ public class ProjectMetadata implements Jsonizable {
|
|||||||
|
|
||||||
pm._encoding = JSONUtilities.getString(obj, "encoding", "");
|
pm._encoding = JSONUtilities.getString(obj, "encoding", "");
|
||||||
pm._encodingConfidence = JSONUtilities.getInt(obj, "encodingConfidence", 0);
|
pm._encodingConfidence = JSONUtilities.getInt(obj, "encodingConfidence", 0);
|
||||||
|
|
||||||
pm._creator = JSONUtilities.getString(obj, "creator", "");
|
pm._creator = JSONUtilities.getString(obj, "creator", "");
|
||||||
pm._contributors = JSONUtilities.getString(obj, "contributors", "");
|
pm._contributors = JSONUtilities.getString(obj, "contributors", "");
|
||||||
pm._subject = JSONUtilities.getString(obj, "subject", "");
|
pm._subject = JSONUtilities.getString(obj, "subject", "");
|
||||||
pm._description = JSONUtilities.getString(obj, "description", "");
|
pm._description = JSONUtilities.getString(obj, "description", "");
|
||||||
pm._rowCount = JSONUtilities.getInt(obj, "rowCount", 0);
|
pm._rowCount = JSONUtilities.getInt(obj, "rowCount", 0);
|
||||||
|
|
||||||
|
pm._tags = JSONUtilities.getStringArray(obj, "tags");
|
||||||
|
|
||||||
if (obj.has("preferences") && !obj.isNull("preferences")) {
|
if (obj.has("preferences") && !obj.isNull("preferences")) {
|
||||||
try {
|
try {
|
||||||
pm._preferenceStore.load(obj.getJSONObject("preferences"));
|
pm._preferenceStore.load(obj.getJSONObject("preferences"));
|
||||||
@ -203,20 +232,19 @@ public class ProjectMetadata implements Jsonizable {
|
|||||||
logger.error(ExceptionUtils.getFullStackTrace(e));
|
logger.error(ExceptionUtils.getFullStackTrace(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj.has("expressions") && !obj.isNull("expressions")) { // backward compatibility
|
if (obj.has("expressions") && !obj.isNull("expressions")) { // backward compatibility
|
||||||
try {
|
try {
|
||||||
((TopList) pm._preferenceStore.get("scripting.expressions"))
|
((TopList) pm._preferenceStore.get("scripting.expressions")).load(obj.getJSONArray("expressions"));
|
||||||
.load(obj.getJSONArray("expressions"));
|
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
logger.error(ExceptionUtils.getFullStackTrace(e));
|
logger.error(ExceptionUtils.getFullStackTrace(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj.has("customMetadata") && !obj.isNull("customMetadata")) {
|
if (obj.has("customMetadata") && !obj.isNull("customMetadata")) {
|
||||||
try {
|
try {
|
||||||
JSONObject obj2 = obj.getJSONObject("customMetadata");
|
JSONObject obj2 = obj.getJSONObject("customMetadata");
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Iterator<String> keys = obj2.keys();
|
Iterator<String> keys = obj2.keys();
|
||||||
while (keys.hasNext()) {
|
while (keys.hasNext()) {
|
||||||
@ -230,7 +258,7 @@ public class ProjectMetadata implements Jsonizable {
|
|||||||
logger.error(ExceptionUtils.getFullStackTrace(e));
|
logger.error(ExceptionUtils.getFullStackTrace(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj.has("importOptionMetadata") && !obj.isNull("importOptionMetadata")) {
|
if (obj.has("importOptionMetadata") && !obj.isNull("importOptionMetadata")) {
|
||||||
try {
|
try {
|
||||||
JSONArray jsonArray = obj.getJSONArray("importOptionMetadata");
|
JSONArray jsonArray = obj.getJSONArray("importOptionMetadata");
|
||||||
@ -239,7 +267,7 @@ public class ProjectMetadata implements Jsonizable {
|
|||||||
logger.error(ExceptionUtils.getFullStackTrace(e));
|
logger.error(ExceptionUtils.getFullStackTrace(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj.has(PreferenceStore.USER_METADATA_KEY) && !obj.isNull(PreferenceStore.USER_METADATA_KEY)) {
|
if (obj.has(PreferenceStore.USER_METADATA_KEY) && !obj.isNull(PreferenceStore.USER_METADATA_KEY)) {
|
||||||
try {
|
try {
|
||||||
JSONArray jsonArray = obj.getJSONArray(PreferenceStore.USER_METADATA_KEY);
|
JSONArray jsonArray = obj.getJSONArray(PreferenceStore.USER_METADATA_KEY);
|
||||||
@ -247,13 +275,13 @@ public class ProjectMetadata implements Jsonizable {
|
|||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
logger.error(ExceptionUtils.getFullStackTrace(e));
|
logger.error(ExceptionUtils.getFullStackTrace(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pm.written = new Date(); // Mark it as not needing writing until modified
|
pm.written = new Date(); // Mark it as not needing writing until modified
|
||||||
|
|
||||||
return pm;
|
return pm;
|
||||||
}
|
}
|
||||||
|
|
||||||
static protected void preparePreferenceStore(PreferenceStore ps) {
|
static protected void preparePreferenceStore(PreferenceStore ps) {
|
||||||
ProjectManager.preparePreferenceStore(ps);
|
ProjectManager.preparePreferenceStore(ps);
|
||||||
// Any project specific preferences?
|
// Any project specific preferences?
|
||||||
@ -296,6 +324,31 @@ public class ProjectMetadata implements Jsonizable {
|
|||||||
return _encodingConfidence;
|
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();
|
||||||
|
|
||||||
|
if (!trimmedTag.isEmpty()) {
|
||||||
|
tmpTags.add(trimmedTag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this._tags = tmpTags.toArray(new String[tmpTags.size()]);
|
||||||
|
} else {
|
||||||
|
this._tags = tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateModified();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getTags() {
|
||||||
|
if (_tags == null) this._tags = new String[0];
|
||||||
|
return _tags;
|
||||||
|
}
|
||||||
|
|
||||||
public void setPassword(String password) {
|
public void setPassword(String password) {
|
||||||
this._password = password;
|
this._password = password;
|
||||||
updateModified();
|
updateModified();
|
||||||
@ -316,11 +369,11 @@ public class ProjectMetadata implements Jsonizable {
|
|||||||
public PreferenceStore getPreferenceStore() {
|
public PreferenceStore getPreferenceStore() {
|
||||||
return _preferenceStore;
|
return _preferenceStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Serializable getCustomMetadata(String key) {
|
public Serializable getCustomMetadata(String key) {
|
||||||
return _customMetadata.get(key);
|
return _customMetadata.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCustomMetadata(String key, Serializable value) {
|
public void setCustomMetadata(String key, Serializable value) {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
_customMetadata.remove(key);
|
_customMetadata.remove(key);
|
||||||
@ -329,87 +382,75 @@ public class ProjectMetadata implements Jsonizable {
|
|||||||
}
|
}
|
||||||
updateModified();
|
updateModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
public JSONArray getImportOptionMetadata() {
|
public JSONArray getImportOptionMetadata() {
|
||||||
return _importOptionMetadata;
|
return _importOptionMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setImportOptionMetadata(JSONArray jsonArray) {
|
public void setImportOptionMetadata(JSONArray jsonArray) {
|
||||||
_importOptionMetadata = jsonArray;
|
_importOptionMetadata = jsonArray;
|
||||||
updateModified();
|
updateModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void appendImportOptionMetadata(JSONObject obj) {
|
public void appendImportOptionMetadata(JSONObject obj) {
|
||||||
_importOptionMetadata.put(obj);
|
_importOptionMetadata.put(obj);
|
||||||
updateModified();
|
updateModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String getCreator() {
|
public String getCreator() {
|
||||||
return _creator;
|
return _creator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setCreator(String creator) {
|
public void setCreator(String creator) {
|
||||||
this._creator = creator;
|
this._creator = creator;
|
||||||
updateModified();
|
updateModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String getContributors() {
|
public String getContributors() {
|
||||||
return _contributors;
|
return _contributors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setContributors(String contributors) {
|
public void setContributors(String contributors) {
|
||||||
this._contributors = contributors;
|
this._contributors = contributors;
|
||||||
updateModified();
|
updateModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String getSubject() {
|
public String getSubject() {
|
||||||
return _subject;
|
return _subject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setSubject(String subject) {
|
public void setSubject(String subject) {
|
||||||
this._subject = subject;
|
this._subject = subject;
|
||||||
updateModified();
|
updateModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return _description;
|
return _description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setDescription(String description) {
|
public void setDescription(String description) {
|
||||||
this._description = description;
|
this._description = description;
|
||||||
updateModified();
|
updateModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int getRowCount() {
|
public int getRowCount() {
|
||||||
return _rowCount;
|
return _rowCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setRowCount(int rowCount) {
|
public void setRowCount(int rowCount) {
|
||||||
this._rowCount = rowCount;
|
this._rowCount = rowCount;
|
||||||
updateModified();
|
updateModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public JSONArray getUserMetadata() {
|
public JSONArray getUserMetadata() {
|
||||||
return _userMetadata;
|
return _userMetadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setUserMetadata(JSONArray userMetadata) {
|
public void setUserMetadata(JSONArray userMetadata) {
|
||||||
this._userMetadata = 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++) {
|
for (int i = 0; i < _userMetadata.length(); i++) {
|
||||||
try {
|
try {
|
||||||
JSONObject obj = _userMetadata.getJSONObject(i);
|
JSONObject obj = _userMetadata.getJSONObject(i);
|
||||||
@ -421,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();
|
Class<? extends ProjectMetadata> metaClass = this.getClass();
|
||||||
try {
|
try {
|
||||||
Field metaField = metaClass.getDeclaredField("_" + metaName);
|
Field metaField = metaClass.getDeclaredField("_" + metaName);
|
||||||
|
if (metaName.equals("tags")) {
|
||||||
metaField.set(this, valueString);
|
metaField.set(this, valueString.split(","));
|
||||||
|
} else {
|
||||||
|
metaField.set(this, valueString);
|
||||||
|
}
|
||||||
} catch (NoSuchFieldException e) {
|
} catch (NoSuchFieldException e) {
|
||||||
updateUserMetadata(metaName, valueString);
|
updateUserMetadata(metaName, valueString);
|
||||||
} catch (SecurityException | IllegalArgumentException | IllegalAccessException e) {
|
} catch (SecurityException | IllegalArgumentException | IllegalAccessException e) {
|
||||||
logger.error(ExceptionUtils.getFullStackTrace(e));
|
logger.error(ExceptionUtils.getFullStackTrace(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -34,26 +34,44 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
package com.google.refine.commands.project;
|
package com.google.refine.commands.project;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import com.google.refine.ProjectManager;
|
import com.google.refine.ProjectManager;
|
||||||
|
import com.google.refine.ProjectMetadata;
|
||||||
import com.google.refine.commands.Command;
|
import com.google.refine.commands.Command;
|
||||||
|
|
||||||
public class DeleteProjectCommand extends Command {
|
public class DeleteProjectCommand extends Command {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
response.setHeader("Content-Type", "application/json");
|
||||||
try {
|
try {
|
||||||
long projectID = Long.parseLong(request.getParameter("project"));
|
long projectID = Long.parseLong(request.getParameter("project"));
|
||||||
|
|
||||||
|
// Remove the project tags from the general map
|
||||||
|
Map<String, Integer> allProjectTags = ProjectManager.singleton.getAllProjectTags();
|
||||||
|
ProjectMetadata metadata = ProjectManager.singleton.getProjectMetadata(projectID);
|
||||||
|
for (String tag : metadata.getTags()) {
|
||||||
|
if (allProjectTags.containsKey(tag)) {
|
||||||
|
int occurrence = allProjectTags.get(tag);
|
||||||
|
|
||||||
|
if (occurrence == 1)
|
||||||
|
allProjectTags.remove(tag);
|
||||||
|
else {
|
||||||
|
allProjectTags.put(tag, occurrence - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ProjectManager.singleton.deleteProject(projectID);
|
ProjectManager.singleton.deleteProject(projectID);
|
||||||
|
|
||||||
respond(response, "{ \"code\" : \"ok\" }");
|
respond(response, "{ \"code\" : \"ok\" }");
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
respondException(response, e);
|
respondException(response, e);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2010, Google Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
* provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||||
|
* and the following disclaimer. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
* materials provided with the distribution. Neither the name of Google Inc. nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
|
||||||
|
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.refine.commands.project;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
|
||||||
|
import com.google.refine.ProjectManager;
|
||||||
|
import com.google.refine.ProjectMetadata;
|
||||||
|
import com.google.refine.commands.Command;
|
||||||
|
import com.google.refine.model.Project;
|
||||||
|
|
||||||
|
public class SetProjectTagsCommand extends Command {
|
||||||
|
@Override
|
||||||
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
|
throws ServletException, IOException {
|
||||||
|
response.setHeader("Content-Type", "application/json");
|
||||||
|
|
||||||
|
try {
|
||||||
|
Project project;
|
||||||
|
try {
|
||||||
|
project = getProject(request);
|
||||||
|
} catch (ServletException e) {
|
||||||
|
respond(response, "error", e.getLocalizedMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProjectMetadata metadata = project.getMetadata();
|
||||||
|
|
||||||
|
String oldT = request.getParameter("old");
|
||||||
|
String newT = request.getParameter("new");
|
||||||
|
|
||||||
|
Map<String, Integer> allProjectTags = ProjectManager.singleton.getAllProjectTags();
|
||||||
|
|
||||||
|
// Lets remove the old tags from the general map
|
||||||
|
String[] oldTags = oldT.split(",");
|
||||||
|
for (String tag : oldTags) {
|
||||||
|
if (allProjectTags!= null && allProjectTags.containsKey(tag)) {
|
||||||
|
int occurrence = allProjectTags.get(tag);
|
||||||
|
|
||||||
|
if (occurrence == 1) {
|
||||||
|
allProjectTags.remove(tag);
|
||||||
|
} else {
|
||||||
|
allProjectTags.put(tag, occurrence - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lets add the new tags to the general map
|
||||||
|
String[] newTags = newT.split(" |\\,");
|
||||||
|
List<String> polishedTags = new ArrayList<String>(newTags.length);
|
||||||
|
for (String tag : newTags) {
|
||||||
|
tag = tag.trim();
|
||||||
|
|
||||||
|
if (!tag.isEmpty()) {
|
||||||
|
if (allProjectTags!= null && allProjectTags.containsKey(tag)) {
|
||||||
|
allProjectTags.put(tag, allProjectTags.get(tag) + 1);
|
||||||
|
} else {
|
||||||
|
allProjectTags.put(tag, 1);
|
||||||
|
}
|
||||||
|
polishedTags.add(tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lets update the project tags
|
||||||
|
metadata.setTags(polishedTags.toArray(new String[polishedTags.size()]));
|
||||||
|
metadata.updateModified();
|
||||||
|
|
||||||
|
respond(response, "{ \"code\" : \"ok\" }");
|
||||||
|
|
||||||
|
} catch (JSONException e) {
|
||||||
|
respondException(response, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2010, Google Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||||
|
* provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list of conditions
|
||||||
|
* and the following disclaimer. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
* materials provided with the distribution. Neither the name of Google Inc. nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
|
||||||
|
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.refine.commands.workspace;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONWriter;
|
||||||
|
|
||||||
|
import com.google.refine.ProjectManager;
|
||||||
|
import com.google.refine.commands.Command;
|
||||||
|
|
||||||
|
public class GetAllProjectTagsCommand extends Command {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||||
|
throws ServletException, IOException {
|
||||||
|
|
||||||
|
try {
|
||||||
|
response.setCharacterEncoding("UTF-8");
|
||||||
|
response.setHeader("Content-Type", "application/json");
|
||||||
|
|
||||||
|
JSONWriter writer = new JSONWriter(response.getWriter());
|
||||||
|
// Properties options = new Properties();
|
||||||
|
|
||||||
|
writer.object();
|
||||||
|
writer.key("tags");
|
||||||
|
writer.array();
|
||||||
|
Map<String, Integer> tags = ProjectManager.singleton.getAllProjectTags();
|
||||||
|
if (tags != null) {
|
||||||
|
for (Map.Entry<String, Integer> entry : tags.entrySet()) {
|
||||||
|
writer.value(entry.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writer.endArray();
|
||||||
|
writer.endObject();
|
||||||
|
} catch (JSONException e) {
|
||||||
|
respondException(response, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1007,6 +1007,7 @@ public class ImportingUtilities {
|
|||||||
) {
|
) {
|
||||||
ProjectMetadata pm = new ProjectMetadata();
|
ProjectMetadata pm = new ProjectMetadata();
|
||||||
pm.setName(JSONUtilities.getString(optionObj, "projectName", "Untitled"));
|
pm.setName(JSONUtilities.getString(optionObj, "projectName", "Untitled"));
|
||||||
|
pm.setTags(JSONUtilities.getStringArray(optionObj, "projectTags"));
|
||||||
String encoding = JSONUtilities.getString(optionObj, "encoding", "UTF-8");
|
String encoding = JSONUtilities.getString(optionObj, "encoding", "UTF-8");
|
||||||
if ("".equals(encoding)) {
|
if ("".equals(encoding)) {
|
||||||
// encoding can be present, but empty, which won't trigger JSONUtilities default processing
|
// encoding can be present, but empty, which won't trigger JSONUtilities default processing
|
||||||
|
@ -41,6 +41,7 @@ import java.io.FileWriter;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
@ -119,8 +120,22 @@ public class FileProjectManager extends ProjectManager {
|
|||||||
if (metadata == null) {
|
if (metadata == null) {
|
||||||
metadata = ProjectMetadataUtilities.recover(getProjectDir(projectID), projectID);
|
metadata = ProjectMetadataUtilities.recover(getProjectDir(projectID), projectID);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (metadata != null) {
|
if (metadata != null) {
|
||||||
_projectsMetadata.put(projectID, metadata);
|
_projectsMetadata.put(projectID, metadata);
|
||||||
|
if (_projectsTags == null) {
|
||||||
|
_projectsTags = new HashMap<String, Integer>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (metadata != null && metadata.getTags() != null) {
|
||||||
|
for (String tag : metadata.getTags()) {
|
||||||
|
if (_projectsTags.containsKey(tag)) {
|
||||||
|
_projectsTags.put(tag, _projectsTags.get(tag) + 1);
|
||||||
|
} else {
|
||||||
|
_projectsTags.put(tag, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -375,6 +390,16 @@ public class FileProjectManager extends ProjectManager {
|
|||||||
mergeEmptyUserMetadata(metadata);
|
mergeEmptyUserMetadata(metadata);
|
||||||
|
|
||||||
_projectsMetadata.put(id, metadata);
|
_projectsMetadata.put(id, metadata);
|
||||||
|
|
||||||
|
if (metadata != null && metadata.getTags() != null) {
|
||||||
|
for (String tag : metadata.getTags()) {
|
||||||
|
if (_projectsTags.containsKey(tag)) {
|
||||||
|
_projectsTags.put(tag, _projectsTags.get(tag) + 1);
|
||||||
|
} else {
|
||||||
|
_projectsTags.put(tag, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj.has("expressions") && !obj.isNull("expressions")) { // backward compatibility
|
if (obj.has("expressions") && !obj.isNull("expressions")) { // backward compatibility
|
||||||
|
@ -94,8 +94,9 @@ public class ProjectManagerTests extends RefineTest {
|
|||||||
|
|
||||||
SUT.registerProject(project, metadata);
|
SUT.registerProject(project, metadata);
|
||||||
|
|
||||||
AssertProjectRegistered();
|
AssertProjectRegistered();
|
||||||
|
verify(metadata, times(1)).getTags();
|
||||||
|
|
||||||
verifyNoMoreInteractions(project);
|
verifyNoMoreInteractions(project);
|
||||||
verifyNoMoreInteractions(metadata);
|
verifyNoMoreInteractions(metadata);
|
||||||
}
|
}
|
||||||
@ -119,7 +120,8 @@ public class ProjectManagerTests extends RefineTest {
|
|||||||
}
|
}
|
||||||
this.verifySaveTimeCompared(1);
|
this.verifySaveTimeCompared(1);
|
||||||
verify(SUT, times(1)).saveProject(project);
|
verify(SUT, times(1)).saveProject(project);
|
||||||
|
verify(metadata, times(1)).getTags();
|
||||||
|
|
||||||
//ensure end
|
//ensure end
|
||||||
verifyNoMoreInteractions(project);
|
verifyNoMoreInteractions(project);
|
||||||
verifyNoMoreInteractions(metadata);
|
verifyNoMoreInteractions(metadata);
|
||||||
@ -160,6 +162,7 @@ public class ProjectManagerTests extends RefineTest {
|
|||||||
SUT.save(true);
|
SUT.save(true);
|
||||||
|
|
||||||
verify(metadata, times(1)).getModified();
|
verify(metadata, times(1)).getModified();
|
||||||
|
verify(metadata, times(1)).getTags();
|
||||||
verify(project, times(1)).getProcessManager();
|
verify(project, times(1)).getProcessManager();
|
||||||
verify(project, times(2)).getLastSave();
|
verify(project, times(2)).getLastSave();
|
||||||
verify(project, times(1)).dispose();
|
verify(project, times(1)).dispose();
|
||||||
@ -180,6 +183,7 @@ public class ProjectManagerTests extends RefineTest {
|
|||||||
|
|
||||||
verify(SUT, never()).saveProjects(Mockito.anyBoolean());
|
verify(SUT, never()).saveProjects(Mockito.anyBoolean());
|
||||||
verify(SUT, never()).saveWorkspace();
|
verify(SUT, never()).saveWorkspace();
|
||||||
|
verify(metadata, times(1)).getTags();
|
||||||
verifyNoMoreInteractions(project);
|
verifyNoMoreInteractions(project);
|
||||||
verifyNoMoreInteractions(metadata);
|
verifyNoMoreInteractions(metadata);
|
||||||
}
|
}
|
||||||
@ -246,6 +250,7 @@ public class ProjectManagerTests extends RefineTest {
|
|||||||
verify(meta, times(1)).getModified();
|
verify(meta, times(1)).getModified();
|
||||||
verify(proj, times(2)).getLastSave();
|
verify(proj, times(2)).getLastSave();
|
||||||
verify(SUT, times(1)).saveProject(proj);
|
verify(SUT, times(1)).saveProject(proj);
|
||||||
|
verify(meta, times(1)).getTags();
|
||||||
|
|
||||||
verifyNoMoreInteractions(proj);
|
verifyNoMoreInteractions(proj);
|
||||||
verifyNoMoreInteractions(meta);
|
verifyNoMoreInteractions(meta);
|
||||||
|
@ -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;
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
|
@ -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;
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
|
@ -69,6 +69,8 @@ function registerCommands() {
|
|||||||
RS.registerCommand(module, "get-project-metadata", new Packages.com.google.refine.commands.project.GetProjectMetadataCommand());
|
RS.registerCommand(module, "get-project-metadata", new Packages.com.google.refine.commands.project.GetProjectMetadataCommand());
|
||||||
RS.registerCommand(module, "get-all-project-metadata", new Packages.com.google.refine.commands.workspace.GetAllProjectMetadataCommand());
|
RS.registerCommand(module, "get-all-project-metadata", new Packages.com.google.refine.commands.workspace.GetAllProjectMetadataCommand());
|
||||||
RS.registerCommand(module, "set-metaData", new Packages.com.google.refine.commands.project.SetProjectMetadataCommand());
|
RS.registerCommand(module, "set-metaData", new Packages.com.google.refine.commands.project.SetProjectMetadataCommand());
|
||||||
|
RS.registerCommand(module, "get-all-project-tags", new Packages.com.google.refine.commands.workspace.GetAllProjectTagsCommand());
|
||||||
|
RS.registerCommand(module, "set-project-tags", new Packages.com.google.refine.commands.project.SetProjectTagsCommand());
|
||||||
|
|
||||||
RS.registerCommand(module, "delete-project", new Packages.com.google.refine.commands.project.DeleteProjectCommand());
|
RS.registerCommand(module, "delete-project", new Packages.com.google.refine.commands.project.DeleteProjectCommand());
|
||||||
RS.registerCommand(module, "rename-project", new Packages.com.google.refine.commands.project.RenameProjectCommand());
|
RS.registerCommand(module, "rename-project", new Packages.com.google.refine.commands.project.RenameProjectCommand());
|
||||||
@ -321,6 +323,8 @@ function init() {
|
|||||||
"externals/jquery.i18n.js",
|
"externals/jquery.i18n.js",
|
||||||
"externals/tablesorter/jquery.tablesorter.min.js",
|
"externals/tablesorter/jquery.tablesorter.min.js",
|
||||||
"externals/moment-with-locales.min.js",
|
"externals/moment-with-locales.min.js",
|
||||||
|
"externals/select2/select2.min.js",
|
||||||
|
"externals/jquery.lavalamp.min.js",
|
||||||
|
|
||||||
"scripts/util/misc.js",
|
"scripts/util/misc.js",
|
||||||
"scripts/util/url.js",
|
"scripts/util/url.js",
|
||||||
@ -332,6 +336,7 @@ function init() {
|
|||||||
"scripts/util/date-time.js",
|
"scripts/util/date-time.js",
|
||||||
"scripts/util/encoding.js",
|
"scripts/util/encoding.js",
|
||||||
"scripts/util/sign.js",
|
"scripts/util/sign.js",
|
||||||
|
"scripts/util/filter-lists.js",
|
||||||
|
|
||||||
"scripts/index.js",
|
"scripts/index.js",
|
||||||
"scripts/index/create-project-ui.js",
|
"scripts/index/create-project-ui.js",
|
||||||
@ -364,6 +369,7 @@ function init() {
|
|||||||
module,
|
module,
|
||||||
[
|
[
|
||||||
"externals/jquery-ui/css/ui-lightness/jquery-ui-1.10.3.custom.css",
|
"externals/jquery-ui/css/ui-lightness/jquery-ui-1.10.3.custom.css",
|
||||||
|
"externals/select2/select2.css",
|
||||||
"externals/tablesorter/theme.blue.css",
|
"externals/tablesorter/theme.blue.css",
|
||||||
"styles/jquery-ui-overrides.less",
|
"styles/jquery-ui-overrides.less",
|
||||||
"styles/common.less",
|
"styles/common.less",
|
||||||
|
20
main/webapp/modules/core/externals/jquery.lavalamp.min.js
vendored
Normal file
20
main/webapp/modules/core/externals/jquery.lavalamp.min.js
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* Lava Lamp
|
||||||
|
* http://lavalamp.magicmediamuse.com/
|
||||||
|
*
|
||||||
|
* Author
|
||||||
|
* Richard Hung
|
||||||
|
* http://www.magicmediamuse.com/
|
||||||
|
*
|
||||||
|
* Version
|
||||||
|
* 1.0.6
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014 Richard Hung.
|
||||||
|
*
|
||||||
|
* License
|
||||||
|
* Lava Lamp by Richard Hung is licensed under a Creative Commons Attribution-NonCommercial 3.0 Unported License.
|
||||||
|
* http://creativecommons.org/licenses/by-nc/3.0/deed.en_US
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
(function(e){var t={init:function(t){var i={easing:"swing",duration:700,margins:false,setOnClick:false,activeObj:".active",autoUpdate:false,updateTime:100,enableHover:true};var t=e.extend({},i,t);return this.each(function(){var i=t.easing;var s=t.duration;var o=t.margins;var u=t.setOnClick;var a=t.activeObj;var f=t.autoUpdate;var l=t.updateTime;var c=t.enableHover;var h=e(this);var p=h.children();var d=h.children(a);if(d.length==0){d=p.eq(0)}h.data({easing:i,duration:s,margins:o,setOnClick:u,active:d,enableHover:c,isAnim:false});h.addClass("lavalamp").css({position:"relative"});var v=e('<div class="lavalamp-object" />').prependTo(h).css({position:"absolute"});p.addClass("lavalamp-item").css({zIndex:5,position:"relative"});var m=d.outerWidth(o);var g=d.outerHeight(o);var y=d.position().top;var b=d.position().left;var w=d.css("marginTop");var E=d.css("marginLeft");if(!o){E=parseInt(E);w=parseInt(w);b=b+E;y=y+w}v.css({width:m,height:g,top:y,left:b});var S=false;n=function(){var t=e(this);S=true;h.lavalamp("anim",t)};r=function(){var e=h.data("active");S=false;h.lavalamp("anim",e)};if(c){h.on("mouseenter",".lavalamp-item",n);h.on("mouseleave",".lavalamp-item",r)}if(u){p.click(function(){d=e(this);h.data("active",d).lavalamp("update")})}if(f){setInterval(function(){var e=h.data("isAnim");if(S==false&&e==false){h.lavalamp("update")}},l)}})},destroy:function(){return this.each(function(){var t=e(this);var i=t.children(".lavalamp-item");var s=t.data("enableHover");if(s){t.off("mouseenter",".lavalamp-item",n);t.off("mouseleave",".lavalamp-item",r)}t.removeClass("lavalamp");i.removeClass("lavalamp-item");t.children(".lavalamp-object").remove();t.removeData()})},update:function(){return this.each(function(){var t=e(this);var n=t.children(":not(.lavalamp-object)");var r=t.data("active");var i=t.children(".lavalamp-object");n.addClass("lavalamp-item").css({zIndex:5,position:"relative"});t.lavalamp("anim",r)})},anim:function(e){var t=this;var n=t.data("duration");var r=t.data("easing");var i=t.data("margins");var s=t.children(".lavalamp-object");var o=e.outerWidth(i);var u=e.outerHeight(i);var a=e.position().top;var f=e.position().left;var l=e.css("marginTop");var c=e.css("marginLeft");if(!i){c=parseInt(c);l=parseInt(l);f=f+c;a=a+l}t.data("isAnim",true);s.stop(true,false).animate({width:o,height:u,top:a,left:f},n,r,function(){t.data("isAnim",false)})}};e.fn.lavalamp=function(n){if(t[n]){return t[n].apply(this,Array.prototype.slice.call(arguments,1))}else if(typeof n==="object"||!n){return t.init.apply(this,arguments)}else{e.error("Method "+n+" does not exist on jQuery.lavalamp")}};var n,r})(jQuery)
|
BIN
main/webapp/modules/core/externals/select2/select2-spinner.gif
vendored
Normal file
BIN
main/webapp/modules/core/externals/select2/select2-spinner.gif
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
704
main/webapp/modules/core/externals/select2/select2.css
vendored
Normal file
704
main/webapp/modules/core/externals/select2/select2.css
vendored
Normal file
@ -0,0 +1,704 @@
|
|||||||
|
/*
|
||||||
|
Version: 3.5.2 Timestamp: Sat Nov 1 14:43:36 EDT 2014
|
||||||
|
*/
|
||||||
|
.select2-container {
|
||||||
|
margin: 0;
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
/* inline-block for ie7 */
|
||||||
|
zoom: 1;
|
||||||
|
*display: inline;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container,
|
||||||
|
.select2-drop,
|
||||||
|
.select2-search,
|
||||||
|
.select2-search input {
|
||||||
|
/*
|
||||||
|
Force border-box so that % widths fit the parent
|
||||||
|
container without overlap because of margin/padding.
|
||||||
|
More Info : http://www.quirksmode.org/css/box.html
|
||||||
|
*/
|
||||||
|
-webkit-box-sizing: border-box; /* webkit */
|
||||||
|
-moz-box-sizing: border-box; /* firefox */
|
||||||
|
box-sizing: border-box; /* css3 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container .select2-choice {
|
||||||
|
display: block;
|
||||||
|
height: 26px;
|
||||||
|
padding: 0 0 0 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
white-space: nowrap;
|
||||||
|
line-height: 26px;
|
||||||
|
color: #444;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
background-clip: padding-box;
|
||||||
|
|
||||||
|
-webkit-touch-callout: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
background-color: #fff;
|
||||||
|
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(0.5, #fff));
|
||||||
|
background-image: -webkit-linear-gradient(center bottom, #eee 0%, #fff 50%);
|
||||||
|
background-image: -moz-linear-gradient(center bottom, #eee 0%, #fff 50%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#ffffff', endColorstr = '#eeeeee', GradientType = 0);
|
||||||
|
background-image: linear-gradient(to top, #eee 0%, #fff 50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
html[dir="rtl"] .select2-container .select2-choice {
|
||||||
|
padding: 0 8px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container.select2-drop-above .select2-choice {
|
||||||
|
border-bottom-color: #aaa;
|
||||||
|
|
||||||
|
border-radius: 0 0 4px 4px;
|
||||||
|
|
||||||
|
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(0.9, #fff));
|
||||||
|
background-image: -webkit-linear-gradient(center bottom, #eee 0%, #fff 90%);
|
||||||
|
background-image: -moz-linear-gradient(center bottom, #eee 0%, #fff 90%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);
|
||||||
|
background-image: linear-gradient(to bottom, #eee 0%, #fff 90%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container.select2-allowclear .select2-choice .select2-chosen {
|
||||||
|
margin-right: 42px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container .select2-choice > .select2-chosen {
|
||||||
|
margin-right: 26px;
|
||||||
|
display: block;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
float: none;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[dir="rtl"] .select2-container .select2-choice > .select2-chosen {
|
||||||
|
margin-left: 26px;
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container .select2-choice abbr {
|
||||||
|
display: none;
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
position: absolute;
|
||||||
|
right: 24px;
|
||||||
|
top: 8px;
|
||||||
|
|
||||||
|
font-size: 1px;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
border: 0;
|
||||||
|
background: url('select2.png') right top no-repeat;
|
||||||
|
cursor: pointer;
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container.select2-allowclear .select2-choice abbr {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container .select2-choice abbr:hover {
|
||||||
|
background-position: right -11px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-drop-mask {
|
||||||
|
border: 0;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
min-height: 100%;
|
||||||
|
min-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
width: auto;
|
||||||
|
opacity: 0;
|
||||||
|
z-index: 9998;
|
||||||
|
/* styles required for IE to work */
|
||||||
|
background-color: #fff;
|
||||||
|
filter: alpha(opacity=0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-drop {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: -1px;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 9999;
|
||||||
|
top: 100%;
|
||||||
|
|
||||||
|
background: #fff;
|
||||||
|
color: #000;
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
border-top: 0;
|
||||||
|
|
||||||
|
border-radius: 0 0 4px 4px;
|
||||||
|
|
||||||
|
-webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
|
||||||
|
box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-drop.select2-drop-above {
|
||||||
|
margin-top: 1px;
|
||||||
|
border-top: 1px solid #aaa;
|
||||||
|
border-bottom: 0;
|
||||||
|
|
||||||
|
border-radius: 4px 4px 0 0;
|
||||||
|
|
||||||
|
-webkit-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
|
||||||
|
box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-drop-active {
|
||||||
|
border: 1px solid #5897fb;
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-drop.select2-drop-above.select2-drop-active {
|
||||||
|
border-top: 1px solid #5897fb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-drop-auto-width {
|
||||||
|
border-top: 1px solid #aaa;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-drop-auto-width .select2-search {
|
||||||
|
padding-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container .select2-choice .select2-arrow {
|
||||||
|
display: inline-block;
|
||||||
|
width: 18px;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
|
||||||
|
border-left: 1px solid #aaa;
|
||||||
|
border-radius: 0 4px 4px 0;
|
||||||
|
|
||||||
|
background-clip: padding-box;
|
||||||
|
|
||||||
|
background: #ccc;
|
||||||
|
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #ccc), color-stop(0.6, #eee));
|
||||||
|
background-image: -webkit-linear-gradient(center bottom, #ccc 0%, #eee 60%);
|
||||||
|
background-image: -moz-linear-gradient(center bottom, #ccc 0%, #eee 60%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#eeeeee', endColorstr = '#cccccc', GradientType = 0);
|
||||||
|
background-image: linear-gradient(to top, #ccc 0%, #eee 60%);
|
||||||
|
}
|
||||||
|
|
||||||
|
html[dir="rtl"] .select2-container .select2-choice .select2-arrow {
|
||||||
|
left: 0;
|
||||||
|
right: auto;
|
||||||
|
|
||||||
|
border-left: none;
|
||||||
|
border-right: 1px solid #aaa;
|
||||||
|
border-radius: 4px 0 0 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container .select2-choice .select2-arrow b {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: url('select2.png') no-repeat 0 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[dir="rtl"] .select2-container .select2-choice .select2-arrow b {
|
||||||
|
background-position: 2px 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-search {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 26px;
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 4px;
|
||||||
|
padding-right: 4px;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
z-index: 10000;
|
||||||
|
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-search input {
|
||||||
|
width: 100%;
|
||||||
|
height: auto !important;
|
||||||
|
min-height: 26px;
|
||||||
|
padding: 4px 20px 4px 5px;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
outline: 0;
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 1em;
|
||||||
|
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
border-radius: 0;
|
||||||
|
|
||||||
|
-webkit-box-shadow: none;
|
||||||
|
box-shadow: none;
|
||||||
|
|
||||||
|
background: #fff url('select2.png') no-repeat 100% -22px;
|
||||||
|
background: url('select2.png') no-repeat 100% -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee));
|
||||||
|
background: url('select2.png') no-repeat 100% -22px, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%);
|
||||||
|
background: url('select2.png') no-repeat 100% -22px, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%);
|
||||||
|
background: url('select2.png') no-repeat 100% -22px, linear-gradient(to bottom, #fff 85%, #eee 99%) 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[dir="rtl"] .select2-search input {
|
||||||
|
padding: 4px 5px 4px 20px;
|
||||||
|
|
||||||
|
background: #fff url('select2.png') no-repeat -37px -22px;
|
||||||
|
background: url('select2.png') no-repeat -37px -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee));
|
||||||
|
background: url('select2.png') no-repeat -37px -22px, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%);
|
||||||
|
background: url('select2.png') no-repeat -37px -22px, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%);
|
||||||
|
background: url('select2.png') no-repeat -37px -22px, linear-gradient(to bottom, #fff 85%, #eee 99%) 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-drop.select2-drop-above .select2-search input {
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-search input.select2-active {
|
||||||
|
background: #fff url('select2-spinner.gif') no-repeat 100%;
|
||||||
|
background: url('select2-spinner.gif') no-repeat 100%, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee));
|
||||||
|
background: url('select2-spinner.gif') no-repeat 100%, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%);
|
||||||
|
background: url('select2-spinner.gif') no-repeat 100%, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%);
|
||||||
|
background: url('select2-spinner.gif') no-repeat 100%, linear-gradient(to bottom, #fff 85%, #eee 99%) 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container-active .select2-choice,
|
||||||
|
.select2-container-active .select2-choices {
|
||||||
|
border: 1px solid #5897fb;
|
||||||
|
outline: none;
|
||||||
|
|
||||||
|
-webkit-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
|
||||||
|
box-shadow: 0 0 5px rgba(0, 0, 0, .3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-dropdown-open .select2-choice {
|
||||||
|
border-bottom-color: transparent;
|
||||||
|
-webkit-box-shadow: 0 1px 0 #fff inset;
|
||||||
|
box-shadow: 0 1px 0 #fff inset;
|
||||||
|
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
|
||||||
|
background-color: #eee;
|
||||||
|
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #fff), color-stop(0.5, #eee));
|
||||||
|
background-image: -webkit-linear-gradient(center bottom, #fff 0%, #eee 50%);
|
||||||
|
background-image: -moz-linear-gradient(center bottom, #fff 0%, #eee 50%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0);
|
||||||
|
background-image: linear-gradient(to top, #fff 0%, #eee 50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-dropdown-open.select2-drop-above .select2-choice,
|
||||||
|
.select2-dropdown-open.select2-drop-above .select2-choices {
|
||||||
|
border: 1px solid #5897fb;
|
||||||
|
border-top-color: transparent;
|
||||||
|
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #fff), color-stop(0.5, #eee));
|
||||||
|
background-image: -webkit-linear-gradient(center top, #fff 0%, #eee 50%);
|
||||||
|
background-image: -moz-linear-gradient(center top, #fff 0%, #eee 50%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0);
|
||||||
|
background-image: linear-gradient(to bottom, #fff 0%, #eee 50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-dropdown-open .select2-choice .select2-arrow {
|
||||||
|
background: transparent;
|
||||||
|
border-left: none;
|
||||||
|
filter: none;
|
||||||
|
}
|
||||||
|
html[dir="rtl"] .select2-dropdown-open .select2-choice .select2-arrow {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-dropdown-open .select2-choice .select2-arrow b {
|
||||||
|
background-position: -18px 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[dir="rtl"] .select2-dropdown-open .select2-choice .select2-arrow b {
|
||||||
|
background-position: -16px 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-hidden-accessible {
|
||||||
|
border: 0;
|
||||||
|
clip: rect(0 0 0 0);
|
||||||
|
height: 1px;
|
||||||
|
margin: -1px;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0;
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* results */
|
||||||
|
.select2-results {
|
||||||
|
max-height: 200px;
|
||||||
|
padding: 0 0 0 4px;
|
||||||
|
margin: 4px 4px 4px 0;
|
||||||
|
position: relative;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
html[dir="rtl"] .select2-results {
|
||||||
|
padding: 0 4px 0 0;
|
||||||
|
margin: 4px 0 4px 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-results ul.select2-result-sub {
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-results li {
|
||||||
|
list-style: none;
|
||||||
|
display: list-item;
|
||||||
|
background-image: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-results li.select2-result-with-children > .select2-result-label {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-results .select2-result-label {
|
||||||
|
padding: 3px 7px 4px;
|
||||||
|
margin: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
min-height: 1em;
|
||||||
|
|
||||||
|
-webkit-touch-callout: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-results-dept-1 .select2-result-label { padding-left: 20px }
|
||||||
|
.select2-results-dept-2 .select2-result-label { padding-left: 40px }
|
||||||
|
.select2-results-dept-3 .select2-result-label { padding-left: 60px }
|
||||||
|
.select2-results-dept-4 .select2-result-label { padding-left: 80px }
|
||||||
|
.select2-results-dept-5 .select2-result-label { padding-left: 100px }
|
||||||
|
.select2-results-dept-6 .select2-result-label { padding-left: 110px }
|
||||||
|
.select2-results-dept-7 .select2-result-label { padding-left: 120px }
|
||||||
|
|
||||||
|
.select2-results .select2-highlighted {
|
||||||
|
background: #3875d7;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-results li em {
|
||||||
|
background: #feffde;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-results .select2-highlighted em {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-results .select2-highlighted ul {
|
||||||
|
background: #fff;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-results .select2-no-results,
|
||||||
|
.select2-results .select2-searching,
|
||||||
|
.select2-results .select2-ajax-error,
|
||||||
|
.select2-results .select2-selection-limit {
|
||||||
|
background: #f4f4f4;
|
||||||
|
display: list-item;
|
||||||
|
padding-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
disabled look for disabled choices in the results dropdown
|
||||||
|
*/
|
||||||
|
.select2-results .select2-disabled.select2-highlighted {
|
||||||
|
color: #666;
|
||||||
|
background: #f4f4f4;
|
||||||
|
display: list-item;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
.select2-results .select2-disabled {
|
||||||
|
background: #f4f4f4;
|
||||||
|
display: list-item;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-results .select2-selected {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-more-results.select2-active {
|
||||||
|
background: #f4f4f4 url('select2-spinner.gif') no-repeat 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-results .select2-ajax-error {
|
||||||
|
background: rgba(255, 50, 50, .2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-more-results {
|
||||||
|
background: #f4f4f4;
|
||||||
|
display: list-item;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* disabled styles */
|
||||||
|
|
||||||
|
.select2-container.select2-container-disabled .select2-choice {
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
background-image: none;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container.select2-container-disabled .select2-choice .select2-arrow {
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
background-image: none;
|
||||||
|
border-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container.select2-container-disabled .select2-choice abbr {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* multiselect */
|
||||||
|
|
||||||
|
.select2-container-multi .select2-choices {
|
||||||
|
height: auto !important;
|
||||||
|
height: 1%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 5px 0 0;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
cursor: text;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
background-color: #fff;
|
||||||
|
background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(1%, #eee), color-stop(15%, #fff));
|
||||||
|
background-image: -webkit-linear-gradient(top, #eee 1%, #fff 15%);
|
||||||
|
background-image: -moz-linear-gradient(top, #eee 1%, #fff 15%);
|
||||||
|
background-image: linear-gradient(to bottom, #eee 1%, #fff 15%);
|
||||||
|
}
|
||||||
|
|
||||||
|
html[dir="rtl"] .select2-container-multi .select2-choices {
|
||||||
|
padding: 0 0 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-locked {
|
||||||
|
padding: 3px 5px 3px 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container-multi .select2-choices {
|
||||||
|
min-height: 26px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container-multi.select2-container-active .select2-choices {
|
||||||
|
border: 1px solid #5897fb;
|
||||||
|
outline: none;
|
||||||
|
|
||||||
|
-webkit-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
|
||||||
|
box-shadow: 0 0 5px rgba(0, 0, 0, .3);
|
||||||
|
}
|
||||||
|
.select2-container-multi .select2-choices li {
|
||||||
|
float: left;
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
html[dir="rtl"] .select2-container-multi .select2-choices li
|
||||||
|
{
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
.select2-container-multi .select2-choices .select2-search-field {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container-multi .select2-choices .select2-search-field input {
|
||||||
|
padding: 5px;
|
||||||
|
margin: 1px 0;
|
||||||
|
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 100%;
|
||||||
|
color: #666;
|
||||||
|
outline: 0;
|
||||||
|
border: 0;
|
||||||
|
-webkit-box-shadow: none;
|
||||||
|
box-shadow: none;
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container-multi .select2-choices .select2-search-field input.select2-active {
|
||||||
|
background: #fff url('select2-spinner.gif') no-repeat 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-default {
|
||||||
|
color: #999 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container-multi .select2-choices .select2-search-choice {
|
||||||
|
padding: 3px 5px 3px 18px;
|
||||||
|
margin: 3px 0 3px 5px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
line-height: 13px;
|
||||||
|
color: #333;
|
||||||
|
cursor: default;
|
||||||
|
border: 1px solid #aaaaaa;
|
||||||
|
|
||||||
|
border-radius: 3px;
|
||||||
|
|
||||||
|
-webkit-box-shadow: 0 0 2px #fff inset, 0 1px 0 rgba(0, 0, 0, 0.05);
|
||||||
|
box-shadow: 0 0 2px #fff inset, 0 1px 0 rgba(0, 0, 0, 0.05);
|
||||||
|
|
||||||
|
background-clip: padding-box;
|
||||||
|
|
||||||
|
-webkit-touch-callout: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
background-color: #e4e4e4;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#f4f4f4', GradientType=0);
|
||||||
|
background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eee));
|
||||||
|
background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
|
||||||
|
background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
|
||||||
|
background-image: linear-gradient(to bottom, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
|
||||||
|
}
|
||||||
|
html[dir="rtl"] .select2-container-multi .select2-choices .select2-search-choice
|
||||||
|
{
|
||||||
|
margin: 3px 5px 3px 0;
|
||||||
|
padding: 3px 18px 3px 5px;
|
||||||
|
}
|
||||||
|
.select2-container-multi .select2-choices .select2-search-choice .select2-chosen {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
.select2-container-multi .select2-choices .select2-search-choice-focus {
|
||||||
|
background: #d4d4d4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-search-choice-close {
|
||||||
|
display: block;
|
||||||
|
width: 12px;
|
||||||
|
height: 13px;
|
||||||
|
position: absolute;
|
||||||
|
right: 3px;
|
||||||
|
top: 4px;
|
||||||
|
|
||||||
|
font-size: 1px;
|
||||||
|
outline: none;
|
||||||
|
background: url('select2.png') right top no-repeat;
|
||||||
|
}
|
||||||
|
html[dir="rtl"] .select2-search-choice-close {
|
||||||
|
right: auto;
|
||||||
|
left: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container-multi .select2-search-choice-close {
|
||||||
|
left: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[dir="rtl"] .select2-container-multi .select2-search-choice-close {
|
||||||
|
left: auto;
|
||||||
|
right: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover {
|
||||||
|
background-position: right -11px;
|
||||||
|
}
|
||||||
|
.select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close {
|
||||||
|
background-position: right -11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* disabled styles */
|
||||||
|
.select2-container-multi.select2-container-disabled .select2-choices {
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
background-image: none;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice {
|
||||||
|
padding: 3px 5px 3px 5px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
background-image: none;
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close { display: none;
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
/* end multiselect */
|
||||||
|
|
||||||
|
|
||||||
|
.select2-result-selectable .select2-match,
|
||||||
|
.select2-result-unselectable .select2-match {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-offscreen, .select2-offscreen:focus {
|
||||||
|
clip: rect(0 0 0 0) !important;
|
||||||
|
width: 1px !important;
|
||||||
|
height: 1px !important;
|
||||||
|
border: 0 !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
position: absolute !important;
|
||||||
|
outline: 0 !important;
|
||||||
|
left: 0px !important;
|
||||||
|
top: 0px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-display-none {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-measure-scrollbar {
|
||||||
|
position: absolute;
|
||||||
|
top: -10000px;
|
||||||
|
left: -10000px;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
overflow: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Retina-ize icons */
|
||||||
|
|
||||||
|
@media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-resolution: 2dppx) {
|
||||||
|
.select2-search input,
|
||||||
|
.select2-search-choice-close,
|
||||||
|
.select2-container .select2-choice abbr,
|
||||||
|
.select2-container .select2-choice .select2-arrow b {
|
||||||
|
background-image: url('select2x2.png') !important;
|
||||||
|
background-repeat: no-repeat !important;
|
||||||
|
background-size: 60px 40px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-search input {
|
||||||
|
background-position: 100% -21px !important;
|
||||||
|
}
|
||||||
|
}
|
18
main/webapp/modules/core/externals/select2/select2.min.js
vendored
Normal file
18
main/webapp/modules/core/externals/select2/select2.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
main/webapp/modules/core/externals/select2/select2.png
vendored
Normal file
BIN
main/webapp/modules/core/externals/select2/select2.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 613 B |
BIN
main/webapp/modules/core/images/edit.png
Normal file
BIN
main/webapp/modules/core/images/edit.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
@ -72,6 +72,7 @@
|
|||||||
"sel-by-regex": "Select by Regex on File Names",
|
"sel-by-regex": "Select by Regex on File Names",
|
||||||
"parsing-options": "Configure Parsing Options",
|
"parsing-options": "Configure Parsing Options",
|
||||||
"project-name": "Project name",
|
"project-name": "Project name",
|
||||||
|
"project-tags": "Tags",
|
||||||
"updating-preview": "Updating preview ...",
|
"updating-preview": "Updating preview ...",
|
||||||
"parse-as": "Parse data as",
|
"parse-as": "Parse data as",
|
||||||
"this-computer": "This Computer",
|
"this-computer": "This Computer",
|
||||||
@ -112,7 +113,10 @@
|
|||||||
"warning-rename": "Failed to rename project:",
|
"warning-rename": "Failed to rename project:",
|
||||||
"warning-proj-name": "You must specify a project name.",
|
"warning-proj-name": "You must specify a project name.",
|
||||||
"warning-data-file": "You must specify a data file to upload or a URL to retrieve.",
|
"warning-data-file": "You must specify a data file to upload or a URL to retrieve.",
|
||||||
"browse": "Browse workspace directory"
|
"browse": "Browse workspace directory",
|
||||||
|
"tags": "Tags",
|
||||||
|
"edit-tags": "Edit project tags",
|
||||||
|
"edit-tags-desc": "Edit project tags (space and comma are delimiters):"
|
||||||
},
|
},
|
||||||
"core-index-lang": {
|
"core-index-lang": {
|
||||||
"lang-settings": "Language Settings",
|
"lang-settings": "Language Settings",
|
||||||
|
@ -278,9 +278,12 @@ Refine.DefaultImportingController.prototype._createProject = function() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var projectTags = $("#tagsInput").val().split(",");
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
var options = this._formatParserUI.getOptions();
|
var options = this._formatParserUI.getOptions();
|
||||||
options.projectName = projectName;
|
options.projectName = projectName;
|
||||||
|
options.projectTags = projectTags;
|
||||||
$.post(
|
$.post(
|
||||||
"command/core/importing-controller?" + $.param({
|
"command/core/importing-controller?" + $.param({
|
||||||
"controller": "core/default-importing-controller",
|
"controller": "core/default-importing-controller",
|
||||||
@ -333,3 +336,27 @@ Refine.DefaultImportingController.prototype._createProject = function() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Refine.TagsManager = {};
|
||||||
|
Refine.TagsManager.allProjectTags = [];
|
||||||
|
|
||||||
|
Refine.TagsManager._getAllProjectTags = function() {
|
||||||
|
var self = this;
|
||||||
|
if (self.allProjectTags.length === 0) {
|
||||||
|
jQuery.ajax({
|
||||||
|
url : "command/core/get-all-project-tags",
|
||||||
|
success : function(result) {
|
||||||
|
var array = result.tags.sort(function (a, b) {
|
||||||
|
return a.toLowerCase().localeCompare(b.toLowerCase());
|
||||||
|
});
|
||||||
|
|
||||||
|
array.map(function(item){
|
||||||
|
self.allProjectTags.push(item);
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
async : false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return self.allProjectTags;
|
||||||
|
};
|
||||||
|
@ -4,6 +4,12 @@
|
|||||||
<td width="98%" id="or-import-parsopt"></td>
|
<td width="98%" id="or-import-parsopt"></td>
|
||||||
<td style="text-align: right;" id="or-import-projname"></td>
|
<td style="text-align: right;" id="or-import-projname"></td>
|
||||||
<td width="1%"><input class="inline" type="text" size="30" bind="projectNameInput" /></td>
|
<td width="1%"><input class="inline" type="text" size="30" bind="projectNameInput" /></td>
|
||||||
|
<td style="text-align: right;" id="or-import-projtags"></td>
|
||||||
|
<td width="1%">
|
||||||
|
<div id="project-tags-container" class="inline">
|
||||||
|
<input type="hidden" id="tagsInput" style="width: 300px;" />
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
<td width="1%"><button bind="nextButton" class="button button-primary"></button></td>
|
<td width="1%"><button bind="nextButton" class="button button-primary"></button></td>
|
||||||
</tr></table></div></div>
|
</tr></table></div></div>
|
||||||
|
|
||||||
|
@ -96,9 +96,16 @@ Refine.DefaultImportingController.prototype._prepareParsingPanel = function() {
|
|||||||
this._parsingPanelElmts.nextButton.html($.i18n._('core-buttons')["create-project"]);
|
this._parsingPanelElmts.nextButton.html($.i18n._('core-buttons')["create-project"]);
|
||||||
$('#or-import-parsopt').text($.i18n._('core-index-import')["parsing-options"]);
|
$('#or-import-parsopt').text($.i18n._('core-index-import')["parsing-options"]);
|
||||||
$('#or-import-projname').html($.i18n._('core-index-import')["project-name"]);
|
$('#or-import-projname').html($.i18n._('core-index-import')["project-name"]);
|
||||||
|
$('#or-import-projtags').html($.i18n._('core-index-import')["project-tags"]);
|
||||||
$('#or-import-updating').text($.i18n._('core-index-import')["updating-preview"]);
|
$('#or-import-updating').text($.i18n._('core-index-import')["updating-preview"]);
|
||||||
$('#or-import-parseas').text($.i18n._('core-index-import')["parse-as"]);
|
$('#or-import-parseas').text($.i18n._('core-index-import')["parse-as"]);
|
||||||
|
|
||||||
|
//tags dropdown
|
||||||
|
$("#tagsInput").select2({
|
||||||
|
tags: Refine.TagsManager._getAllProjectTags() ,
|
||||||
|
tokenSeparators: [",", " "]
|
||||||
|
});
|
||||||
|
|
||||||
this._parsingPanelResizer = function() {
|
this._parsingPanelResizer = function() {
|
||||||
var elmts = self._parsingPanelElmts;
|
var elmts = self._parsingPanelElmts;
|
||||||
var width = self._parsingPanel.width();
|
var width = self._parsingPanel.width();
|
||||||
|
@ -21,11 +21,38 @@ function EditMetadataDialog(metaData, targetRowElem) {
|
|||||||
|
|
||||||
var td2 = tr.insertCell(2);
|
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("]","");
|
||||||
|
oldTags = replaceAll(oldTags,"\"","");
|
||||||
|
var newTags = window.prompt($.i18n._('core-index')["change-metadata-value"]+" " + key, $(td1).text());
|
||||||
|
newTags = newTags.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, project);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (key !== "created" &&
|
if (key !== "created" &&
|
||||||
key !== "modified" &&
|
key !== "modified" &&
|
||||||
key !== "rowCount" &&
|
key !== "rowCount" &&
|
||||||
key !== "importOptionMetadata" &&
|
key !== "importOptionMetadata" &&
|
||||||
key !== "id") {
|
key !== "id" &&
|
||||||
|
key !== "tags") {
|
||||||
$('<button class="button">').text($.i18n._('core-index')["edit"]).appendTo(td2).click(function() {
|
$('<button class="button">').text($.i18n._('core-index')["edit"]).appendTo(td2).click(function() {
|
||||||
var newValue = window.prompt($.i18n._('core-index')["change-metadata-value"]+" " + key, value);
|
var newValue = window.prompt($.i18n._('core-index')["change-metadata-value"]+" " + key, value);
|
||||||
if (newValue !== null) {
|
if (newValue !== null) {
|
||||||
@ -47,7 +74,7 @@ function EditMetadataDialog(metaData, targetRowElem) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Refine.OpenProjectUI.refreshProject(targetRowElem, metaData);
|
Refine.OpenProjectUI.refreshProject(targetRowElem, metaData, project);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -63,7 +90,7 @@ EditMetadataDialog.prototype._createDialog = function() {
|
|||||||
|
|
||||||
this._level = DialogSystem.showDialog(frame);
|
this._level = DialogSystem.showDialog(frame);
|
||||||
this._elmts.closeButton.html($.i18n._('core-buttons')["close"]);
|
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");
|
var body = $("#metadata-body");
|
||||||
|
|
||||||
@ -111,3 +138,11 @@ EditMetadataDialog.prototype._dismiss = function() {
|
|||||||
DialogSystem.dismissUntil(this._level - 1);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
<div class="relative-frame">
|
<div class="relative-frame">
|
||||||
<div bind="projectsContainer" id="projects-container"></div>
|
<div bind="projectsContainer" id="projects-container">
|
||||||
<div bind="workspaceControls" id="projects-workspace-controls"><a id="projects-workspace-open" href="javascript:{}" class="secondary"></a></div>
|
<div bind="projectTags" id="projectTags"></div>
|
||||||
</div>
|
<div bind="projectList" id="projects-list"></div>
|
||||||
|
</div>
|
||||||
|
<div bind="workspaceControls" id="projects-workspace-controls">
|
||||||
|
<a id="projects-workspace-open" href="javascript:{}" class="secondary"></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -70,8 +70,8 @@ Refine.OpenProjectUI = function(elmt) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Refine.TagsManager.allProjectTags = [];
|
||||||
this._fetchProjects();
|
this._buildTagsAndFetchProjects();
|
||||||
};
|
};
|
||||||
|
|
||||||
Refine.OpenProjectUI.prototype.resize = function() {
|
Refine.OpenProjectUI.prototype.resize = function() {
|
||||||
@ -100,6 +100,53 @@ Refine.OpenProjectUI.prototype._fetchProjects = function() {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Refine.OpenProjectUI.prototype._buildTagsAndFetchProjects = function() {
|
||||||
|
this._buildTagsListPanel();
|
||||||
|
this._fetchProjects();
|
||||||
|
};
|
||||||
|
|
||||||
|
Refine.OpenProjectUI.prototype._buildTagsListPanel = function() {
|
||||||
|
var self = this;
|
||||||
|
self._allTags = Refine.TagsManager._getAllProjectTags();
|
||||||
|
|
||||||
|
var container = self._elmts.projectTags.empty();
|
||||||
|
var ul = $("<ul/>").attr('id', 'tagsUl').appendTo(container);
|
||||||
|
|
||||||
|
// Add 'all' menu item
|
||||||
|
var li = $('<li/>').addClass("active").appendTo(ul);
|
||||||
|
$('<a/>').attr('href', '#all').addClass("current").text('All').appendTo(li);
|
||||||
|
|
||||||
|
$.each(self._allTags, function(i) {
|
||||||
|
var li = $('<li/>').appendTo(ul);
|
||||||
|
$('<a/>').attr('href', '#' + self._allTags[i]).text(self._allTags[i])
|
||||||
|
.appendTo(li);
|
||||||
|
});
|
||||||
|
|
||||||
|
self._addTagsListAnimation();
|
||||||
|
};
|
||||||
|
|
||||||
|
Refine.OpenProjectUI.prototype._addTagsListAnimation = function() {
|
||||||
|
$("#tagsUl").lavalamp({
|
||||||
|
setOnClick : true,
|
||||||
|
duration : 300
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Refine.OpenProjectUI.prototype._fetchProjects = function() {
|
||||||
|
var self = this;
|
||||||
|
$.ajax({
|
||||||
|
type : 'GET',
|
||||||
|
url : "command/core/get-all-project-metadata",
|
||||||
|
dataType : 'json',
|
||||||
|
success : function(data) {
|
||||||
|
self._renderProjects(data);
|
||||||
|
self.resize();
|
||||||
|
},
|
||||||
|
data : {},
|
||||||
|
async : false
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
Refine.OpenProjectUI.prototype._renderProjects = function(data) {
|
Refine.OpenProjectUI.prototype._renderProjects = function(data) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var projects = [];
|
var projects = [];
|
||||||
@ -131,11 +178,13 @@ Refine.OpenProjectUI.prototype._renderProjects = function(data) {
|
|||||||
projects.push(project);
|
projects.push(project);
|
||||||
}
|
}
|
||||||
|
|
||||||
var container = $("#projects-container").empty();
|
var container = self._elmts.projectList.empty();
|
||||||
if (!projects.length) {
|
if (!projects.length) {
|
||||||
$("#no-project-message").clone().show().appendTo(container);
|
$("#no-project-message").clone().show().appendTo(container);
|
||||||
} else {
|
} else {
|
||||||
Refine.selectActionArea('open-project');
|
Refine.selectActionArea('open-project');
|
||||||
|
|
||||||
|
var projectsUl = $("<ul/>").attr('id', 'projectsUl').appendTo(container);
|
||||||
|
|
||||||
var table = $(
|
var table = $(
|
||||||
'<table class="tablesorter-blue list-table"><thead><tr>' +
|
'<table class="tablesorter-blue list-table"><thead><tr>' +
|
||||||
@ -143,6 +192,7 @@ Refine.OpenProjectUI.prototype._renderProjects = function(data) {
|
|||||||
'<th></th>' +
|
'<th></th>' +
|
||||||
'<th>'+$.i18n._('core-index-open')["last-mod"]+'</th>' +
|
'<th>'+$.i18n._('core-index-open')["last-mod"]+'</th>' +
|
||||||
'<th>'+$.i18n._('core-index-open')["name"]+'</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')["creator"]+'</th>' +
|
||||||
'<th>'+$.i18n._('core-index-open')["subject"]+'</th>' +
|
'<th>'+$.i18n._('core-index-open')["subject"]+'</th>' +
|
||||||
'<th>'+$.i18n._('core-index-open')["description"]+'</th>' +
|
'<th>'+$.i18n._('core-index-open')["description"]+'</th>' +
|
||||||
@ -157,8 +207,8 @@ Refine.OpenProjectUI.prototype._renderProjects = function(data) {
|
|||||||
|
|
||||||
return htmlDisplay;
|
return htmlDisplay;
|
||||||
})() +
|
})() +
|
||||||
'</tr></thead><tbody></tbody></table>'
|
'</tr></thead><tbody id="tableBody"></tbody></table>'
|
||||||
).appendTo(container)[0];
|
).appendTo(projectsUl)[0];
|
||||||
|
|
||||||
var renderProject = function(project) {
|
var renderProject = function(project) {
|
||||||
var tr = table.getElementsByTagName('tbody')[0].insertRow(table.rows.length - 1);
|
var tr = table.getElementsByTagName('tbody')[0].insertRow(table.rows.length - 1);
|
||||||
@ -178,7 +228,8 @@ Refine.OpenProjectUI.prototype._renderProjects = function(data) {
|
|||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
if (data && typeof data.code != 'undefined' && data.code == "ok") {
|
if (data && typeof data.code != 'undefined' && data.code == "ok") {
|
||||||
self._fetchProjects();
|
Refine.TagsManager.allProjectTags = [];
|
||||||
|
self._buildTagsAndFetchProjects();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -210,25 +261,41 @@ Refine.OpenProjectUI.prototype._renderProjects = function(data) {
|
|||||||
.attr("href", "project?project=" + project.id)
|
.attr("href", "project?project=" + project.id)
|
||||||
.appendTo($(tr.insertCell(tr.cells.length)));
|
.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);
|
var tagsCell = $(tr.insertCell(tr.cells.length));
|
||||||
appendMetaField(project.description, '20%');
|
var tags = project.tags;
|
||||||
appendMetaField(project.rowCount);
|
tags.map(function(tag){
|
||||||
|
$("<span/>")
|
||||||
var data = project.userMetadata;
|
.addClass("project-tag")
|
||||||
for(var i in data)
|
.text(tag)
|
||||||
{
|
.attr("title", $.i18n._('core-index-open')["edit-tags"])
|
||||||
if (data[i].display === true) {
|
.appendTo(tagsCell);
|
||||||
appendMetaField(data[i].value);
|
$(tr).addClass(tag);
|
||||||
}
|
});
|
||||||
}
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
for (var i = 0; i < projects.length; i++) {
|
for (var i = 0; i < projects.length; i++) {
|
||||||
renderProject(projects[i]);
|
renderProject(projects[i]);
|
||||||
@ -243,9 +310,14 @@ Refine.OpenProjectUI.prototype._renderProjects = function(data) {
|
|||||||
sortList: [[2,1]],
|
sortList: [[2,1]],
|
||||||
widthFixed: false
|
widthFixed: false
|
||||||
});
|
});
|
||||||
|
self._addTagFilter();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Refine.OpenProjectUI.prototype._addTagFilter = function() {
|
||||||
|
$("#tableBody").filterList();
|
||||||
|
};
|
||||||
|
|
||||||
Refine.OpenProjectUI.prototype._onClickUploadFileButton = function(evt) {
|
Refine.OpenProjectUI.prototype._onClickUploadFileButton = function(evt) {
|
||||||
var projectName = $("#project-name-input")[0].value;
|
var projectName = $("#project-name-input")[0].value;
|
||||||
var dataURL = $.trim($("#project-url-input")[0].value);
|
var dataURL = $.trim($("#project-url-input")[0].value);
|
||||||
@ -276,19 +348,47 @@ Refine.OpenProjectUI.prototype._onClickUploadFileButton = function(evt) {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
Refine.OpenProjectUI.refreshProject = function(tr, metaData) {
|
Refine.OpenProjectUI.refreshProject = function(tr, metaData, project) {
|
||||||
|
|
||||||
var refreshMetaField = function(data, index) {
|
var refreshMetaField = function(data, index) {
|
||||||
if (index === 3) {
|
if (index === 3) {
|
||||||
$('a', $('td', tr).eq(index))
|
$('a', $('td', tr).eq(index))
|
||||||
.text(data);
|
.text(data);
|
||||||
} else {
|
} else {
|
||||||
$('td', tr).eq(index)
|
$('td', tr).eq(index).find('div')
|
||||||
.text(data);
|
.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);
|
||||||
|
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);
|
||||||
|
tagCol.parent().addClass(tag);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
var index = 3;
|
var index = 3;
|
||||||
refreshMetaField(metaData.name, index); index++;
|
refreshMetaField(metaData.name, index); index++;
|
||||||
|
refreshMetaTags(metaData.tags, index); index++;
|
||||||
refreshMetaField(metaData.creator, index); index++;
|
refreshMetaField(metaData.creator, index); index++;
|
||||||
refreshMetaField(metaData.subject,index); index++;
|
refreshMetaField(metaData.subject,index); index++;
|
||||||
refreshMetaField(metaData.description,index); index++;
|
refreshMetaField(metaData.description,index); index++;
|
||||||
@ -316,11 +416,25 @@ Refine.OpenProjectUI.refreshProject = function(tr, metaData) {
|
|||||||
refreshMetaField(data[i].value,index); index++;
|
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({
|
Refine.actionAreas.push({
|
||||||
id: "open-project",
|
id: "open-project",
|
||||||
label: $.i18n._('core-index-open')["open-proj"],
|
label: $.i18n._('core-index-open')["open-proj"],
|
||||||
uiClass: Refine.OpenProjectUI
|
uiClass: Refine.OpenProjectUI
|
||||||
});
|
});
|
62
main/webapp/modules/core/scripts/util/filter-lists.js
Normal file
62
main/webapp/modules/core/scripts/util/filter-lists.js
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2009 Joel Sutherland.
|
||||||
|
* Liscenced under the MIT liscense
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function($) {
|
||||||
|
$.fn.filterList = function(settings) {
|
||||||
|
settings = $.extend(
|
||||||
|
{
|
||||||
|
animationSpeed: 500,
|
||||||
|
show: { height: 'show', opacity: 'show' },
|
||||||
|
hide: { height: 'hide', opacity: 'hide' },
|
||||||
|
useTags: true,
|
||||||
|
tagSelector: '#projectTags a',
|
||||||
|
selectedTagClass: 'current',
|
||||||
|
allTag: 'all'
|
||||||
|
}, settings);
|
||||||
|
|
||||||
|
var listElement = $(this);
|
||||||
|
|
||||||
|
/* FILTER: select a tag and filter */
|
||||||
|
listElement.bind("filter", function( e, tagToShow ){
|
||||||
|
if(settings.useTags){
|
||||||
|
$(settings.tagSelector).removeClass(settings.selectedTagClass);
|
||||||
|
$(settings.tagSelector + '[href=' + tagToShow + ']').addClass(settings.selectedTagClass);
|
||||||
|
}
|
||||||
|
$(this).trigger("filterMyList", [ tagToShow.substr(1) ]);
|
||||||
|
});
|
||||||
|
|
||||||
|
/* FILTERPORTFOLIO: pass in a class to show, all others will be hidden */
|
||||||
|
listElement.bind("filterMyList", function( e, classToShow ){
|
||||||
|
if(classToShow === settings.allTag){
|
||||||
|
$(this).trigger("show");
|
||||||
|
}else{
|
||||||
|
$(this).trigger("show", [ '.' + classToShow ] );
|
||||||
|
$(this).trigger("hide", [ ':not(.' + classToShow + ')' ] );
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* SHOW: show a single class*/
|
||||||
|
$(this).bind("show", function( e, selectorToShow ){
|
||||||
|
listElement.children(selectorToShow).animate(settings.show, settings.animationSpeed);
|
||||||
|
});
|
||||||
|
|
||||||
|
/* SHOW: hide a single class*/
|
||||||
|
$(this).bind("hide", function( e, selectorToHide ){
|
||||||
|
listElement.children(selectorToHide).animate(settings.hide, settings.animationSpeed * 0.6);
|
||||||
|
});
|
||||||
|
|
||||||
|
/* ============ Setup Tags ====================*/
|
||||||
|
if(settings.useTags){
|
||||||
|
$(settings.tagSelector).on("click", function(){
|
||||||
|
listElement.trigger("filter", [ $(this).attr('href') ]);
|
||||||
|
|
||||||
|
$(settings.tagSelector).removeClass('current');
|
||||||
|
$(this).addClass('current');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
})(jQuery);
|
@ -139,3 +139,71 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#metadata-body > table > tbody > tr:nth-child(1) > th:nth-child(3) {
|
#metadata-body > table > tbody > tr:nth-child(1) > th:nth-child(3) {
|
||||||
width: 4%
|
width: 4%
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Project Tags */
|
||||||
|
#projectTags {
|
||||||
|
position: relative;
|
||||||
|
padding: 3px 10px;
|
||||||
|
margin: 5px;
|
||||||
|
font-size: 130%;
|
||||||
|
border-radius: 5px;
|
||||||
|
-moz-border-radius: 5px;
|
||||||
|
-webkit-border-radius: 5px;
|
||||||
|
background: #bcf;
|
||||||
|
min-height: 18px;
|
||||||
|
height: auto;
|
||||||
|
overflow:auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul#tagsUl {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul#tagsUl li {
|
||||||
|
list-style: none;
|
||||||
|
float: left;
|
||||||
|
text-align: center;
|
||||||
|
min-width: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul#tagsUl li a {
|
||||||
|
padding: 6px 5px;
|
||||||
|
display : inline-block;
|
||||||
|
text-align: center;
|
||||||
|
color: #444;
|
||||||
|
text-shadow: 0 -1px 2px rgba(255, 255, 255, 0.60);
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: bold;
|
||||||
|
min-width: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul#tagsUl li a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#projectTags .lavalamp-object {
|
||||||
|
background-color: #DEE6FF;
|
||||||
|
border-radius: 10px;
|
||||||
|
-moz-border-radius: 10px;
|
||||||
|
-webkit-border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Project List */
|
||||||
|
#projects-list{
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project .project-tag {
|
||||||
|
float: left;
|
||||||
|
padding: 3px 8px;
|
||||||
|
margin: 0px 2px;
|
||||||
|
border-radius: 3px;
|
||||||
|
-moz-border-radius: 3px;
|
||||||
|
-webkit-border-radius: 3px;
|
||||||
|
font-size: 100%;
|
||||||
|
font-weight: bold;
|
||||||
|
background: #28458A;
|
||||||
|
color: white;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user