Merge branch 'master' into replaceGUI
This commit is contained in:
commit
726960b410
50
extensions/wikidata/module/langs/translation-it.json
Normal file
50
extensions/wikidata/module/langs/translation-it.json
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"wikidata-extension": {
|
||||||
|
"edit-wikidata-schema": "Modifica lo schema per Wikidata",
|
||||||
|
"manage-wikidata-account": "Gestisci il tuo account su Wikidata",
|
||||||
|
"perform-edits-on-wikidata": "Carica le tue modifiche su Wikidata",
|
||||||
|
"export-to-qs": "Esporta verso QuickStatements",
|
||||||
|
"quickstatements-export-name": "QuickStatements"
|
||||||
|
},
|
||||||
|
"wikidata-schema": {
|
||||||
|
"dialog-explanation": "Lo schema per Wikidata ti permette di trasformare i dati nella tua tabella in modifiche pronte per Wikidata. Puoi trascinare i nomi delle colonne nei box di testo appropriati: in questo modo, per ogni riga verranno generate delle modifiche su Wikidata con i valori presenti.",
|
||||||
|
"preview-explanation": "Questa pagina mostra solo i primi risultati (su {nb_edits}) delle modifiche che verranno effettuate su Wikidata. Puoi usare le faccette per controllare le singole modifiche sugli elementi.",
|
||||||
|
"schema-tab-header": "Schema",
|
||||||
|
"warnings-tab-header": "Problemi",
|
||||||
|
"edits-preview-tab-header": "Anteprima",
|
||||||
|
"statements-header": "Dichiarazioni",
|
||||||
|
"terms-header": "Termini",
|
||||||
|
"empty-statements": "Nessuna dichiarazione generata",
|
||||||
|
"empty-terms": "Nessuna etichetta, descrizione o alias aggiunto",
|
||||||
|
"add-item-button": "aggiungi elemento",
|
||||||
|
"add-term": "aggiungi termine",
|
||||||
|
"remove": "rimuovi",
|
||||||
|
"add-statement": "aggiungi dichiarazione",
|
||||||
|
"add-value": "aggiungi valore",
|
||||||
|
"add-qualifier": "aggiungi qualificatore",
|
||||||
|
"add-reference": "aggiungi fonte",
|
||||||
|
"add-reference-snak": "aggiungi",
|
||||||
|
"property-placeholder": "proprietà",
|
||||||
|
"nb-references": " note",
|
||||||
|
"remove-column": "rimuovi colonna",
|
||||||
|
"label": "Etichetta",
|
||||||
|
"description": "Descrizione",
|
||||||
|
"alias": "Alias",
|
||||||
|
"item-or-reconciled-column": "digita l'elemento o trascina una colonna riconciliata",
|
||||||
|
"amount": "quantità",
|
||||||
|
"unit": "unità",
|
||||||
|
"full-url": "URL completo (compreso http:// o https://)",
|
||||||
|
"tabular-data-with-prefix": "nome del file (compreso \"Data:\")",
|
||||||
|
"commons-media": "nome del file",
|
||||||
|
"math-expression": "espressione matematica",
|
||||||
|
"geoshape-with-prefix": "nome del file (compreso \"Data:\")",
|
||||||
|
"datatype-not-supported-yet": "Ci dispiace, questo tipo di dato non è ancora supportato.",
|
||||||
|
"invalid-schema-warning-issues": "Il tuo schema è incompleto, per favore correggilo per vedere gli errori.",
|
||||||
|
"invalid-schema-warning-preview": "Il tuo schema è incompleto, per favore correggilo per vedere l'anteprima.",
|
||||||
|
"discard-button": "Non salvare le modifiche",
|
||||||
|
"save-button": "Salva lo schema",
|
||||||
|
"close-button": "Chiudi",
|
||||||
|
"unsaved-changes-alt": "Non hai salvato alcune modifiche al tuo schema Wikidata.",
|
||||||
|
"save-schema-alt": "Salva lo schema. Non verrà ancora effettuata alcuna modifica su Wikidata."
|
||||||
|
}
|
||||||
|
}
|
@ -192,7 +192,8 @@ public class EditBatchProcessor {
|
|||||||
logger.info("Requesting documents");
|
logger.info("Requesting documents");
|
||||||
currentDocs = null;
|
currentDocs = null;
|
||||||
int retries = 3;
|
int retries = 3;
|
||||||
while (currentDocs == null && retries > 0) {
|
// TODO: remove currentDocs.isEmpty() once https://github.com/Wikidata/Wikidata-Toolkit/issues/402 is solved
|
||||||
|
while ((currentDocs == null || currentDocs.isEmpty()) && retries > 0) {
|
||||||
try {
|
try {
|
||||||
currentDocs = fetcher.getEntityDocuments(qidsToFetch);
|
currentDocs = fetcher.getEntityDocuments(qidsToFetch);
|
||||||
} catch (MediaWikiApiErrorException e) {
|
} catch (MediaWikiApiErrorException e) {
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.google.refine.commands.recon;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import com.google.refine.browsing.EngineConfig;
|
||||||
|
import com.google.refine.commands.EngineDependentCommand;
|
||||||
|
import com.google.refine.model.AbstractOperation;
|
||||||
|
import com.google.refine.model.Project;
|
||||||
|
import com.google.refine.model.ReconCandidate;
|
||||||
|
import com.google.refine.model.recon.StandardReconConfig;
|
||||||
|
import com.google.refine.operations.recon.ReconMatchSpecificTopicOperation;
|
||||||
|
import com.google.refine.operations.recon.ReconUseValuesAsIdentifiersOperation;
|
||||||
|
|
||||||
|
public class ReconUseValuesAsIdentifiersCommand extends EngineDependentCommand {
|
||||||
|
@Override
|
||||||
|
protected AbstractOperation createOperation(Project project,
|
||||||
|
HttpServletRequest request, EngineConfig engineConfig) throws Exception {
|
||||||
|
|
||||||
|
String columnName = request.getParameter("columnName");
|
||||||
|
|
||||||
|
return new ReconUseValuesAsIdentifiersOperation(
|
||||||
|
engineConfig,
|
||||||
|
columnName,
|
||||||
|
request.getParameter("service"),
|
||||||
|
request.getParameter("identifierSpace"),
|
||||||
|
request.getParameter("schemaSpace")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -101,6 +101,28 @@ public class SeparatorBasedImporter extends TabularImportingParserBase {
|
|||||||
boolean processQuotes = JSONUtilities.getBoolean(options, "processQuotes", true);
|
boolean processQuotes = JSONUtilities.getBoolean(options, "processQuotes", true);
|
||||||
boolean strictQuotes = JSONUtilities.getBoolean(options, "strictQuotes", false);
|
boolean strictQuotes = JSONUtilities.getBoolean(options, "strictQuotes", false);
|
||||||
|
|
||||||
|
|
||||||
|
List<Object> retrievedColumnNames = null;
|
||||||
|
if (options.has("columnNames")) {
|
||||||
|
String[] strings = JSONUtilities.getStringArray(options, "columnNames");
|
||||||
|
if (strings.length > 0) {
|
||||||
|
retrievedColumnNames = new ArrayList<Object>();
|
||||||
|
for (String s : strings) {
|
||||||
|
s = s.trim();
|
||||||
|
if (!s.isEmpty()) {
|
||||||
|
retrievedColumnNames.add(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!retrievedColumnNames.isEmpty()) {
|
||||||
|
JSONUtilities.safePut(options, "headerLines", 1);
|
||||||
|
} else {
|
||||||
|
retrievedColumnNames = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final List<Object> columnNames = retrievedColumnNames;
|
||||||
|
|
||||||
Character quote = CSVParser.DEFAULT_QUOTE_CHARACTER;
|
Character quote = CSVParser.DEFAULT_QUOTE_CHARACTER;
|
||||||
String quoteCharacter = JSONUtilities.getString(options, "quoteCharacter", null);
|
String quoteCharacter = JSONUtilities.getString(options, "quoteCharacter", null);
|
||||||
if (quoteCharacter != null && quoteCharacter.trim().length() == 1) {
|
if (quoteCharacter != null && quoteCharacter.trim().length() == 1) {
|
||||||
@ -118,14 +140,20 @@ public class SeparatorBasedImporter extends TabularImportingParserBase {
|
|||||||
final LineNumberReader lnReader = new LineNumberReader(reader);
|
final LineNumberReader lnReader = new LineNumberReader(reader);
|
||||||
|
|
||||||
TableDataReader dataReader = new TableDataReader() {
|
TableDataReader dataReader = new TableDataReader() {
|
||||||
|
boolean usedColumnNames = false;
|
||||||
@Override
|
@Override
|
||||||
public List<Object> getNextRowOfCells() throws IOException {
|
public List<Object> getNextRowOfCells() throws IOException {
|
||||||
|
if (columnNames != null && !usedColumnNames) {
|
||||||
|
usedColumnNames = true;
|
||||||
|
return columnNames;
|
||||||
|
} else {
|
||||||
String line = lnReader.readLine();
|
String line = lnReader.readLine();
|
||||||
if (line == null) {
|
if (line == null) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return getCells(line, parser, lnReader);
|
return getCells(line, parser, lnReader);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -0,0 +1,157 @@
|
|||||||
|
package com.google.refine.operations.recon;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.json.JSONWriter;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
import com.google.refine.browsing.EngineConfig;
|
||||||
|
import com.google.refine.browsing.RowVisitor;
|
||||||
|
import com.google.refine.expr.ExpressionUtils;
|
||||||
|
import com.google.refine.history.Change;
|
||||||
|
import com.google.refine.model.Cell;
|
||||||
|
import com.google.refine.model.Column;
|
||||||
|
import com.google.refine.model.Project;
|
||||||
|
import com.google.refine.model.Recon;
|
||||||
|
import com.google.refine.model.Recon.Judgment;
|
||||||
|
import com.google.refine.model.ReconCandidate;
|
||||||
|
import com.google.refine.model.Row;
|
||||||
|
import com.google.refine.model.changes.CellChange;
|
||||||
|
import com.google.refine.model.changes.ReconChange;
|
||||||
|
import com.google.refine.model.recon.StandardReconConfig;
|
||||||
|
import com.google.refine.operations.EngineDependentMassCellOperation;
|
||||||
|
import com.google.refine.operations.OperationRegistry;
|
||||||
|
|
||||||
|
public class ReconUseValuesAsIdentifiersOperation extends EngineDependentMassCellOperation {
|
||||||
|
|
||||||
|
@JsonProperty("identifierSpace")
|
||||||
|
protected String identifierSpace;
|
||||||
|
@JsonProperty("schemaSpace")
|
||||||
|
protected String schemaSpace;
|
||||||
|
@JsonProperty("service")
|
||||||
|
protected String service;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
protected StandardReconConfig reconConfig;
|
||||||
|
|
||||||
|
public ReconUseValuesAsIdentifiersOperation(
|
||||||
|
EngineConfig engineConfig,
|
||||||
|
String columnName,
|
||||||
|
String service,
|
||||||
|
String identifierSpace,
|
||||||
|
String schemaSpace) {
|
||||||
|
super(engineConfig, columnName, false);
|
||||||
|
this.service = service;
|
||||||
|
this.identifierSpace = identifierSpace;
|
||||||
|
this.schemaSpace = schemaSpace;
|
||||||
|
this.reconConfig = new StandardReconConfig(service, identifierSpace, schemaSpace, null, null, true, Collections.emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
|
static public ReconUseValuesAsIdentifiersOperation reconstruct(JSONObject obj) throws Exception {
|
||||||
|
JSONObject engineConfig = obj.getJSONObject("engineConfig");
|
||||||
|
return new ReconUseValuesAsIdentifiersOperation(
|
||||||
|
EngineConfig.reconstruct(engineConfig),
|
||||||
|
obj.getString("columnName"),
|
||||||
|
obj.getString("service"),
|
||||||
|
obj.getString("identifierSpace"),
|
||||||
|
obj.getString("schemaSpace")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(JSONWriter writer, Properties options)
|
||||||
|
throws JSONException {
|
||||||
|
writer.object();
|
||||||
|
writer.key("op"); writer.value(OperationRegistry.s_opClassToName.get(this.getClass()));
|
||||||
|
writer.key("description"); writer.value(getBriefDescription(null));
|
||||||
|
writer.key("engineConfig"); getEngineConfig().write(writer, options);
|
||||||
|
writer.key("columnName"); writer.value(_columnName);
|
||||||
|
writer.key("service"); writer.value(service);
|
||||||
|
writer.key("schemaSpace"); writer.value(schemaSpace);
|
||||||
|
writer.key("identifierSpace"); writer.value(identifierSpace);
|
||||||
|
writer.endObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getBriefDescription(Project project) {
|
||||||
|
return "Use values as reconciliation identifiers in column " + _columnName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected RowVisitor createRowVisitor(Project project, List<CellChange> cellChanges, long historyEntryID)
|
||||||
|
throws Exception {
|
||||||
|
Column column = project.columnModel.getColumnByName(_columnName);
|
||||||
|
|
||||||
|
return new RowVisitor() {
|
||||||
|
int cellIndex;
|
||||||
|
List<CellChange> cellChanges;
|
||||||
|
long historyEntryID;
|
||||||
|
|
||||||
|
public RowVisitor init(int cellIndex, List<CellChange> cellChanges, long historyEntryID) {
|
||||||
|
this.cellIndex = cellIndex;
|
||||||
|
this.cellChanges = cellChanges;
|
||||||
|
this.historyEntryID = historyEntryID;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start(Project project) {
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void end(Project project) {
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean visit(Project project, int rowIndex, Row row) {
|
||||||
|
Cell cell = row.getCell(cellIndex);
|
||||||
|
if (cell != null && ExpressionUtils.isNonBlankData(cell.value)) {
|
||||||
|
String id = cell.value.toString();
|
||||||
|
|
||||||
|
ReconCandidate match = new ReconCandidate(id, id, new String[0], 100);
|
||||||
|
Recon newRecon = reconConfig.createNewRecon(historyEntryID);
|
||||||
|
newRecon.match = match;
|
||||||
|
newRecon.candidates = Collections.singletonList(match);
|
||||||
|
newRecon.matchRank = -1;
|
||||||
|
newRecon.judgment = Judgment.Matched;
|
||||||
|
newRecon.judgmentAction = "mass";
|
||||||
|
newRecon.judgmentBatchSize = 1;
|
||||||
|
|
||||||
|
Cell newCell = new Cell(
|
||||||
|
cell.value,
|
||||||
|
newRecon
|
||||||
|
);
|
||||||
|
|
||||||
|
CellChange cellChange = new CellChange(rowIndex, cellIndex, cell, newCell);
|
||||||
|
cellChanges.add(cellChange);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}.init(column.getCellIndex(), cellChanges, historyEntryID);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String createDescription(Column column, List<CellChange> cellChanges) {
|
||||||
|
return "Use values as reconciliation identifiers for "+ cellChanges.size() +
|
||||||
|
" cells in column " + column.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Change createChange(Project project, Column column, List<CellChange> cellChanges) {
|
||||||
|
return new ReconChange(
|
||||||
|
cellChanges,
|
||||||
|
_columnName,
|
||||||
|
reconConfig,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -38,6 +38,7 @@ import static org.mockito.Mockito.verify;
|
|||||||
|
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.testng.Assert;
|
import org.testng.Assert;
|
||||||
@ -514,6 +515,27 @@ public class TsvCsvImporterTests extends ImporterTest {
|
|||||||
Assert.assertEquals(project.rows.get(0).cells.get(2).value, "data3");
|
Assert.assertEquals(project.rows.get(0).cells.get(2).value, "data3");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(dataProvider = "CSV-TSV-AutoDetermine")
|
||||||
|
public void readCustomColumnNames(String sep){
|
||||||
|
//create input
|
||||||
|
String inputSeparator = sep == null ? "\t" : sep;
|
||||||
|
String input = "data1" + inputSeparator + "data2" + inputSeparator + "data3\n";
|
||||||
|
|
||||||
|
try {
|
||||||
|
prepareOptions(sep, -1, 0, 0, 1, false, false,"\"","[col1,col2,col3]");
|
||||||
|
parseOneFile(SUT, new StringReader(input));
|
||||||
|
} catch (Exception e) {
|
||||||
|
Assert.fail("Exception during file parse",e);
|
||||||
|
}
|
||||||
|
Assert.assertEquals(project.columnModel.columns.size(), 3);
|
||||||
|
Assert.assertEquals(project.columnModel.columns.get(0).getName(), "col1");
|
||||||
|
Assert.assertEquals(project.columnModel.columns.get(1).getName(), "col2");
|
||||||
|
Assert.assertEquals(project.columnModel.columns.get(2).getName(), "col3");
|
||||||
|
Assert.assertEquals(project.rows.get(0).cells.get(0).value, "data1");
|
||||||
|
Assert.assertEquals(project.rows.get(0).cells.get(1).value, "data2");
|
||||||
|
Assert.assertEquals(project.rows.get(0).cells.get(2).value, "data3");
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------read tests------------------------
|
//---------------------read tests------------------------
|
||||||
@Test
|
@Test
|
||||||
public void readCsvWithProperties() {
|
public void readCsvWithProperties() {
|
||||||
@ -580,17 +602,25 @@ public class TsvCsvImporterTests extends ImporterTest {
|
|||||||
String sep, int limit, int skip, int ignoreLines,
|
String sep, int limit, int skip, int ignoreLines,
|
||||||
int headerLines, boolean guessValueType, boolean ignoreQuotes, String quoteCharacter) {
|
int headerLines, boolean guessValueType, boolean ignoreQuotes, String quoteCharacter) {
|
||||||
|
|
||||||
whenGetStringOption("separator", options, sep);
|
prepareOptions(sep, limit, skip, ignoreLines, headerLines, guessValueType, ignoreQuotes, quoteCharacter,"[]");
|
||||||
whenGetStringOption("quoteCharacter", options, quoteCharacter);
|
|
||||||
whenGetIntegerOption("limit", options, limit);
|
|
||||||
whenGetIntegerOption("skipDataLines", options, skip);
|
|
||||||
whenGetIntegerOption("ignoreLines", options, ignoreLines);
|
|
||||||
whenGetIntegerOption("headerLines", options, headerLines);
|
|
||||||
whenGetBooleanOption("guessCellValueTypes", options, guessValueType);
|
|
||||||
whenGetBooleanOption("processQuotes", options, !ignoreQuotes);
|
|
||||||
whenGetBooleanOption("storeBlankCellsAsNulls", options, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void prepareOptions(
|
||||||
|
String sep, int limit, int skip, int ignoreLines,
|
||||||
|
int headerLines, boolean guessValueType, boolean ignoreQuotes, String quoteCharacter, String columnNames) {
|
||||||
|
|
||||||
|
whenGetStringOption("separator", options, sep);
|
||||||
|
whenGetStringOption("quoteCharacter", options, quoteCharacter);
|
||||||
|
whenGetIntegerOption("limit", options, limit);
|
||||||
|
whenGetIntegerOption("skipDataLines", options, skip);
|
||||||
|
whenGetIntegerOption("ignoreLines", options, ignoreLines);
|
||||||
|
whenGetIntegerOption("headerLines", options, headerLines);
|
||||||
|
whenGetBooleanOption("guessCellValueTypes", options, guessValueType);
|
||||||
|
whenGetBooleanOption("processQuotes", options, !ignoreQuotes);
|
||||||
|
whenGetBooleanOption("storeBlankCellsAsNulls", options, true);
|
||||||
|
whenGetArrayOption("columnNames", options, new JSONArray(columnNames));
|
||||||
|
}
|
||||||
|
|
||||||
private void verifyOptions() {
|
private void verifyOptions() {
|
||||||
try {
|
try {
|
||||||
verify(options, times(1)).getString("separator");
|
verify(options, times(1)).getString("separator");
|
||||||
@ -601,6 +631,7 @@ public class TsvCsvImporterTests extends ImporterTest {
|
|||||||
verify(options, times(1)).getBoolean("guessCellValueTypes");
|
verify(options, times(1)).getBoolean("guessCellValueTypes");
|
||||||
verify(options, times(1)).getBoolean("processQuotes");
|
verify(options, times(1)).getBoolean("processQuotes");
|
||||||
verify(options, times(1)).getBoolean("storeBlankCellsAsNulls");
|
verify(options, times(1)).getBoolean("storeBlankCellsAsNulls");
|
||||||
|
verify(options, times(1)).getJSONArray("columnNames");
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
Assert.fail("JSON exception",e);
|
Assert.fail("JSON exception",e);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
package com.google.refine.tests.operations.recon;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertNull;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.testng.annotations.BeforeSuite;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.refine.model.Project;
|
||||||
|
import com.google.refine.model.recon.StandardReconConfig;
|
||||||
|
import com.google.refine.operations.OperationRegistry;
|
||||||
|
import com.google.refine.operations.recon.ReconUseValuesAsIdentifiersOperation;
|
||||||
|
import com.google.refine.tests.RefineTest;
|
||||||
|
import com.google.refine.tests.util.TestUtils;
|
||||||
|
|
||||||
|
|
||||||
|
public class ReconUseValuesAsIdsOperation extends RefineTest {
|
||||||
|
String json = "{"
|
||||||
|
+ "\"op\":\"core/recon-use-values-as-identifiers\","
|
||||||
|
+ "\"description\":\"Use values as reconciliation identifiers in column ids\","
|
||||||
|
+ "\"columnName\":\"ids\","
|
||||||
|
+ "\"engineConfig\":{\"mode\":\"row-based\",\"facets\":[]},"
|
||||||
|
+ "\"service\":\"http://localhost:8080/api\","
|
||||||
|
+ "\"identifierSpace\":\"http://test.org/entities\","
|
||||||
|
+ "\"schemaSpace\":\"http://test.org/schema\""
|
||||||
|
+ "}";
|
||||||
|
|
||||||
|
@BeforeSuite
|
||||||
|
public void registerOperation() {
|
||||||
|
OperationRegistry.registerOperation(getCoreModule(), "recon-use-values-as-identifiers", ReconUseValuesAsIdentifiersOperation.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void serializeReconUseValuesAsIdentifiersOperation() throws JSONException, Exception {
|
||||||
|
TestUtils.isSerializedTo(ReconUseValuesAsIdentifiersOperation.reconstruct(new JSONObject(json)), json);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUseValuesAsIds() throws JSONException, Exception {
|
||||||
|
Project project = createCSVProject("ids,v\n"
|
||||||
|
+ "Q343,hello\n"
|
||||||
|
+ ",world\n"
|
||||||
|
+ "Q31,test");
|
||||||
|
ReconUseValuesAsIdentifiersOperation op = ReconUseValuesAsIdentifiersOperation.reconstruct(new JSONObject(json));
|
||||||
|
op.createProcess(project, new Properties()).performImmediate();
|
||||||
|
|
||||||
|
assertEquals("Q343", project.rows.get(0).cells.get(0).recon.match.id);
|
||||||
|
assertEquals("http://test.org/entities", project.rows.get(0).cells.get(0).recon.identifierSpace);
|
||||||
|
assertNull(project.rows.get(1).cells.get(0));
|
||||||
|
assertEquals("Q31", project.rows.get(2).cells.get(0).recon.match.id);
|
||||||
|
assertEquals(2, project.columnModel.columns.get(0).getReconStats().matchedTopics);
|
||||||
|
assertEquals("http://test.org/schema", ((StandardReconConfig)project.columnModel.columns.get(0).getReconConfig()).schemaSpace);
|
||||||
|
}
|
||||||
|
}
|
@ -127,6 +127,7 @@ function registerCommands() {
|
|||||||
RS.registerCommand(module, "recon-clear-one-cell", new Packages.com.google.refine.commands.recon.ReconClearOneCellCommand());
|
RS.registerCommand(module, "recon-clear-one-cell", new Packages.com.google.refine.commands.recon.ReconClearOneCellCommand());
|
||||||
RS.registerCommand(module, "recon-clear-similar-cells", new Packages.com.google.refine.commands.recon.ReconClearSimilarCellsCommand());
|
RS.registerCommand(module, "recon-clear-similar-cells", new Packages.com.google.refine.commands.recon.ReconClearSimilarCellsCommand());
|
||||||
RS.registerCommand(module, "recon-copy-across-columns", new Packages.com.google.refine.commands.recon.ReconCopyAcrossColumnsCommand());
|
RS.registerCommand(module, "recon-copy-across-columns", new Packages.com.google.refine.commands.recon.ReconCopyAcrossColumnsCommand());
|
||||||
|
RS.registerCommand(module, "recon-use-values-as-identifiers", new Packages.com.google.refine.commands.recon.ReconUseValuesAsIdentifiersCommand());
|
||||||
RS.registerCommand(module, "preview-extend-data", new Packages.com.google.refine.commands.recon.PreviewExtendDataCommand());
|
RS.registerCommand(module, "preview-extend-data", new Packages.com.google.refine.commands.recon.PreviewExtendDataCommand());
|
||||||
RS.registerCommand(module, "extend-data", new Packages.com.google.refine.commands.recon.ExtendDataCommand());
|
RS.registerCommand(module, "extend-data", new Packages.com.google.refine.commands.recon.ExtendDataCommand());
|
||||||
|
|
||||||
@ -190,6 +191,7 @@ function registerOperations() {
|
|||||||
OR.registerOperation(module, "recon-clear-similar-cells", Packages.com.google.refine.operations.recon.ReconClearSimilarCellsOperation);
|
OR.registerOperation(module, "recon-clear-similar-cells", Packages.com.google.refine.operations.recon.ReconClearSimilarCellsOperation);
|
||||||
OR.registerOperation(module, "recon-copy-across-columns", Packages.com.google.refine.operations.recon.ReconCopyAcrossColumnsOperation);
|
OR.registerOperation(module, "recon-copy-across-columns", Packages.com.google.refine.operations.recon.ReconCopyAcrossColumnsOperation);
|
||||||
OR.registerOperation(module, "extend-reconciled-data", Packages.com.google.refine.operations.recon.ExtendDataOperation);
|
OR.registerOperation(module, "extend-reconciled-data", Packages.com.google.refine.operations.recon.ExtendDataOperation);
|
||||||
|
OR.registerOperation(module, "recon-use-values-as-identifiers", Packages.com.google.refine.operations.recon.ReconUseValuesAsIdentifiersOperation);
|
||||||
}
|
}
|
||||||
|
|
||||||
function registerImporting() {
|
function registerImporting() {
|
||||||
@ -585,7 +587,7 @@ function process(path, request, response) {
|
|||||||
var urlConnection = url.openConnection();
|
var urlConnection = url.openConnection();
|
||||||
|
|
||||||
input = new Packages.java.io.BufferedReader(
|
input = new Packages.java.io.BufferedReader(
|
||||||
new Packages.java.io.InputStreamReader(urlConnection.getInputStream()));
|
new Packages.java.io.InputStreamReader(urlConnection.getInputStream(), "UTF8"));
|
||||||
|
|
||||||
output.write("/* ===== ");
|
output.write("/* ===== ");
|
||||||
output.write(qualifiedPath.fullPath);
|
output.write(qualifiedPath.fullPath);
|
||||||
|
@ -155,7 +155,9 @@
|
|||||||
"lines-beg": "Zeile(n) am Dateianfang",
|
"lines-beg": "Zeile(n) am Dateianfang",
|
||||||
"preserve-empty": "Leere Zeichenfolgen bewahren",
|
"preserve-empty": "Leere Zeichenfolgen bewahren",
|
||||||
"rows-data": "Datenzeile(n)",
|
"rows-data": "Datenzeile(n)",
|
||||||
"load-at-most": "Maximale Last"
|
"load-at-most": "Maximale Last",
|
||||||
|
"column-names-label": "Spaltennamen (durch Kommata getrennt)",
|
||||||
|
"column-names-optional": "Kommagetrennt"
|
||||||
},
|
},
|
||||||
"core-dialogs": {
|
"core-dialogs": {
|
||||||
"help": "Hilfe",
|
"help": "Hilfe",
|
||||||
|
@ -155,7 +155,9 @@
|
|||||||
"escape": "Escape special characters with \\",
|
"escape": "Escape special characters with \\",
|
||||||
"use-quote": "Use character",
|
"use-quote": "Use character",
|
||||||
"quote-delimits-cells": "to enclose cells containing column separators",
|
"quote-delimits-cells": "to enclose cells containing column separators",
|
||||||
"click-xml": "Click on the first XML element corresponding to the first record to load."
|
"click-xml": "Click on the first XML element corresponding to the first record to load.",
|
||||||
|
"column-names-label": "Column names (comma separated)",
|
||||||
|
"column-names-optional":"comma separated"
|
||||||
},
|
},
|
||||||
"core-dialogs": {
|
"core-dialogs": {
|
||||||
"cluster-edit": "Cluster & Edit column",
|
"cluster-edit": "Cluster & Edit column",
|
||||||
@ -685,6 +687,10 @@
|
|||||||
"replacement-info": "If \"regular expression\" option is checked and finding pattern contains groups delimited with parentheses, $0 will return the complete string matching the pattern, and $1, $2... the 1st, 2d... group.",
|
"replacement-info": "If \"regular expression\" option is checked and finding pattern contains groups delimited with parentheses, $0 will return the complete string matching the pattern, and $1, $2... the 1st, 2d... group.",
|
||||||
"replace-dont-escape": "use \\n for new lines, \\t for tabulation, \\\\n for \\n, \\\\t for \\t.",
|
"replace-dont-escape": "use \\n for new lines, \\t for tabulation, \\\\n for \\n, \\\\t for \\t.",
|
||||||
"warning-regex": "Invalid regular expression."
|
"warning-regex": "Invalid regular expression."
|
||||||
|
"use-values-as-identifiers": "Use values as identifiers",
|
||||||
|
"use-values-as-identifiers2": "Mark cells as reconciled with their values as identifiers",
|
||||||
|
"choose-reconciliation-service": "Choose a reconciliation service",
|
||||||
|
"choose-reconciliation-service-alert": "Please choose a reconciliation service first."
|
||||||
},
|
},
|
||||||
"core-buttons": {
|
"core-buttons": {
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
|
@ -406,7 +406,7 @@
|
|||||||
"all": "Tous les encodages",
|
"all": "Tous les encodages",
|
||||||
"years-ago": "années avant",
|
"years-ago": "années avant",
|
||||||
"week-ago": "semaine dernière",
|
"week-ago": "semaine dernière",
|
||||||
"working": "En fonctionnement",
|
"working": "Veuillez patienter",
|
||||||
"encoding": "Encodage",
|
"encoding": "Encodage",
|
||||||
"months-ago": "mois avant",
|
"months-ago": "mois avant",
|
||||||
"yesterday": "hier",
|
"yesterday": "hier",
|
||||||
@ -430,7 +430,7 @@
|
|||||||
"match-identical": "Apparier toutes les cellules identiques",
|
"match-identical": "Apparier toutes les cellules identiques",
|
||||||
"join-cells": "Joindre les cellules multivaluées",
|
"join-cells": "Joindre les cellules multivaluées",
|
||||||
"actions": "Actions",
|
"actions": "Actions",
|
||||||
"search-match": "Chercher les correspondances",
|
"search-match": "Chercher une correspondance",
|
||||||
"filtered-cell": "Apparier toutes les cellules filtrées avec...",
|
"filtered-cell": "Apparier toutes les cellules filtrées avec...",
|
||||||
"bounded-log-facet": "Facette logarithmique de limite 1",
|
"bounded-log-facet": "Facette logarithmique de limite 1",
|
||||||
"remove-col": "Supprimer cette colonne",
|
"remove-col": "Supprimer cette colonne",
|
||||||
|
@ -110,7 +110,7 @@
|
|||||||
"subject": "題名",
|
"subject": "題名",
|
||||||
"warning-proj-name": "プロジェクト名を指定してください。",
|
"warning-proj-name": "プロジェクト名を指定してください。",
|
||||||
"warning-rename": "プロジェクトのリネームに失敗しました:",
|
"warning-rename": "プロジェクトのリネームに失敗しました:",
|
||||||
"edit-tags-desc": "タグを編集(空白とコンマで分割):",
|
"edit-tags-desc": "タグを編集(空白とカンマで分割):",
|
||||||
"del-title": "プロジェクトを削除",
|
"del-title": "プロジェクトを削除",
|
||||||
"edit-tags": "プロジェクトタグを編集",
|
"edit-tags": "プロジェクトタグを編集",
|
||||||
"edit-meta-data": "文書情報",
|
"edit-meta-data": "文書情報",
|
||||||
@ -156,7 +156,9 @@
|
|||||||
"lines-beg": "行分(先頭から)",
|
"lines-beg": "行分(先頭から)",
|
||||||
"preserve-empty": "空文字を保存",
|
"preserve-empty": "空文字を保存",
|
||||||
"rows-data": "行分",
|
"rows-data": "行分",
|
||||||
"load-at-most": "最大読み込み行数"
|
"load-at-most": "最大読み込み行数",
|
||||||
|
"column-names-label": "カラム名(カンマ切り)",
|
||||||
|
"column-names-optional": "カンマ切り"
|
||||||
},
|
},
|
||||||
"core-dialogs": {
|
"core-dialogs": {
|
||||||
"help": "ヘルプ",
|
"help": "ヘルプ",
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<div class="grid-layout layout-loose layout-full"><table>
|
<div class="grid-layout layout-loose layout-full"><table>
|
||||||
<tr>
|
<tr>
|
||||||
<td><div class="grid-layout layout-tighter"><table>
|
<td><div class="grid-layout layout-tighter"><table>
|
||||||
<tr>
|
<tr>
|
||||||
@ -24,7 +24,7 @@
|
|||||||
<td><label for="$column-separator-custom" id="or-import-custom"></label>
|
<td><label for="$column-separator-custom" id="or-import-custom"></label>
|
||||||
<input bind="columnSeparatorInput" type="text" class="lightweight" size="5" /></td></tr>
|
<input bind="columnSeparatorInput" type="text" class="lightweight" size="5" /></td></tr>
|
||||||
<tr><td colspan="2" id="or-import-escape"></td></tr>
|
<tr><td colspan="2" id="or-import-escape"></td></tr>
|
||||||
</table></div></td>
|
</table></div></td>
|
||||||
|
|
||||||
<td colspan="2"><div class="grid-layout layout-tightest"><table>
|
<td colspan="2"><div class="grid-layout layout-tightest"><table>
|
||||||
<tr><td width="1%"><input type="checkbox" bind="ignoreCheckbox" id="$ignore" /></td>
|
<tr><td width="1%"><input type="checkbox" bind="ignoreCheckbox" id="$ignore" /></td>
|
||||||
@ -55,9 +55,14 @@
|
|||||||
</table></div></td>
|
</table></div></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td> </td>
|
<td><div class="grid-layout layout-tightest" style="width:fit-content;"><table>
|
||||||
|
<tr><td width="1%"><input type="checkbox" bind="columnNamesCheckbox" id="$check-column-names" />
|
||||||
|
<label id="or-import-columnNames"></label></td></tr>
|
||||||
|
<tr>
|
||||||
|
<td><input style="width: 25em;" bind="columnNamesInput" /></td>
|
||||||
|
</tr></table></div></td>
|
||||||
|
|
||||||
<td><div class="grid-layout layout-tightest"><table>
|
<td colspan="1"><div class="grid-layout layout-tightest"><table>
|
||||||
<tr><td width="1%"><input type="checkbox" bind="guessCellValueTypesCheckbox" id="$guess" /></td>
|
<tr><td width="1%"><input type="checkbox" bind="guessCellValueTypesCheckbox" id="$guess" /></td>
|
||||||
<td><label for="$guess" id="or-import-parseCell"></label></td></tr>
|
<td><label for="$guess" id="or-import-parseCell"></label></td></tr>
|
||||||
</table></div></td>
|
</table></div></td>
|
||||||
|
@ -118,6 +118,13 @@ Refine.SeparatorBasedParserUI.prototype.getOptions = function() {
|
|||||||
options.storeBlankCellsAsNulls = this._optionContainerElmts.storeBlankCellsAsNullsCheckbox[0].checked;
|
options.storeBlankCellsAsNulls = this._optionContainerElmts.storeBlankCellsAsNullsCheckbox[0].checked;
|
||||||
options.includeFileSources = this._optionContainerElmts.includeFileSourcesCheckbox[0].checked;
|
options.includeFileSources = this._optionContainerElmts.includeFileSourcesCheckbox[0].checked;
|
||||||
|
|
||||||
|
if (this._optionContainerElmts.columnNamesCheckbox[0].checked) {
|
||||||
|
var columnNames = this._optionContainerElmts.columnNamesInput.val();
|
||||||
|
if (columnNames != undefined && columnNames != null && columnNames != '') {
|
||||||
|
options.columnNames = columnNames.split(",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -136,6 +143,10 @@ Refine.SeparatorBasedParserUI.prototype._initialize = function() {
|
|||||||
$('#or-import-tabs').html($.i18n._('core-index-parser')["tabs"]);
|
$('#or-import-tabs').html($.i18n._('core-index-parser')["tabs"]);
|
||||||
$('#or-import-custom').html($.i18n._('core-index-parser')["custom"]);
|
$('#or-import-custom').html($.i18n._('core-index-parser')["custom"]);
|
||||||
$('#or-import-escape').html($.i18n._('core-index-parser')["escape"]);
|
$('#or-import-escape').html($.i18n._('core-index-parser')["escape"]);
|
||||||
|
$('#or-import-columnNames').html($.i18n._('core-index-parser')["column-names-label"] + ':');
|
||||||
|
$('#or-import-optional').html($.i18n._('core-index-parser')["column-names-optional"]);
|
||||||
|
|
||||||
|
self._optionContainerElmts.columnNamesInput.prop('disabled', true);
|
||||||
|
|
||||||
$('#or-import-ignore').text($.i18n._('core-index-parser')["ignore-first"]);
|
$('#or-import-ignore').text($.i18n._('core-index-parser')["ignore-first"]);
|
||||||
$('#or-import-lines').text($.i18n._('core-index-parser')["lines-beg"]);
|
$('#or-import-lines').text($.i18n._('core-index-parser')["lines-beg"]);
|
||||||
@ -160,6 +171,31 @@ Refine.SeparatorBasedParserUI.prototype._initialize = function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this._optionContainerElmts.headerLinesCheckbox.on("click", function() {
|
||||||
|
if ($(this).is(':checked')) {
|
||||||
|
var isDisabled = $('textbox').prop('disabled');
|
||||||
|
if (!isDisabled) {
|
||||||
|
self._optionContainerElmts.columnNamesInput.prop('disabled', true);
|
||||||
|
self._optionContainerElmts.columnNamesCheckbox.prop("checked", false);
|
||||||
|
self._optionContainerElmts.columnNamesInput.val('');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self._optionContainerElmts.columnNamesInput.prop('disabled', false);
|
||||||
|
self._optionContainerElmts.columnNamesCheckbox.prop("checked", true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this._optionContainerElmts.columnNamesCheckbox.on("click", function() {
|
||||||
|
if ($(this).is(':checked')) {
|
||||||
|
self._optionContainerElmts.headerLinesCheckbox.prop("checked", false);
|
||||||
|
self._optionContainerElmts.columnNamesInput.prop('disabled', false);
|
||||||
|
} else {
|
||||||
|
self._optionContainerElmts.headerLinesCheckbox.prop("checked", true);
|
||||||
|
self._optionContainerElmts.columnNamesInput.val('');
|
||||||
|
self._optionContainerElmts.columnNamesInput.prop('disabled', true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
var columnSeparatorValue = (this._config.separator == ",") ? 'comma' :
|
var columnSeparatorValue = (this._config.separator == ",") ? 'comma' :
|
||||||
((this._config.separator == "\\t") ? 'tab' : 'custom');
|
((this._config.separator == "\\t") ? 'tab' : 'custom');
|
||||||
this._optionContainer.find(
|
this._optionContainer.find(
|
||||||
@ -206,6 +242,7 @@ Refine.SeparatorBasedParserUI.prototype._initialize = function() {
|
|||||||
};
|
};
|
||||||
this._optionContainer.find("input").bind("change", onChange);
|
this._optionContainer.find("input").bind("change", onChange);
|
||||||
this._optionContainer.find("select").bind("change", onChange);
|
this._optionContainer.find("select").bind("change", onChange);
|
||||||
|
this._optionContainerElmts.columnNamesInput.bind("keyup",onChange);
|
||||||
};
|
};
|
||||||
|
|
||||||
Refine.SeparatorBasedParserUI.prototype._scheduleUpdatePreview = function() {
|
Refine.SeparatorBasedParserUI.prototype._scheduleUpdatePreview = function() {
|
||||||
|
@ -126,6 +126,60 @@ DataTableColumnHeaderUI.extendMenu(function(column, columnHeaderUI, menu) {
|
|||||||
input.focus().data("suggest").textchange();
|
input.focus().data("suggest").textchange();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var doUseValuesAsIdentifiers = function() {
|
||||||
|
var frame = DialogSystem.createDialog();
|
||||||
|
frame.width("400px");
|
||||||
|
|
||||||
|
var header = $('<div></div>').addClass("dialog-header").text($.i18n._('core-views')["use-values-as-identifiers"]).appendTo(frame);
|
||||||
|
var body = $('<div></div>').addClass("dialog-body").appendTo(frame);
|
||||||
|
var footer = $('<div></div>').addClass("dialog-footer").appendTo(frame);
|
||||||
|
|
||||||
|
$('<p></p>').text($.i18n._('core-views')["choose-reconciliation-service"]).appendTo(body);
|
||||||
|
var select = $('<select></select>').appendTo(body);
|
||||||
|
var services = ReconciliationManager.getAllServices();
|
||||||
|
for (var i = 0; i < services.length; i++) {
|
||||||
|
var service = services[i];
|
||||||
|
$('<option></option>').attr('value', service.url)
|
||||||
|
.text(service.name)
|
||||||
|
.appendTo(select);
|
||||||
|
}
|
||||||
|
|
||||||
|
$('<button class="button"></button>').text($.i18n._('core-buttons')["cancel"]).click(function() {
|
||||||
|
DialogSystem.dismissUntil(level - 1);
|
||||||
|
}).appendTo(footer);
|
||||||
|
$('<button class="button"></button>').html($.i18n._('core-buttons')["ok"]).click(function() {
|
||||||
|
|
||||||
|
var service = select.val();
|
||||||
|
var identifierSpace = null;
|
||||||
|
var schemaSpace = null;
|
||||||
|
for(var i = 0; i < services.length; i++) {
|
||||||
|
if(services[i].url === service) {
|
||||||
|
identifierSpace = services[i].identifierSpace;
|
||||||
|
schemaSpace = services[i].schemaSpace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (identifierSpace === null) {
|
||||||
|
alert($.i18n._('core-views')["choose-reconciliation-service-alert"]);
|
||||||
|
} else {
|
||||||
|
Refine.postCoreProcess(
|
||||||
|
"recon-use-values-as-identifiers",
|
||||||
|
{
|
||||||
|
columnName: column.name,
|
||||||
|
service: service,
|
||||||
|
identifierSpace: identifierSpace,
|
||||||
|
schemaSpace: schemaSpace
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
{ cellsChanged: true, columnStatsChanged: true }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
DialogSystem.dismissUntil(level - 1);
|
||||||
|
}).appendTo(footer);
|
||||||
|
|
||||||
|
var level = DialogSystem.showDialog(frame);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
var doCopyAcrossColumns = function() {
|
var doCopyAcrossColumns = function() {
|
||||||
var frame = $(DOM.loadHTML("core", "scripts/views/data-table/copy-recon-across-columns-dialog.html"));
|
var frame = $(DOM.loadHTML("core", "scripts/views/data-table/copy-recon-across-columns-dialog.html"));
|
||||||
var elmts = DOM.bind(frame);
|
var elmts = DOM.bind(frame);
|
||||||
@ -402,6 +456,12 @@ DataTableColumnHeaderUI.extendMenu(function(column, columnHeaderUI, menu) {
|
|||||||
label: $.i18n._('core-views')["copy-recon"],
|
label: $.i18n._('core-views')["copy-recon"],
|
||||||
tooltip: $.i18n._('core-views')["copy-recon2"],
|
tooltip: $.i18n._('core-views')["copy-recon2"],
|
||||||
click: doCopyAcrossColumns
|
click: doCopyAcrossColumns
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "core/use-values-as-identifiers",
|
||||||
|
label: $.i18n._('core-views')["use-values-as-identifiers"],
|
||||||
|
tooltip: $.i18n._('core-views')['use-values-as-identifiers2'],
|
||||||
|
click: doUseValuesAsIdentifiers
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user