Google Script App Delete Duplicate Rows with a Specific Value in Specific Column in Google Sheet - if-statement

I have a google sheet where people submit tasks they are working on and they'll submit a status update which is either 'in progress' or 'complete' for let's say task A. Task A is in column D[4] and Status is in column E[5]. I'm trying to get this code to only delete the 'in progress' row for Task A when there is duplicate Task A with the status being 'Complete'. This works for identifying the duplicate and removes the duplicate rows in order, but I'm not sure how to get it to only delete duplicate 'Task A' 'In Progress' rows when there is a 'Task A' 'Complete' row. Any help would be much appreciated!
function removeDuplicates() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet2");
var data = sheet.getDataRange().getValues();
var newData = [];
for (i in data) {
var row = data[i];
var duplicate = false;
for (j in newData) {
if(row[3] == newData[j][3]){
duplicate = true;
}
}
if (!duplicate) {
newData.push(row);
}
}
sheet.clearContents();
sheet.getRange(1, 1, newData.length, newData[0].length).setValues(newData);
}

I would try
function removeDuplicates()
{
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("test");
var dataRange = sheet.getDataRange();
var data = dataRange.getValues();
var indexOfStatusColumn = 4;
var newData = [];
data.forEach(function (row, rowI){
var isDuplicate = false
if (newData.length)
newData.forEach(function (dup, dupI)
{
if (dup[3] == row[3])
{
if (row[indexOfStatusColumn] == "Complete" && dup[indexOfStatusColumn] != "Complete")
newData[dupI][indexOfStatusColumn] = "Complete";
isDuplicate = true;
return (false);
}
})
if (!isDuplicate)
newData.push(row);
});
dataRange = sheet.getRange(2, 1, dataRange.getLastRow() - 1, dataRange.getLastColumn());
dataRange.clearContent();
sheet.getRange(1, 1, newData.length, newData[0].length).setValues(newData);
}
few things
I use forEach()loop it's more efficient
break loop by returning falseto avoid parsing trough all your newDatauselessly
when I find a duplicate I perform some of this actions
Check if duplicate is Complete on data and not on newData if so
change the value in newDatato "Complete" this way it will keep the complete status (be careful if there's different datas on both rows it will probably twist datas).
also use clearContent() from a range to avoid removing all the content of the sheet but only a specific portion of it. Here I've rebuilded it to keep the header
REFERENCES
forEach()
Tanaike benchmark
clearContent()

Related

How to search for a particular text from list of names using if else condition in protractor?

var totalList_grps = element.all(by.css('p.group-name-text'));
totalList_grps.getText().then(function(text){
console.log('Total list of joined groups : ' + text);
});
Tried the above code for printing list of group names.
Got Output :Total list of joined groups : Party,Innovation,capsLock,Gym,Sunrisers
AW,Big Boss.
Now i need to search for a particular name using if else condition and i tried the second set of code, but its not displaying any output not even a error.
totalList_grps.getText().then(function(itemList) {
expect(itemList).toContain('Big Boss');
});
Here is developers code
1) use by.cssContainingText():
var bigBoss = element(by.cssContainingText('p.group-name-text', 'Big Boss'));
// then you can call click(), getText(), getAttribute('') on found element as following:
bigBoss.click();
2) use elements.filter():
var bigBoss = element.all(by.css('p.group-name-text'))
.filter(function(it){
return it.getText().then(function(txt){
console.log('txt: ' + txt);
return txt === 'Big Boss' || txt.includes('Big Boss');
});
})
.first();
3) use await with combination of if/else
var allNames = element.all(by.css('p.group-name-text'));
var length = await allNames.count();
var matchedIndex = -1;
for(var i=0;i<length;i++) {
var name = await allNames.get(i).getText();
if (name === 'Big Boss' || name.includes('Big Boss')) {
matchedIndex = i;
console.log('matchedIndex = ' + matchedIndex);
break;
}
}
var bigBoss = allNames.get(matchedIndex);
We can implement option 3 without using await, but the code will be not easy readable and more complex than current.
FYI, If you want to use await/async, you need to disable protractor promise management (know as control flow). You can't use both in your code at same time.

How to add dynamic values to field injections list with custom trigger to camunda properties panel?

I have two questions here
Is it possible to add dynamic lists values to field injection list input ?
Can I create a trigger for this so this can be initiated from any other input selection say a class selection will populate all fields
I was just looking into FieldInjection.js whether that can be extented for the same
Can someone please provide a hint or direction for this ?
Thanks.
For anyone interested in the answer, I was able to achieve the above goal by changing the set function of the Java Class select input as folllowing
few imports
var extensionElementsHelper = require('../../../../helper/ExtensionElementsHelper'),
elementHelper = require('../../../../helper/ElementHelper')
var CAMUNDA_FIELD_EXTENSION_ELEMENT = 'camunda:Field';
function getExtensionFields(bo) {
return bo && extensionElementsHelper.getExtensionElements(bo, CAMUNDA_FIELD_EXTENSION_ELEMENT) || [];
}
then changing the set function to create extension element and push the field values as :
set: function(element, values, node) {
var bo = getBusinessObject(element);
var type = getImplementationType(element);
var attr = getAttribute(type);
var prop = {}
var commands = [];
prop[attr] = values.delegate || '';
var extensionElements = getExtensionFields(bo);
//remove any extension elements existing before
extensionElements.forEach(function(ele){
commands.push(extensionElementsHelper.removeEntry(getBusinessObject(element), element, ele));
});
if(prop[attr] !== ""){
var extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory);
commands.push(cmdHelper.updateBusinessObject(element, bo, { extensionElements: extensionElements }));
var arrProperties = ["private org.camunda.bpm.engine.delegate.Expression com.cfe.extensions.SampleJavaDelegate.varOne","private org.camunda.bpm.engine.delegate.Expression com.cfe.extensions.SampleJavaDelegate.varTwo"]
var newFieldElem = "";
arrProperties.forEach(function(prop){
var eachProp = {
name:"",
string:"",
expression:""
}
var type = prop.split(" ")[1].split(".").reverse()[0];
var val = prop.split(" ")[2].split(".").reverse()[0];
eachProp.name = val;
if( type == "String"){
eachProp.string = "${" + val +" }"
}else if( type == "Expression"){
eachProp.expression = "${" + val +" }"
}
newFieldElem = elementHelper.createElement(CAMUNDA_FIELD_EXTENSION_ELEMENT, eachProp, extensionElements, bpmnFactory);
commands.push(cmdHelper.addElementsTolist(element, extensionElements, 'values', [ newFieldElem ]));
});
}
commands.push(cmdHelper.updateBusinessObject(element, bo, prop));
return commands;
}
Cheers !.

Ember.computed.sort property not updating

I've been cracking my head for the last several days, trying to understand what am I doing wrong.
I'm implementing an infrastructure of lists for my app, which can include paging/infinite scroll/filtering/grouping/etc. The implementation is based on extending controllers (not array controllers, I want to be Ember 2.0 safe), with a content array property that holds the data.
I'm using Ember.computed.sort for the sorting, and it's working, but i have a strange behavior when i try to change the sorter. the sortedContent is not updating within the displayContent, even though the sortingDefinitions definitions are updated.
This causes a weird behaviour that it will only sort if I sort it twice, as if the sorting was asynchronous.
I am using Ember 1.5 (but it also happens on 1.8)
(attaching a snippet of code explaining my problem)
sortingDefinitions: function(){
var sortBy = this.get('sortBy');
var sortOrder = this.get('sortOrder') || 'asc';
if (_.isArray(sortBy)) {
return sortBy;
}
else {
return (sortBy ? [sortBy + ':' + sortOrder] : []);
}
}.property('sortBy', 'sortOrder'),
sortedContent: Ember.computed.sort('content', 'sortingDefinitions'),
displayContent: function() {
var that = this;
var sortBy = this.get('sortBy');
var sortOrder = this.get('sortOrder');
var list = (sortBy ? this.get('sortedContent') : this.get('content'));
var itemsPerPage = this.get('itemsPerPage');
var currentPage = this.get('currentPage');
var listItemModel = this.get('listItemModel');
return list.filter(function(item, index, enumerable){
return ((index >= (currentPage * itemsPerPage)) && (index < ((currentPage + 1) * itemsPerPage)));
}).map(function(item) {
var listItemModel = that.get('listItemModel');
if (listItemModel) {
return listItemModel.create(item);
}
else {
return item;
}
});
}.property('content.length', 'sortBy', 'sortOrder', 'currentPage', 'itemsPerPage')
Edit:
fixed by adding another dependency to the displayContent (sortedContent.[]):
displayContent: function() {
....
}.property('content.length', 'sortBy', 'sortOrder', 'currentPage', 'itemsPerPage' , 'sortedContent.[]')
Your sort function is watching the whole array sortingDefinitions instead of each element in the array. If the array changed to a string or some other variable it would update but not if an element in the array changes.
To ensure your computed property updates correctly, add a .[] to the end of the array so it looks like this: Ember.computed.sort('content', 'sortingDefinitions.[]')

How to hide/disable specific cell in SharePoint 2013 quick edit using CSR?

I'm using Sharepoint 2013 CSR to disable columns in quick edit. I want to disable complete row or cell based on column value.
For example. If I have two requests whose status are pending there is one column
request status which is a choice-(pending/Approve) type where user can change that pending column to approve. Once it is approved the request status column should be disabled or entire row should be disabled. Can it be possible ?
I'm using below script but it disables complete column.
<script type="text/javascript">
var updateViewerFields=["Request Status","Request Id"];
(function updateView() {
var overrideContext = {};
overrideContext.Templates = overrideContext.Templates || {};
overrideContext.Templates.OnPreRender = function(ctx) {
for(j=0; j<ctx.ListSchema.Field.length; j++)
{
var f = ctx.ListSchema.Field[j];
for(i=0;i<updateViewerFields.length;i++){
if(f.DisplayName == updateViewerFields[i]){
f.AllowGridEditing=false;
}
}
}
}
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext);
})();
</script>
I'm trying below script but no luck
overrideContext.Templates.OnPostRender = function(ctx) {
var rows = ctx.ListData.Row;
//console.log(rows);
for (var i=0;i<rows.length;i++)
{
var isApproved = rows[i]["Request_x0020_Status"] == "Approved";
if (isApproved)
{
//alert("Please confirm");
var rowElementId = GenerateIIDForListItem(ctx, rows[i]);
var tr = document.getElementById(rowElementId);
//tr.style.backgroundColor = "#ada";
console.log(tr);
}
}

Ember js, get next item in model?

Is there any way to get the next item in model in ember.js?
something like:
var nextObjectAfterIdOne = this.store.getById(App.Model, '1').get('nextObject')
I came across this answer but it seems a bit hacky, and the IDs in my application aren't necessarily sequential, and the items are ordered by a different attribute.
Any ideas?
I'm not sure it's the good way to do it but at least it should work. Try to iterate over your list of item and once you find the current id, the next iteration will give you the next item.
var list = this.store.all(App.Model);
var id = 2;
var found = false;
var itemFound = undefined;
list.forEach(function(item, i) {
if (found) {
itemFound = item;
return true;
}
if (item.get('id') == id) found = true;
});
This has not been tested but you can try it.