[form] Added new controls Attach and Attach Image and cleaned up field_groups - now using full form layout
This commit is contained in:
parent
f4e1740366
commit
d2a1ba6cd0
11 changed files with 182 additions and 111 deletions
|
|
@ -64,6 +64,7 @@
|
|||
"lib/public/js/legacy/loaders.js",
|
||||
|
||||
"lib/public/js/wn/ui/appframe.js",
|
||||
"lib/public/js/wn/form/layout.js",
|
||||
"lib/public/js/wn/ui/field_group.js",
|
||||
"lib/public/js/wn/ui/dialog.js",
|
||||
"lib/public/js/wn/ui/button.js",
|
||||
|
|
@ -120,7 +121,6 @@
|
|||
|
||||
"lib/public/js/wn/form/toolbar.js",
|
||||
"lib/public/js/wn/form/infobar.js",
|
||||
"lib/public/js/wn/form/layout.js",
|
||||
"lib/public/js/wn/form/dashboard.js",
|
||||
"lib/public/js/wn/form/script_manager.js",
|
||||
"lib/public/js/wn/form/control.js",
|
||||
|
|
|
|||
|
|
@ -183,6 +183,10 @@ _f.Frm.prototype.setup_std_layout = function() {
|
|||
doctype: this.doctype,
|
||||
frm: this,
|
||||
});
|
||||
this.layout.make();
|
||||
|
||||
this.fields_dict = this.layout.fields_dict;
|
||||
this.fields = this.layout.fields_list;
|
||||
|
||||
this.dashboard = new wn.ui.form.Dashboard({
|
||||
frm: this,
|
||||
|
|
@ -467,6 +471,7 @@ _f.Frm.prototype.refresh_field = function(fname) {
|
|||
|
||||
_f.Frm.prototype.refresh_fields = function() {
|
||||
this.layout.refresh();
|
||||
this.layout.primary_button = $(this.wrapper).find(".btn-primary");
|
||||
|
||||
// cleanup activities after refresh
|
||||
this.cleanup_refresh(this);
|
||||
|
|
|
|||
|
|
@ -111,14 +111,11 @@ wn.ui.form.Attachments = Class.extend({
|
|||
if(!this.dialog) {
|
||||
this.dialog = new wn.ui.Dialog({
|
||||
title: wn._('Upload Attachment'),
|
||||
width: 400
|
||||
});
|
||||
$y(this.dialog.body, {margin:'13px'});
|
||||
this.dialog.make();
|
||||
}
|
||||
this.dialog.body.innerHTML = '';
|
||||
this.dialog.show();
|
||||
|
||||
$(this.dialog.body).empty();
|
||||
wn.upload.make({
|
||||
parent: this.dialog.body,
|
||||
args: {
|
||||
|
|
@ -127,8 +124,8 @@ wn.ui.form.Attachments = Class.extend({
|
|||
docname: this.frm.docname,
|
||||
},
|
||||
callback: function(fileid, filename, r) {
|
||||
me.dialog.hide();
|
||||
me.update_attachment(fileid, filename, fieldname, r);
|
||||
me.frm.toolbar.show_infobar();
|
||||
},
|
||||
onerror: function() {
|
||||
me.dialog.hide();
|
||||
|
|
@ -138,13 +135,13 @@ wn.ui.form.Attachments = Class.extend({
|
|||
});
|
||||
},
|
||||
update_attachment: function(fileid, filename, fieldname, r) {
|
||||
this.dialog && this.dialog.hide();
|
||||
if(fileid) {
|
||||
this.add_to_attachments(fileid, filename);
|
||||
this.refresh();
|
||||
if(fieldname) {
|
||||
this.frm.set_value(fieldname, wn.utils.get_file_link(filename));
|
||||
this.frm.cscript[fieldname] && this.frm.cscript[fieldname](this.frm.doc);
|
||||
this.frm.toolbar.show_infobar();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ wn.ui.form.ControlInput = wn.ui.form.Control.extend({
|
|||
<label class="control-label"></label>\
|
||||
<div class="control-input"></div>\
|
||||
<div class="control-value like-disabled-input" style="display: none;"></div>\
|
||||
<p class="help-box small text-muted"> </p>\
|
||||
<p class="help-box small text-muted"></p>\
|
||||
</div>').appendTo(this.parent);
|
||||
}
|
||||
},
|
||||
|
|
@ -231,7 +231,7 @@ wn.ui.form.ControlInput = wn.ui.form.Control.extend({
|
|||
this._description = this.df.description;
|
||||
},
|
||||
set_empty_description: function() {
|
||||
this.$wrapper.find(".help-box").html(" ");
|
||||
this.$wrapper.find(".help-box").html("");
|
||||
},
|
||||
set_mandatory: function(value) {
|
||||
this.$wrapper.toggleClass("has-error", (this.df.reqd
|
||||
|
|
@ -470,22 +470,24 @@ wn.ui.form.ControlButton = wn.ui.form.ControlData.extend({
|
|||
var me = this;
|
||||
this.$input = $('<button class="btn btn-default">')
|
||||
.prependTo(me.input_area)
|
||||
.css({"margin-bottom": "7px"})
|
||||
.on("click", function() {
|
||||
if(me.frm && me.frm.doc && me.frm.cscript) {
|
||||
if(me.frm.cscript[me.df.fieldname]) {
|
||||
me.frm.script_manager.trigger(me.df.fieldname, me.doctype, me.docname);
|
||||
} else {
|
||||
me.frm.runscript(me.df.options, me);
|
||||
}
|
||||
}
|
||||
else if(me.df.click) {
|
||||
me.df.click();
|
||||
}
|
||||
me.onclick();
|
||||
});
|
||||
this.input = this.$input.get(0);
|
||||
this.has_input = true;
|
||||
},
|
||||
onclick: function() {
|
||||
if(this.frm && this.frm.doc && this.frm.cscript) {
|
||||
if(this.frm.cscript[this.df.fieldname]) {
|
||||
this.frm.script_manager.trigger(this.df.fieldname, this.doctype, this.docname);
|
||||
} else {
|
||||
this.frm.runscript(this.df.options, me);
|
||||
}
|
||||
}
|
||||
else if(this.df.click) {
|
||||
this.df.click();
|
||||
}
|
||||
},
|
||||
set_input_areas: function() {
|
||||
this._super();
|
||||
$(this.disp_area).removeClass();
|
||||
|
|
@ -494,10 +496,89 @@ wn.ui.form.ControlButton = wn.ui.form.ControlData.extend({
|
|||
this.$wrapper.find(".help-box").empty().toggle(false);
|
||||
},
|
||||
set_label: function() {
|
||||
$(this.label_span).html(" ");
|
||||
this.$input && this.$input.html(this.df.label);
|
||||
}
|
||||
});
|
||||
|
||||
wn.ui.form.ControlAttach = wn.ui.form.ControlButton.extend({
|
||||
onclick: function() {
|
||||
if(!this.dialog) {
|
||||
this.dialog = new wn.ui.Dialog({
|
||||
title: wn._(this.df.label || "Upload Attachment"),
|
||||
});
|
||||
}
|
||||
|
||||
$(this.dialog.body).empty();
|
||||
|
||||
this.set_upload_options();
|
||||
wn.upload.make(this.upload_options);
|
||||
this.dialog.show();
|
||||
},
|
||||
|
||||
set_upload_options: function() {
|
||||
var me = this;
|
||||
this.upload_options = {
|
||||
parent: this.dialog.body,
|
||||
args: {},
|
||||
max_width: this.df.max_width,
|
||||
max_height: this.df.max_height,
|
||||
callback: function() {
|
||||
me.dialog.hide();
|
||||
me.on_upload_complete(fileid, filename, r);
|
||||
me.show_ok_on_button();
|
||||
},
|
||||
onerror: function() {
|
||||
me.dialog.hide();
|
||||
},
|
||||
}
|
||||
|
||||
if(this.frm) {
|
||||
this.upload_options.args = {
|
||||
from_form: 1,
|
||||
doctype: this.frm.doctype,
|
||||
docname: this.frm.docname,
|
||||
}
|
||||
} else {
|
||||
this.upload_options.on_attach = function(fileobj, dataurl) {
|
||||
me.dialog.hide();
|
||||
me.fileobj = fileobj;
|
||||
me.dataurl = dataurl;
|
||||
if(me.on_attach) {
|
||||
me.on_attach(fileobj, dataurl)
|
||||
}
|
||||
if(me.df.on_attach) {
|
||||
me.df.on_attach(fileobj, dataurl);
|
||||
}
|
||||
me.show_ok_on_button();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
on_upload_complete: function(fileid, filename, r) {
|
||||
this.frm && this.frm.attachments.update_attachment(fileid, filename, this.df.fieldname, r);
|
||||
},
|
||||
|
||||
show_ok_on_button: function() {
|
||||
if(!$(this.input).find(".icon-ok").length) {
|
||||
$(this.input).html('<i class="icon-ok"></i> ' + this.df.label);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
wn.ui.form.ControlAttachImage = wn.ui.form.ControlAttach.extend({
|
||||
make_input: function() {
|
||||
this._super();
|
||||
this.img = $("<img class='img-responsive'>").appendTo($('<div style="margin-top: 7px;">\
|
||||
<div class="missing-image"><i class="icon-camera"></i></div></div>').appendTo(this.input_area)).toggle(false);
|
||||
},
|
||||
on_attach: function(fileobj, dataurl) {
|
||||
$(this.input_area).find(".missing-image").toggle(false);
|
||||
this.img.attr("src", dataurl).toggle(true);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
wn.ui.form.ControlSelect = wn.ui.form.ControlData.extend({
|
||||
html_element: "select",
|
||||
make_input: function() {
|
||||
|
|
|
|||
|
|
@ -1,19 +1,25 @@
|
|||
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
|
||||
// MIT License. See license.txt
|
||||
|
||||
wn.provide("wn.ui.form");
|
||||
wn.ui.form.Layout = Class.extend({
|
||||
init: function(opts) {
|
||||
this.views = {};
|
||||
this.sections = [];
|
||||
this.fields_list = [];
|
||||
this.fields_dict = {};
|
||||
this.labelled_section_count = 0;
|
||||
this.ignore_types = ["Section Break", "Column Break"];
|
||||
|
||||
$.extend(this, opts);
|
||||
this.make();
|
||||
this.render();
|
||||
},
|
||||
make: function() {
|
||||
if(!this.parent && this.body)
|
||||
this.parent = this.body;
|
||||
this.wrapper = $('<div class="form-layout">').appendTo(this.parent);
|
||||
this.fields = wn.meta.get_docfields(this.frm.doctype, this.frm.docname);
|
||||
if(!this.fields)
|
||||
this.fields = wn.meta.docfield_map[this.doctype];
|
||||
this.setup_tabbing();
|
||||
this.render();
|
||||
},
|
||||
add_view: function(label) {
|
||||
var view = $('<div class="form-add-view">').appendTo(this.parent).toggle(false);
|
||||
|
|
@ -32,15 +38,18 @@ wn.ui.form.Layout = Class.extend({
|
|||
},
|
||||
refresh: function() {
|
||||
var me = this;
|
||||
$.each(this.frm.fields, function(i, fieldobj) {
|
||||
fieldobj.docname = me.frm.docname;
|
||||
fieldobj.df = wn.meta.get_docfield(me.frm.doctype,
|
||||
fieldobj.df.fieldname, me.frm.docname);
|
||||
// on form change, permissions can change
|
||||
fieldobj.perm = me.frm.perm;
|
||||
$.each(this.fields_list, function(i, fieldobj) {
|
||||
if(me.frm) {
|
||||
fieldobj.docname = me.frm.docname;
|
||||
fieldobj.df = wn.meta.get_docfield(me.frm.doctype,
|
||||
fieldobj.df.fieldname, me.frm.docname);
|
||||
// on form change, permissions can change
|
||||
fieldobj.perm = me.frm.perm;
|
||||
};
|
||||
fieldobj.refresh && fieldobj.refresh();
|
||||
});
|
||||
$(this.frm.wrapper).trigger("refresh-fields");
|
||||
if(this.frm)
|
||||
$(this.frm.wrapper).trigger("refresh-fields");
|
||||
},
|
||||
render: function() {
|
||||
var me = this;
|
||||
|
|
@ -82,9 +91,11 @@ wn.ui.form.Layout = Class.extend({
|
|||
make_field: function(df, colspan) {
|
||||
!this.column && this.make_column();
|
||||
var fieldobj = make_field(df, this.doctype, this.column.get(0), this.frm);
|
||||
this.frm.fields.push(fieldobj);
|
||||
this.frm.fields_dict[df.fieldname] = fieldobj;
|
||||
fieldobj.perm = this.frm.perm;
|
||||
this.fields_list.push(fieldobj);
|
||||
this.fields_dict[df.fieldname] = fieldobj;
|
||||
if(this.frm) {
|
||||
fieldobj.perm = this.frm.perm;
|
||||
}
|
||||
},
|
||||
make_section: function(df) {
|
||||
if(this.section) {
|
||||
|
|
@ -92,7 +103,7 @@ wn.ui.form.Layout = Class.extend({
|
|||
}
|
||||
this.section = $('<div class="row">')
|
||||
.appendTo(this.wrapper);
|
||||
this.frm.sections.push(this.section);
|
||||
this.sections.push(this.section);
|
||||
|
||||
var section = this.section[0];
|
||||
section.df = df;
|
||||
|
|
@ -108,7 +119,7 @@ wn.ui.form.Layout = Class.extend({
|
|||
"font-weight": "bold",
|
||||
})
|
||||
.appendTo(this.section);
|
||||
if(this.frm.sections.length > 1)
|
||||
if(this.sections.length > 1)
|
||||
this.section.css({
|
||||
"margin-top": "15px",
|
||||
"border-top": "1px solid #ddd"
|
||||
|
|
@ -125,8 +136,8 @@ wn.ui.form.Layout = Class.extend({
|
|||
.appendTo(this.section)
|
||||
.css({"height": "20px"});
|
||||
}
|
||||
this.frm.fields_dict[df.fieldname] = section;
|
||||
this.frm.fields.push(section);
|
||||
this.fields_dict[df.fieldname] = section;
|
||||
this.fields_list.push(section);
|
||||
}
|
||||
// for bc
|
||||
this.section.body = $('<div style="padding: 0px 3%">').appendTo(this.section);
|
||||
|
|
@ -163,11 +174,11 @@ wn.ui.form.Layout = Class.extend({
|
|||
var me = this,
|
||||
grid_row = null;
|
||||
prev = null,
|
||||
fields = me.frm.fields,
|
||||
fields = me.fields,
|
||||
in_grid = false;
|
||||
|
||||
// in grid
|
||||
if(doctype != me.frm.doctype) {
|
||||
if(doctype != me.doctype) {
|
||||
grid_row =me.get_open_grid_row()
|
||||
fields = grid_row.fields;
|
||||
}
|
||||
|
|
@ -178,7 +189,7 @@ wn.ui.form.Layout = Class.extend({
|
|||
if(prev) {
|
||||
this.set_focus(prev)
|
||||
} else {
|
||||
$(cur_frm.wrapper).find(".btn-primary").focus();
|
||||
$(this.primary_button).focus();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -196,7 +207,7 @@ wn.ui.form.Layout = Class.extend({
|
|||
grid_row.grid.grid_rows[grid_row.doc.idx].toggle_view(true);
|
||||
}
|
||||
} else {
|
||||
$(cur_frm.wrapper).find(".btn-primary").focus();
|
||||
$(this.primary_button).focus();
|
||||
}
|
||||
} else {
|
||||
me.focus_on_next_field(i, fields);
|
||||
|
|
@ -238,37 +249,4 @@ wn.ui.form.Layout = Class.extend({
|
|||
return $(".grid-row-open").data("grid_row");
|
||||
},
|
||||
|
||||
// dashboard
|
||||
clear_dashboard: function() {
|
||||
this.dashboard.empty();
|
||||
},
|
||||
add_doctype_badge: function(doctype, fieldname) {
|
||||
if(wn.model.can_read(doctype)) {
|
||||
this.add_badge(wn._(doctype), function() {
|
||||
wn.route_options = {};
|
||||
wn.route_options[fieldname] = cur_frm.doc.name;
|
||||
wn.set_route("List", doctype);
|
||||
}).attr("data-doctype", doctype);
|
||||
}
|
||||
},
|
||||
add_badge: function(label, onclick) {
|
||||
var badge = $(repl('<div class="col-md-4">\
|
||||
<div class="alert alert-warning alert-badge">\
|
||||
<a class="badge-link">%(label)s</a>\
|
||||
<span class="badge pull-right">-</span>\
|
||||
</div></div>', {label:label}))
|
||||
.appendTo(this.dashboard)
|
||||
|
||||
badge.find(".badge-link").click(onclick);
|
||||
|
||||
return badge.find(".alert-badge");
|
||||
},
|
||||
set_badge_count: function(data) {
|
||||
var me = this;
|
||||
$.each(data, function(doctype, count) {
|
||||
$(me.dashboard)
|
||||
.find(".alert-badge[data-doctype='"+doctype+"'] .badge")
|
||||
.html(cint(count));
|
||||
});
|
||||
},
|
||||
})
|
||||
|
|
@ -237,7 +237,7 @@ wn.utils = {
|
|||
var ctx = canvas.getContext("2d");
|
||||
ctx.drawImage(this, 0, 0, tempW, tempH);
|
||||
var dataURL = canvas.toDataURL("image/jpeg");
|
||||
callback(dataURL);
|
||||
setTimeout(function() { callback(dataURL); }, 10 );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -64,7 +64,7 @@ $.extend(wn.meta, {
|
|||
},
|
||||
|
||||
get_fieldnames: function(doctype, name, filters) {
|
||||
return $.map(wn.meta.get_docfields(doctype, name, filters),
|
||||
return $.map(wn.utils.filter_dict(wn.meta.docfield_map[doctype], filters),
|
||||
function(df) { return df.fieldname; });
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ wn.ui.Dialog = wn.ui.FieldGroup.extend({
|
|||
if(!opts.width) opts.width = 480;
|
||||
|
||||
$.extend(this, opts);
|
||||
this._super();
|
||||
this.make();
|
||||
},
|
||||
make: function() {
|
||||
|
|
|
|||
|
|
@ -3,50 +3,53 @@
|
|||
|
||||
wn.provide('wn.ui');
|
||||
|
||||
wn.ui.FieldGroup = Class.extend({
|
||||
wn.ui.FieldGroup = wn.ui.form.Layout.extend({
|
||||
init: function(opts) {
|
||||
$.extend(this, opts);
|
||||
this._super();
|
||||
},
|
||||
make: function() {
|
||||
if(this.fields) {
|
||||
this.make_fields();
|
||||
if(!this.no_submit_on_enter)
|
||||
this._super();
|
||||
this.refresh();
|
||||
if(!this.no_submit_on_enter) {
|
||||
$(this.body).find(".btn:first").removeClass("btn-default").addClass("btn-primary");
|
||||
this.catch_enter_as_submit();
|
||||
}
|
||||
}
|
||||
},
|
||||
first_button: false,
|
||||
make_fields: function() {
|
||||
$(this.body).css({padding:'25px'});
|
||||
this.fields_dict = {}; // reset
|
||||
for(var i=0; i< this.fields.length; i++) {
|
||||
var df = this.fields[i];
|
||||
if(!df.fieldname && df.label) {
|
||||
df.fieldname = df.label.replace(/ /g, '_').toLowerCase();
|
||||
}
|
||||
if(!df.fieldtype) df.fieldtype="Data";
|
||||
|
||||
var div = $a(this.body, 'div');
|
||||
f = make_field(df, null, div, null);
|
||||
f.not_in_form = 1;
|
||||
f.dialog_wrapper = this.wrapper || null;
|
||||
this.fields_dict[df.fieldname] = f
|
||||
f.refresh();
|
||||
|
||||
// first button primary ?
|
||||
if(df.fieldtype=='Button' && !this.first_button) {
|
||||
$(f.input).removeClass("btn-default").addClass('btn-info');
|
||||
this.first_button = true;
|
||||
}
|
||||
if(!df.description) {
|
||||
$(f.wrapper).find(".help-box").toggle(false);
|
||||
}
|
||||
}
|
||||
},
|
||||
// make_fields: function() {
|
||||
// this.fields_dict = {}; // reset
|
||||
// for(var i=0; i< this.fields.length; i++) {
|
||||
// var df = this.fields[i];
|
||||
// if(!df.fieldname && df.label) {
|
||||
// df.fieldname = df.label.replace(/ /g, '_').toLowerCase();
|
||||
// }
|
||||
// if(!df.fieldtype) df.fieldtype="Data";
|
||||
//
|
||||
// var div = $a(this.body, 'div');
|
||||
// f = make_field(df, null, div, null);
|
||||
// f.not_in_form = 1;
|
||||
// f.dialog_wrapper = this.wrapper || null;
|
||||
// this.fields_dict[df.fieldname] = f
|
||||
// f.refresh();
|
||||
//
|
||||
// // first button primary ?
|
||||
// if(df.fieldtype=='Button' && !this.first_button) {
|
||||
// $(f.input).removeClass("btn-default").addClass('btn-info');
|
||||
// this.first_button = true;
|
||||
// }
|
||||
// if(!df.description) {
|
||||
// $(f.wrapper).find(".help-box").toggle(false);
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
catch_enter_as_submit: function() {
|
||||
var me = this;
|
||||
$(this.body).find('input[type="text"], input[type="password"]').keypress(function(e) {
|
||||
if(e.which==13) {
|
||||
$(me.body).find('.btn-info:first').click();
|
||||
$(me.body).find('.btn-primary:first').click();
|
||||
}
|
||||
})
|
||||
},
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ wn.upload = {
|
|||
$upload.find(".action-link").addClass("disabled");
|
||||
$upload.find(".action-attach-input").toggle(false);
|
||||
$upload.find(".action-link-input").toggle(true);
|
||||
$upload.find(".btn-upload").html('<i class="icon-link"></i> ' +wn._('Set Link'))
|
||||
return false;
|
||||
})
|
||||
|
||||
|
|
@ -35,6 +36,7 @@ wn.upload = {
|
|||
$upload.find(".action-attach").addClass("disabled");
|
||||
$upload.find(".action-link-input").toggle(false);
|
||||
$upload.find(".action-attach-input").toggle(true);
|
||||
$upload.find(".btn-upload").html('<i class="icon-upload"></i> ' +wn._('Upload'))
|
||||
return false;
|
||||
})
|
||||
|
||||
|
|
@ -72,9 +74,10 @@ wn.upload = {
|
|||
return;
|
||||
}
|
||||
|
||||
var dataurl = null;
|
||||
var _upload_file = function() {
|
||||
if(opts.on_attach) {
|
||||
opts.on_attach(args)
|
||||
opts.on_attach(args, dataurl)
|
||||
} else {
|
||||
var msgbox = msgprint(wn._("Uploading..."));
|
||||
return wn.call({
|
||||
|
|
@ -104,12 +107,14 @@ wn.upload = {
|
|||
freader.onload = function() {
|
||||
args.filename = fileobj.name;
|
||||
if((opts.max_width || opts.max_height) && (/\.(gif|jpg|jpeg|tiff|png)$/i).test(args.filename)) {
|
||||
wn.utils.resize_image(freader, function(dataurl) {
|
||||
args.filedata = dataurl.split(",")[1];
|
||||
wn.utils.resize_image(freader, function(_dataurl) {
|
||||
dataurl = _dataurl;
|
||||
args.filedata = _dataurl.split(",")[1];
|
||||
console.log("resized!")
|
||||
_upload_file();
|
||||
})
|
||||
} else {
|
||||
dataurl = freader.result;
|
||||
args.filedata = freader.result.split(",")[1];
|
||||
_upload_file();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ $(document).ready(function() {
|
|||
}
|
||||
|
||||
wn.call({
|
||||
btn: this,
|
||||
type: "POST",
|
||||
method: "website.templates.includes.comments.add_comment",
|
||||
args: args,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue