Problems with draggable and dropDestination using DataRepresentation in Transferable - drag

I can't get my drag and drop with DataRepresentation to work with Transferable. I'm trying to drag and drop instances of DataSettings which is an NSManagedObject that conforms to NSSecureCoding.
Here's my UTType:
extension UTType {
static var encoderSettings = UTType(exportedAs: "com.simulator.EncoderSettings")
}
Here's my conformance to Transferable:
extension DataSettings: Transferable {
var data: Data? {
try? NSKeyedArchiver.archivedData(withRootObject: self, requiringSecureCoding: true)
}
public static var transferRepresentation: some TransferRepresentation {
/*DataRepresentation(contentType: .commaSeparatedText) { setting in
let data = setting.data
print("DataRepresentation: \(data)")
return data!
} importing: { data in
print("data: \(data)")
return DataSettings()
}*/
DataRepresentation(contentType: .encoderSettings) { setting in
let data = setting.data
print("DataRepresentation: \(data)")
return data!
} importing: { data in
print("data: \(data)")
return DataSettings()
}
// ProxyRepresentation(exporting: \.title)
}
}
Here's a view where I'm testing my drop destination:
struct DropTest: View {
#State var isDropTargeted = false
var body: some View {
Color.pink
.frame(width: 200, height: 200)
.dropDestination(for: EncoderSettings.self) { setting, location in
print("\(setting)")
return true
} isTargeted: {
isDropTargeted = $0
print("Got it!!!")
}
}
}
Here's my Info plist:
The ProxyRepresentation (String) works but I need the actual Data.
The dragging starts (i.e.: I can drag the view that has the .draggable with DataSettings) but I can't drop it on my DropTest view. I can drop it on a view or app that accepts the ProxyRepresentation.
What am I missing?

Related

How to change variable when I slide on TabView in swift

I've following code for my TabView:
struct CardList: View {
var body: some View {
TabView {
ForEach (0..<100 ){ item in
CardViewNew()
}
}
.tabViewStyle(PageTabViewStyle())
.padding(.vertical, 10)
}
}
Every time when I slide to the next view of my TabView the following variable "i" should increased by 1 to show the next element of my array "shuffled_questions".
struct CardViewNew: View {
var body: some View {
Text(shuffled_questions[i])
}
}
Would be nice I've someone can help me :)
Seems like there's two ways to accomplish this. To answer your original question, you could use the selection binding of TabView to get a variable to change when the TabView moves:
#State private var tabSelection = 0
var body: some View {
TabView(selection: $tabSelection) {
ForEach (0..<100 ){ item in
Text("hi")
}
}
.tabViewStyle(PageTabViewStyle())
.padding(.vertical, 10)
Text("\(tabSelection)")
}
However, it seems like in your case it seems like you may just want to pass the index from your ForEach as a parameter to your CardViewNew:
struct ContentView : View {
var body: some View {
TabView {
ForEach (0..<100 ){ item in
CardViewNew(index: item)
}
}
.tabViewStyle(PageTabViewStyle())
.padding(.vertical, 10)
}
}
struct CardViewNew: View {
var index: Int
var body: some View {
Text(shuffled_questions[index])
}
}

Validation on export data for one2many field column in Odoo 13

I want to show validation error when the user export records for state='draft'(in one2many field). I have done code for it and it's working fine. but when I put this code for one2many table then I unable to get a validation message.
My code is below:
class DailyTransaction(models.Model):
_name = 'daily.transaction'
_rec_name = 'batch_id'
date = fields.Date()
batch_id = fields.Char()
daily_transaction = fields.One2many('transaction.log', 'daily_trans_log', string='Daily Transaction')
class Transaction_log(models.Model):
_name = 'transaction.log'
_rec_name = 'daily_trans_log'
daily_trans_log = fields.Many2one('daily.transaction')
log_status = fields.Selection([('Draft', 'Draft'), ('Approved', 'Approved'), ('Confirmed', 'Confirmed')],
default='Draft', string='Log Status')
odoo.define("transaction_log.export_log", function(require) {
"use strict";
var listController = require("web.ListController");
var dialog = require("web.Dialog");
listController.include({
/**
* Opens the Export Dialog
*
* #private
*/
_onExportData: function () {
var self = this;
var do_export = true;
// Avoid calling `read` when `state` field is not available
if (self.initialState.fields.hasOwnProperty('log_status')) {
self._rpc({
model: self.modelName,
method: 'read',
args: [self.getSelectedIds(), ['log_status']],
}).then(function (result) {
// Check if we have at least one draft record
for(var index in result) {
var item = result[index];
if (item.log_status === 'Draft') {
do_export = false;
break;
}
}
if (do_export) {
self._getExportDialogWidget().open();
} else {
dialog.alert(self, "You can't export draft stage data!", {});
}
});
} else {
this._getExportDialogWidget().open();
}
},
});
});
when I export record from 'transaction.log' for 'Draft' log_status then it's work and shows validation message. But I also want to show this validation when export from 'daily.transaction'
Thanks in advance.
You need to add a second condition and read records from the related model to check if there is some record in Draft state.
else if (self.initialState.fields.hasOwnProperty('daily_transaction')){
self._rpc({
model: 'transaction.log',
method: 'search_read',
args: [[['daily_trans_log', 'in', self.getSelectedIds()]], ['log_status']],
}).then(function (result) {
// Check if we have at least one draft record
for(var index in result) {
var item = result[index];
if (item.log_status === 'Draft') {
do_export = false;
break;
}
}
if (do_export) {
self._getExportDialogWidget().open();
} else {
dialog.alert(self, "You can't export draft stage data!", {});
}
});
}
The code after then is the same, I just made a quick example.

How to customize the SwiftUI ViewBuilder

There are some posts about SwiftUI Builder like this. So that I can embed my content like:
struct Container<Content>: View where Content: View {
var content: Content
init(#ViewBuilder content: #escaping () -> Content) {
self.content = content()
}
var body: some View {
return content
}
}
struct ContentView: View {
var body: some View {
Container() {
Text("Content 1").tag(0)
Text("Content 2").tag(1)
}
}
}
I'm wondering if I don't pass the ViewBuilder in init. Instead I'd like to do something like:
struct ContentView: View {
var body: some View {
Container().buildContent {
Text("Content 1").tag(0)
Text("Content 2").tag(1)
}
}
}
The reason why I want to do this is because I want to mimic the TabView's tabItem.
You can't have the buildContent function mutate the Container, but you can default to having a Container that just vends an EmptyView, and the use that as a springboard for creating a new Container with your desired content.
You could achieve that sort of API like this:
struct Container<Content>: View where Content: View {
var content: Content
init(#ViewBuilder content: () -> Content) {
self.content = content()
}
var body: some View {
return content
}
}
extension Container where Content == EmptyView {
init() {
self.content = EmptyView()
}
/// Return a new `Container` with the given `Content` builder.
func buildContent<V : View>(#ViewBuilder content: () -> V) -> Container<V> {
Container<V>(content: content)
}
}
struct ContentView: View {
var body: some View {
Container().buildContent {
Text("Content 1").tag(0)
Text("Content 2").tag(1)
}
}
}

Nodejs async data duplication

I'm having some problems with one async process on nodejs.
I'm getting some data from a remote JSON and adding it in my array, this JSON have some duplicated values, and I need check if it already exists on my array before add it to avoid data duplication.
My problem is when I start the loop between the JSON values, the loop call the next value before the latest one be process be finished, so, my array is filled with duplicated data instead of maintain only one item per type.
Look my current code:
BookRegistration.prototype.process_new_books_list = function(data, callback) {
var i = 0,
self = this;
_.each(data, function(book) {
i++;
console.log('\n\n ------------------------------------------------------------ \n\n');
console.log('BOOK: ' + book.volumeInfo.title);
self.process_author(book, function() { console.log('in author'); });
console.log('\n\n ------------------------------------------------------------');
if(i == data.length) callback();
})
}
BookRegistration.prototype.process_author = function(book, callback) {
if(book.volumeInfo.authors) {
var author = { name: book.volumeInfo.authors[0].toLowerCase() };
if(!this.in_array(this.authors, author)) {
this.authors.push(author);
callback();
}
}
}
BookRegistration.prototype.in_array = function(list, obj) {
for(i in list) { if(list[i] === obj) return true; }
return false;
}
The result is:
[{name: author1 }, {name: author2}, {name: author1}]
And I need:
[{name: author1 }, {name: author2}]
UPDATED:
The solution suggested by #Zub works fine with arrays, but not with sequelize and mysql database.
When I try to save my authors list on the database, the data is duplicated, because the system started to save another array element before finish to save the last one.
What is the correct pattern on this case?
My code using database is:
BookRegistration.prototype.process_author = function(book, callback) {
if(book.volumeInfo.authors) {
var author = { name: book.volumeInfo.authors[0].toLowerCase() };
var self = this;
models.Author.count({ where: { name: book.volumeInfo.authors[0].toLowerCase() }}).success(function(count) {
if(count < 1) {
models.Author.create(author).success(function(author) {
console.log('SALVANDO AUTHOR');
self.process_publisher({ book:book, author:author }, callback);
});
} else {
models.Author.find({where: { name: book.volumeInfo.authors[0].toLowerCase() }}).success(function(author) {
console.log('FIND AUTHOR');
self.process_publisher({ book:book, author:author }, callback);
});
}
});
// if(!this.in_array(this.authors, 'name', author)) {
// this.authors.push(author);
// console.log('AQUI NO AUTHOR');
// this.process_publisher(book, callback);
// }
}
}
How can I avoid data duplication in an async process?
This is because you are comparing different objects and result is always false.
Just for experiment type in the console:
var obj1 = {a:1};
var obj2 = {a:1};
obj1 == obj2; //false
When comparing objects (as well as arrays) it only results true when obj1 links to obj2:
var obj1 = {a:1};
var obj2 = obj1;
obj1 == obj2; //true
Since you create new author objects in each process_author call you always get false when comparing.
In your case the solution would be to compare name property for each book:
BookRegistration.prototype.in_array = function(list, obj) {
for(i in list) { if(list[i].name === obj.name) return true; }
return false;
}
EDIT (related to your comment question):
I would rewrite process_new_books_list method as follows:
BookRegistration.prototype.process_new_books_list = function(data, callback) {
var i = 0,
self = this;
(function nextBook() {
var book = data[i];
if (!book) {
callback();
return;
}
self.process_author(book, function() {
i++;
nextBook();
});
})();
}
In this case next process_author is being called not immediately (like with _.each), but after callback is executed, so you have consequence in your program.
Not sure is this works though.
Sorry for my English, I'm not a native English speaker

ok button in record Form plugin in extjs

how to get the updated records,i am overriding the on Ok function to save changes in form.
1.i just override the on ok function,but not able to get modified record.
Ext.override(Ext.ux.grid.RecordForm , {
onOK:function() {
updateRecord1();
}
});
function updateRecord1() {//alert('record');
var records =store.getModifiedRecords();
if(!records.length) {
return;
}
var data = [];
Ext.each(records, function(r, i) {
var o = r.getChanges();
if(r.data.newRecord) {
o.newRecord = true;
}
o[idName] = r.get(idName);
data.push(o);
});
var o = {
url:gl_acc.php
,method:'post'
,params:{
record:record.get('id'),
task:'update'
}
};
Ext.Ajax.request(o);
} // eo function commitChanges
var records = this.store.getModifiedRecords();

Resources