unclean SPARC
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
<style>
|
||||
.submission.short-form > header {
|
||||
background: url('/app/assets/images/cards/submission-card.jpg');
|
||||
background-position: center;
|
||||
background-size: cover !important;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
.submission.short-form .tools {
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
.submission.short-form input[data-path="organisation"][name="pic"],
|
||||
.submission.short-form input[data-path="organisation.address"][name="postcode"],
|
||||
.submission.short-form input[data-path="proposal"][name="number"] { min-width: 180px; }
|
||||
.submission.short-form textarea { min-height: 120px; }
|
||||
.submission.short-form [data-part="funding"] textarea[name="needs"],
|
||||
.submission.short-form textarea[name="genderBalance"],
|
||||
.submission.short-form [data-part="problem"] textarea,
|
||||
.submission.short-form [data-part="solution"] textarea,
|
||||
.submission.short-form [data-part="competition"] textarea,
|
||||
.submission.short-form [data-part="impacts"] textarea { min-height: 430px; }
|
||||
.submission.short-form [data-part="general"] select[name="estimatedTRL"]+div.eicui-select-selection span { white-space: normal; }
|
||||
.submission.short-form .tools .contributors { white-space: nowrap; }
|
||||
.submission.short-form .tools .contributors [eicchip],
|
||||
.submission.short-form .tools .contributors [eicchip] label { cursor: pointer; }
|
||||
.submission.short-form [data-part] h2 { white-space: normal; }
|
||||
</style>
|
||||
<article eiccard media class="submission short-form">
|
||||
<header>
|
||||
<h1>Short proposal ${models.submission.data.proposal.number}</h1>
|
||||
<h2>
|
||||
<span eicchip primary>short ${models.submission.data.version}</span>
|
||||
<span eicchip primary>${models.submission.data.status}</span>
|
||||
${models.submission.data.resubmitted ? `<span eicchip accent>resubmission</span>`:''}
|
||||
</h2>
|
||||
</header>
|
||||
<section>
|
||||
<div eicalert danger class="display:none;">
|
||||
<p small><span danger>Please note that after <b>December 31st 2023 at 23:59 (GMT +1)</b>, it will no longer be possible to submit a short proposal via the current EIC Platform.</span></p>
|
||||
<div small>
|
||||
Nonetheless, the platform will remain accessible to consult previous proposals, drafts, results and to access the coaching module.
|
||||
Should you intend to submit a new short proposal as of <b>January 3, 2024</b> you can do so via the <a href="https://ec.europa.eu/info/funding-tenders/opportunities/portal/" target="_blank" title="Funding and Tenders Portal">Funding and Tenders Portal</a>.
|
||||
Please note that the templates and rules for the short proposal will change under the <a href="https://eic.ec.europa.eu/eic-2024-work-programme_en" target="_blank" title="EIC Work Programme 2024">EIC Work Programme 2024</a>.
|
||||
We invite you to read them carefully. The new rules will come into force from <b>January 1, 2024</b>.
|
||||
More detailed information will be available shortly on our <a href="https://eic.ec.europa.eu/eic-accelerator-application-platform-frequently-asked-questions_en" target="_blank" title="EIC Website">website</a>.
|
||||
</div>
|
||||
</div>
|
||||
<div class="tools cols-2 right">
|
||||
<div class="cols-2">
|
||||
<div class="updated"><label small>last saved</label><span class="date" small></span> by <span class="contributor"></span></div>
|
||||
<div class="created"><label small>created</label><span class="date" small></span> by <span class="contributor"></span></div>
|
||||
</div>
|
||||
<div class="contributors"></div>
|
||||
</div>
|
||||
<div class="form cols-2 left">
|
||||
<input type="hidden" name="version" data-path="" value="1.0" />
|
||||
<div class="tabs-extended vertical">
|
||||
<section>
|
||||
<menu eictab>
|
||||
<li data-target="general">General<span xxsmall eicbadge danger></span></li>
|
||||
<li data-target="problem">Opportunity<span xxsmall eicbadge danger></span></li>
|
||||
<li data-target="solution">Solution<span xxsmall eicbadge danger></span></li>
|
||||
<li data-target="competition">Competition<span xxsmall eicbadge danger></span></li>
|
||||
<li data-target="impacts">Impacts<span xxsmall eicbadge danger></span></li>
|
||||
<li data-target="company">Company<span xxsmall eicbadge danger></span></li>
|
||||
<li data-target="team">Team<span xxsmall eicbadge danger></span></li>
|
||||
<li data-target="funding">Funding<span xxsmall eicbadge danger></span></li>
|
||||
<li data-target="documents">Documents<span xxsmall eicbadge danger></span></li>
|
||||
<li data-target="status">Submission<span xxsmall eicbadge danger></span></li>
|
||||
<li data-target="consent">Data sharing<span xxsmall eicbadge danger></span></li>
|
||||
</menu>
|
||||
</section>
|
||||
</div>
|
||||
<div class="content" data-part="general"></div>
|
||||
<div class="content" data-part="problem"></div>
|
||||
<div class="content" data-part="solution"></div>
|
||||
<div class="content" data-part="competition"></div>
|
||||
<div class="content" data-part="impacts"></div>
|
||||
<div class="content" data-part="company"></div>
|
||||
<div class="content" data-part="team"></div>
|
||||
<div class="content" data-part="funding"></div>
|
||||
<div class="content" data-part="documents"></div>
|
||||
<div class="content" data-part="status"></div>
|
||||
<div class="content" data-part="consent"></div>
|
||||
</div>
|
||||
</section>
|
||||
</article>
|
||||
@@ -0,0 +1,410 @@
|
||||
/**
|
||||
* Short Proposal Form
|
||||
*
|
||||
* @version 2023
|
||||
* @author Michael Fallise
|
||||
*
|
||||
* Options:
|
||||
* * modeAc
|
||||
*
|
||||
*/
|
||||
class SubmissionShortForm2023View extends EICDomContent {
|
||||
|
||||
options = {
|
||||
mode: 'read',
|
||||
autoSaveInterval: 15 * 1000,
|
||||
validationInterval: 2 * 1000,
|
||||
}
|
||||
|
||||
chunks = [];
|
||||
|
||||
DOMContentLoaded(options) {
|
||||
this.components = ui.eicfy(this.el)
|
||||
for(let model in options.models) this[model] = options.models[model];
|
||||
|
||||
this.tabs = new Tab();
|
||||
this.tabs.addTabs(this.findAll('.tabs-extended menu li'), this.findAll('.content'))
|
||||
|
||||
this.form = new Form(this.find('.form'));
|
||||
|
||||
this.pic = options.profile.pic;
|
||||
this.number = options.profile.number;
|
||||
this.members.list(this.pic,this.number).then(this.fillContributors.bind(this))
|
||||
this.mode = options.profile.mode || this.options.mode;
|
||||
this.checkConcurrency(options.profile.mode || this.options.mode);
|
||||
}
|
||||
|
||||
async checkConcurrency(mode) {
|
||||
if(mode == 'edit') {
|
||||
let diff = (new Date()).getTime() - (new Date(this.submission.data.updated.date)).getTime()
|
||||
let created = (new Date()).getTime() - (new Date(this.submission.data.created.date)).getTime()
|
||||
if(diff < this.options.autoSaveInterval && created > this.options.autoSaveInterval) {
|
||||
// someone is editing right now
|
||||
let goReadOnly = await this.openDialog(
|
||||
await this.loadContent(
|
||||
'projects/submissions/dialogs/SubmissionFormConcurrencyDialog',
|
||||
{ title: 'Someone is already at work' }, {
|
||||
contributor: this.submission.data.updated.contributor
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
mode = 'read';
|
||||
|
||||
if(!goReadOnly) {
|
||||
this.mode = 'edit';
|
||||
this.unload();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.fill(mode);
|
||||
}
|
||||
|
||||
DOMContentRemoved() {
|
||||
if(!this.loaded) return;
|
||||
if(this.autoSave) {
|
||||
clearInterval(this.autoSave)
|
||||
this.autoSave = null;
|
||||
};
|
||||
if(this.validationCheck) {
|
||||
clearInterval(this.validationCheck);
|
||||
this.validationCheck = null;
|
||||
}
|
||||
if((this.mode == 'edit')) this.save();
|
||||
|
||||
for(let chunk of this.chunks) { chunk.view.DOMContentRemoved(); }
|
||||
}
|
||||
|
||||
DOMContentBlured() {
|
||||
if(!this.loaded) return;
|
||||
if(this.autoSave) {
|
||||
clearInterval(this.autoSave);
|
||||
this.autoSave = null;
|
||||
}
|
||||
if(this.validationCheck) {
|
||||
clearInterval(this.validationCheck);
|
||||
this.validationCheck = null;
|
||||
}
|
||||
}
|
||||
|
||||
DOMContentFocused(options) {
|
||||
if(!this.loaded) return;
|
||||
|
||||
//By Nike : if options, means rerouted, then new models, then switch to fresh models !
|
||||
if(options) {
|
||||
for(let model in options.models) this[model] = options.models[model];
|
||||
}
|
||||
|
||||
//By Nike: propagate DOMContentFocused to tabs. Caution before setupMode which calls fill, which must have fresh model.data
|
||||
for(let chunk of this.chunks) chunk.view.DOMContentFocused(options)
|
||||
|
||||
if(
|
||||
options &&
|
||||
options.profile &&
|
||||
options.profile.mode &&
|
||||
options.profile.mode != this.mode
|
||||
) this.setupMode(options.profile.mode);
|
||||
|
||||
if(!this.autoSave && this.mode == 'edit') {
|
||||
this.autoSave = setInterval(this.save.bind(this), this.options.autoSaveInterval);
|
||||
}
|
||||
if(!this.validationCheck && this.mode == 'edit') {
|
||||
this.validationCheck = setInterval(this.validate.bind(this), this.options.validationCheck);
|
||||
}
|
||||
}
|
||||
|
||||
fill(mode) {
|
||||
let myTabsPath = 'projects/submissions/2023/tabs/'
|
||||
|
||||
this.find('.tools .created .date').innerText = (new Date(this.submission.data.created.date)).toLocaleString("en-DE");
|
||||
this.find('.tools .created .contributor').innerText = `${this.submission.data.created.contributor.firstname} ${this.submission.data.created.contributor.lastname}`;
|
||||
|
||||
this.refreshUpdated(this.submission.data.updated);
|
||||
|
||||
let queue = [
|
||||
this.loadContent( myTabsPath+'SubmissionShortForm2023GeneralView', {}, { model: this.submission } )
|
||||
.then( view => this.appendTab('general', view)),
|
||||
this.loadContent( myTabsPath+'SubmissionShortForm2023CompanyView', {}, { model: this.submission } )
|
||||
.then( view => this.appendTab('company', view)),
|
||||
this.loadContent( myTabsPath+'SubmissionShortForm2023TeamView', {}, { model: this.submission, team: this.team, pic: this.pic, number: this.number } )
|
||||
.then( view => this.appendTab('team', view)),
|
||||
this.loadContent( myTabsPath+'SubmissionShortForm2023ProblemView', {}, { model: this.submission } )
|
||||
.then( view => this.appendTab('problem', view)),
|
||||
this.loadContent( myTabsPath+'SubmissionShortForm2023SolutionView', {}, { model: this.submission } )
|
||||
.then( view => this.appendTab('solution', view)),
|
||||
this.loadContent( myTabsPath+'SubmissionShortForm2023CompetitionView', {}, { model: this.submission } )
|
||||
.then( view => this.appendTab('competition', view)),
|
||||
this.loadContent( myTabsPath+'SubmissionShortForm2023FundingView', {}, { model: this.submission } )
|
||||
.then( view => this.appendTab('funding', view)),
|
||||
this.loadContent( myTabsPath+'SubmissionShortForm2023ImpactView', {}, { model: this.submission } )
|
||||
.then( view => this.appendTab('impacts', view)),
|
||||
this.loadContent( myTabsPath+'SubmissionShortForm2023DocumentsView', {}, { model: this.submission } )
|
||||
.then( view => {
|
||||
this.appendTab('documents', view);
|
||||
view.el.addEventListener('save', this.save.bind(this) )
|
||||
}),
|
||||
this.loadContent( myTabsPath+'SubmissionShortForm2023ConsentView', {}, { model: this.submission, team: this.team, pic: this.pic, number: this.number } )
|
||||
.then( view => this.appendTab('consent', view))
|
||||
];
|
||||
|
||||
if(['draft', 'frozen'].includes(this.submission.data.status)) {
|
||||
queue.push(
|
||||
this.loadContent( myTabsPath+'SubmissionShortForm2023DisclaimerView', {}, { model: this.submission } )
|
||||
.then( view => {
|
||||
this.appendTab('status', view);
|
||||
this.statusTab = view;
|
||||
view.el.addEventListener('submit', this.submit.bind(this));
|
||||
})
|
||||
)
|
||||
} else {
|
||||
queue.push(
|
||||
this.loadContent( myTabsPath+'SubmissionShortForm2023StatusView', {}, { model: this.submission } )
|
||||
.then( view => {
|
||||
this.appendTab('status', view);
|
||||
this.statusTab = view;
|
||||
view.el.addEventListener('withdraw', this.withdraw.bind(this));
|
||||
view.el.addEventListener('clone', this.clone.bind(this));
|
||||
view.el.addEventListener('complain', this.complain.bind(this));
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
Promise.allSettled(queue)
|
||||
.then((results) => {
|
||||
this.setupMode(mode);
|
||||
this.loaded = true;
|
||||
});
|
||||
}
|
||||
|
||||
setupMode(mode) {
|
||||
|
||||
this.mode = mode;
|
||||
|
||||
for(let chunk of this.chunks) {
|
||||
chunk.view.options.mode = mode;
|
||||
chunk.view.fill(mode);
|
||||
}
|
||||
|
||||
if(this.mode == 'read' && this.autoSave) {
|
||||
clearInterval(this.autoSave);
|
||||
this.autoSave = null
|
||||
}
|
||||
|
||||
if(this.mode == 'read' && this.validationCheck) {
|
||||
clearInterval(this.validationCheck);
|
||||
this.validationCheck = null
|
||||
}
|
||||
|
||||
if(this.mode == 'edit' && !this.autoSave) {
|
||||
this.autoSave = setInterval(this.save.bind(this), this.options.autoSaveInterval);
|
||||
this.save(); // perform a save on startup to mark editing start
|
||||
}
|
||||
|
||||
if(this.mode == 'edit' && !this.validationCheck) {
|
||||
this.validationCheck = setInterval(this.validate.bind(this), this.options.validationInterval);
|
||||
}
|
||||
|
||||
if(!['draft', 'frozen'].includes(this.submission.data.status)) {
|
||||
this.tabs.selectByIndex(this.tabs.triggers.length - 2);
|
||||
}
|
||||
}
|
||||
|
||||
appendTab(target, view) {
|
||||
let chunk = {target: target, view: view};
|
||||
this.chunks.push( chunk );
|
||||
this.find(`.content[data-part="${target}"]`).append(view.el);
|
||||
return chunk;
|
||||
}
|
||||
|
||||
fillContributors(data) {
|
||||
let metrics = { contributors: 0, pending: 0 }
|
||||
this.find('.contributors').innerHTML = '';
|
||||
for(let item of data) {
|
||||
if(item.status == 'active') metrics.contributors++;
|
||||
if(item.status == 'pending') metrics.pending++;
|
||||
}
|
||||
this.find('.contributors').innerHTML = '';
|
||||
if(metrics.contributors > 0) {
|
||||
let chip = new Chip(null, {label: 'contributors', severity: 'primary', badge: metrics.contributors});
|
||||
chip.el.addEventListener('click', this.onContributorsEdit.bind(this))
|
||||
this.find('.contributors').append(chip.el);
|
||||
}
|
||||
if(metrics.pending > 0) {
|
||||
let chip = new Chip(null, {label: 'pending requests', severity: 'warning', badge: metrics.pending})
|
||||
chip.el.addEventListener('click', this.onContributorsEdit.bind(this))
|
||||
this.find('.contributors').append(chip.el);
|
||||
}
|
||||
}
|
||||
|
||||
async onContributorsEdit(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
await this.openDialog(
|
||||
await this.loadContent(
|
||||
'projects/submissions/dialogs/SubmissionFormAccessDialog',
|
||||
{ title: 'Contributors to this proposal' }, {
|
||||
pic: this.pic,
|
||||
number: this.number,
|
||||
models: {
|
||||
proposal: this.members,
|
||||
organisation: new ApplicantMembersModel(['list'])
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
this.members.list(this.pic,this.number)
|
||||
.then(this.fillContributors.bind(this));
|
||||
|
||||
}
|
||||
|
||||
validate() {
|
||||
let valid = true;
|
||||
|
||||
for(let chunk of this.chunks) {
|
||||
let report = chunk.view.validate(true);
|
||||
let badge = this.components.find(item => item.el.hasAttribute('eicbadge') && item.el.parentElement.dataset.target == chunk.target)
|
||||
badge.value = report.issues;
|
||||
|
||||
valid = valid && report.valid;
|
||||
}
|
||||
this.statusTab.switchSubmit(!valid);
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
refreshUpdated(data) {
|
||||
this.find('.tools .updated .date').innerText = (new Date(data.date)).toLocaleString("en-DE");
|
||||
this.find('.tools .updated .contributor').innerText = `${data.contributor.firstname} ${data.contributor.lastname}`;
|
||||
}
|
||||
|
||||
save() {
|
||||
this.validate();
|
||||
this.submission.save(this.pic, this.number, this.form.value)
|
||||
.then(
|
||||
async payload => {
|
||||
this.refreshUpdated(payload.updated);
|
||||
this.dispatchUpdate();
|
||||
},
|
||||
async error => {
|
||||
if(error.code == 504) {
|
||||
ui.growl('Auto save encountered some issue.', 'danger');
|
||||
this.setupMode('read');
|
||||
} else {
|
||||
ui.growl.append(error.displayMessage, 'danger');
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
async submit(event) {
|
||||
if(this.validate()) {
|
||||
if(this.autoSave) {
|
||||
clearInterval(this.autoSave)
|
||||
this.autoSave = null;
|
||||
};
|
||||
if(this.validationCheck) {
|
||||
clearInterval(this.validationCheck);
|
||||
this.validationCheck = null;
|
||||
}
|
||||
this.submission.submit(this.pic, this.number, this.form.value)
|
||||
.then(async payload => {
|
||||
|
||||
this.dispatchUpdate();
|
||||
this.mode = 'read'; // exiting edit mode, avoiding save on close
|
||||
ui.growl.append('Your proposal has been successfully submitted', 'success');
|
||||
this.unload();
|
||||
|
||||
},
|
||||
() => {
|
||||
if(!this.autoSave && this.mode == 'edit') {
|
||||
this.autoSave = setInterval(this.save.bind(this), this.options.autoSaveInterval);
|
||||
}
|
||||
if(!this.validationCheck && this.mode == 'edit') {
|
||||
this.validationCheck = setInterval(this.validate.bind(this), this.options.validationCheck);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async withdraw(event) {
|
||||
this.submission.withdraw(this.pic, this.number, this.form.value)
|
||||
.then(async payload => {
|
||||
this.dispatchUpdate();
|
||||
ui.growl.append('Your proposal has been successfully withdrawn', 'success');
|
||||
this.unload();
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
async clone(event) {
|
||||
this.submission.clone(this.pic, this.number)
|
||||
.then(
|
||||
async payload => {
|
||||
this.dispatchUpdate();
|
||||
ui.growl.append('A new proposal is available', 'success');
|
||||
this.unload();
|
||||
},
|
||||
async () => {
|
||||
ui.growl.append('Sorry, you don\'t have the rights to clone this proposal', 'danger')
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
async complain(event) {
|
||||
|
||||
let complaint = await this.openDialog(
|
||||
await this.loadContent(
|
||||
'projects/submissions/dialogs/SubmissionFormComplaintDialog',
|
||||
{ title: 'File a complaint about the evaluation' }, {
|
||||
pic: this.pic,
|
||||
number: this.number,
|
||||
proposal: this.submission
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
if(complaint) this.unload();
|
||||
}
|
||||
|
||||
|
||||
|
||||
DOMContentResized() {
|
||||
super.DOMContentResized();
|
||||
|
||||
let device = this.el.getAttribute('device');
|
||||
let tabs = this.find('.tabs-extended');
|
||||
|
||||
switch(device) {
|
||||
case 'desktop':
|
||||
ui.show(tabs);
|
||||
let current = tabs.querySelector('.tab-selected');
|
||||
let part = current.getAttribute('data-target');
|
||||
this.findAll('.content[data-part]').forEach(content => { if(content.getAttribute('data-part') != part) ui.hide(content) });
|
||||
break;
|
||||
default:
|
||||
ui.hide(tabs);
|
||||
this.findAll('.content[data-part]').forEach(content => { ui.show(content) })
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dispatchUpdate() {
|
||||
/*
|
||||
// MFA: if ever needed to perform local updates
|
||||
let data = {
|
||||
number: this.submission.data.proposal.number,
|
||||
acronym: this.submission.data.proposal.acronym,
|
||||
status: this.submission.data.status,
|
||||
version: this.submission.data.version
|
||||
}
|
||||
*/
|
||||
let data = null;
|
||||
|
||||
app.events.trigger('proposal_updated', data);
|
||||
}
|
||||
}
|
||||
|
||||
app.registerClass('SubmissionShortForm2023View', SubmissionShortForm2023View);
|
||||
@@ -0,0 +1,57 @@
|
||||
<h2>Company</h2>
|
||||
<div class="cols-2 left">
|
||||
<div>
|
||||
<label>PIC</label>
|
||||
<input eicinput disabled name="pic" data-path="organisation" data-type="text" />
|
||||
</div>
|
||||
<div>
|
||||
<label>Legal entity name (which can be the name of a person)</label>
|
||||
<input eicinput disabled name="legalname" data-path="organisation" data-type="text" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label>Business name</label>
|
||||
<input eicinput disabled name="businessName" data-path="organisation" data-type="text" />
|
||||
</div>
|
||||
<div>
|
||||
<label>Address</label>
|
||||
<input eicinput disabled name="street" data-path="organisation.address" data-type="text" placeholder="Street" />
|
||||
</div>
|
||||
<div class="cols-2 left">
|
||||
<input eicinput disabled name="postcode" data-path="organisation.address" data-type="text" placeholder="Postal Code" />
|
||||
<input eicinput disabled name="city" data-path="organisation.address" data-type="text" placeholder="City" />
|
||||
</div>
|
||||
<div>
|
||||
<input eicinput disabled name="country" data-path="organisation.address" data-type="text" placeholder="Country" />
|
||||
</div>
|
||||
<div>
|
||||
<label>VAT Number</label>
|
||||
<input eicinput disabled name="VAT" data-path="organisation" data-type="text" />
|
||||
</div>
|
||||
<div>
|
||||
<div eicalert info>
|
||||
The company information above is collected from the Funding & tender opportunities Portal. Should your company data be missing or incorrect please update your company information on the Funding & tender opportunities portal directly following
|
||||
<a class="fundingportal-link" href="https://ec.europa.eu/info/funding-tenders/opportunities/portal/screen/home" target="_blank" title="Funding & tender opportunities">this link</a>.
|
||||
Once done, use the refresh button below to update the organisation info in your proposal.</div>
|
||||
<div class="cols-1 right">
|
||||
<button eicbutton small primary class="company-update">refresh</button>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label>Website</label>
|
||||
<input eicinput name="website" data-path="organisation" data-type="text" />
|
||||
</div>
|
||||
<div>
|
||||
<label>What is your type of entity ?</label>
|
||||
<select eicselect name="companyType" data-path="organisation" class="required">
|
||||
<option value=""></option>
|
||||
<option value="sme">SME</option>
|
||||
<option value="midcap">Small mid-cap</option>
|
||||
<option value="person">Natural person</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label>Describe your company history, your vision and ambitions.</label>
|
||||
<textarea eictextarea name="description" data-path="organisation" data-type="text" maxlen="5000" class="required"></textarea>
|
||||
</div>
|
||||
@@ -0,0 +1,65 @@
|
||||
class SubmissionShortForm2023CompanyView extends SubmissionShortFormTabView {
|
||||
|
||||
setupRules() {
|
||||
this.companyUpdate = this.components.find(component => component.el.classList.contains('company-update'));
|
||||
this.companyUpdate.el.addEventListener('click', this.onCompanyUpdate.bind(this));
|
||||
}
|
||||
|
||||
fill(mode) {
|
||||
super.fill(mode);
|
||||
|
||||
this.find('[name="pic"]').setAttribute('disabled', '');
|
||||
this.find('[name="legalname"]').setAttribute('disabled', '');
|
||||
this.find('[name="businessName"]').setAttribute('disabled', '');
|
||||
this.find('[name="street"]').setAttribute('disabled', '');
|
||||
this.find('[name="postcode"]').setAttribute('disabled', '');
|
||||
this.find('[name="city"]').setAttribute('disabled', '');
|
||||
this.find('[name="country"]').setAttribute('disabled', '');
|
||||
this.find('[name="VAT"]').setAttribute('disabled', '');
|
||||
|
||||
if(mode == 'edit') {
|
||||
ui.show(this.companyUpdate.el)
|
||||
} else {
|
||||
ui.hide(this.companyUpdate.el)
|
||||
}
|
||||
|
||||
// Nike to MFA: was ${model.data.organisation.pic} straight in the markup.
|
||||
// Unfortunaly, it happens that organisation is not (yet?) in data.
|
||||
// Then it crashes the tab on a templating error (actually it makes empty thx to the template-error-catching)
|
||||
// Also the pic can be empty, then you have a "bad pic" arriving on the F&TP.
|
||||
// So defaut link in markup is your F&TP home, the we replace here by more precise if all ok.
|
||||
if(this.model.data.organisation && this.model.data.organisation.pic) {
|
||||
this.find('.fundingportal-link').setAttribute('href', `https://ec.europa.eu/info/funding-tenders/opportunities/portal/participant/${this.model.data.organisation.pic}/organisation-data`);
|
||||
}
|
||||
}
|
||||
|
||||
onCompanyUpdate(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
this.companyUpdate.loading = true;
|
||||
|
||||
this.model.getOrganisationInfo(this.model.data.organisation.pic)
|
||||
.then(this.onSuccess.bind(this), this.onFailure.bind(this))
|
||||
}
|
||||
|
||||
async onSuccess(data) {
|
||||
this.companyUpdate.loading = false;
|
||||
|
||||
this.find('[name="legalname"]').value = data.legalName;
|
||||
// currently missing in service
|
||||
if(data.businessName) this.find('[name="businessName"]').value = data.businessName;
|
||||
this.find('[name="street"]').value = data.street;
|
||||
this.find('[name="postcode"]').value = data.postalCode;
|
||||
this.find('[name="city"]').value = data.city;
|
||||
this.find('[name="country"]').value = data.country;
|
||||
this.find('[name="VAT"]').value = data.vat;
|
||||
}
|
||||
|
||||
async onFailure() {
|
||||
this.companyUpdate.loading = false;
|
||||
ui.growl.append('We could not update your organisation info', 'danger');
|
||||
}
|
||||
}
|
||||
|
||||
app.registerClass('SubmissionShortForm2023CompanyView', SubmissionShortForm2023CompanyView);
|
||||
@@ -0,0 +1,5 @@
|
||||
<h2>Market and Competition analysis</h2>
|
||||
<div>
|
||||
<label>Describe your business model and the target market (segmentations, size, growth and drivers), explain why customers would be willing to pay, outline the advantages and disadvantages of your solution compared to competitors, and explain how the company's growth will be impacted.</label>
|
||||
<textarea eictextarea name="competition" data-path="narrative" data-type="text" maxlen="10000" class="required"></textarea>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
class SubmissionShortForm2023CompetitionView extends SubmissionShortFormTabView {}
|
||||
|
||||
app.registerClass('SubmissionShortForm2023CompetitionView', SubmissionShortForm2023CompetitionView);
|
||||
@@ -0,0 +1,8 @@
|
||||
<h2>Data sharing consent</h2>
|
||||
<p>Your National Contact Point, Enterprise Europe Network (EEN) Members and Knowledge Innovation Communities of the European Institute of Innovation and Technologies (EIT KICs) may be a useful source of information and support in preparation of your full proposal. Therefore, we encourage you to share your data with them.</p>
|
||||
<p>I consent to sharing the following data with my relevant National Contact Point, relevant EEN Member and EIT KICs:</p>
|
||||
<div class="cols-2 left noflex">
|
||||
<input eiccheckbox type="checkbox" name="sharingConsent" data-path="declarations" value="true" />
|
||||
<div>basic information about my proposal limited to the name, phone, email of the CEO or person in charge of managing innovation/company, proposal acronym, title, abstract, evaluation result (GO/NO GO).</div>
|
||||
</div>
|
||||
<p>The data will be made available subject to confidentiality obligations of the NCPs, KICs and EEN members.</p>
|
||||
@@ -0,0 +1,3 @@
|
||||
class SubmissionShortForm2023ConsentView extends SubmissionShortFormTabView {}
|
||||
|
||||
app.registerClass('SubmissionShortForm2023ConsentView', SubmissionShortForm2023ConsentView);
|
||||
@@ -0,0 +1,139 @@
|
||||
<h2>Submit your proposal</h2>
|
||||
<div class="resubmission">
|
||||
<div>
|
||||
<label>Summarise the main changes compared to the previous (rejected) short proposal which you submitted</label>
|
||||
<textarea eictextarea name="changes" data-path="resubmission" data-type="text" maxlen="10000" class=""></textarea>
|
||||
</div>
|
||||
<div>
|
||||
<label>Provide your rebuttal (if any) to the experts' comments to the previous (rejected) short proposal which you submitted</label>
|
||||
<textarea eictextarea name="rebuttal" data-path="resubmission" data-type="text" maxlen="10000" class=""></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="declaration">
|
||||
<h5>Declarations</h5>
|
||||
<div eicalert warning>All declarations have to be agreed when submitting the form</div>
|
||||
<div class="cols-2 left noflex">
|
||||
<input eiccheckbox class="required" type="checkbox" name="consentOfApplicants" data-path="declarations" data-type="ignore" value="true" />
|
||||
<div>
|
||||
We declare to have the explicit consent of all applicants on their
|
||||
participation and on the content of this proposal.
|
||||
</div>
|
||||
</div>
|
||||
<div class="cols-2 left noflex">
|
||||
<input eiccheckbox class="required" type="checkbox" name="correctInformation" data-path="declarations" data-type="ignore" value="true" />
|
||||
<div>
|
||||
We confirm that the information contained in this proposal is correct
|
||||
and complete and that none of the project activities have started
|
||||
before the proposal was submitted (unless explicitly authorised in
|
||||
the call conditions).
|
||||
</div>
|
||||
</div>
|
||||
<div class="cols-2 left noflex">
|
||||
<input eiccheckbox class="required" type="checkbox" name="elligible" data-path="declarations" data-type="ignore" value="true" />
|
||||
|
||||
<div>
|
||||
We declare:
|
||||
<ul bulleted>
|
||||
<li>to be fully compliant with the eligibility criteria set out in the call</li>
|
||||
<li>not to be subject to any exclusion grounds under the EU Financial Regulation 2018/1046</li>
|
||||
<li>to have the financial and operational capacity to carry out the proposed project.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cols-2 left noflex">
|
||||
<input eiccheckbox class="required" type="checkbox" name="useOfFToP" data-path="declarations" data-type="ignore" value="true" />
|
||||
<div>
|
||||
We acknowledge that all communication will be made through the Funding & Tenders opportunities
|
||||
Portal electronic exchange system and that access and use of this system is subject
|
||||
to the Funding & Tenders opportunities Portal Terms & Conditions.
|
||||
</div>
|
||||
</div>
|
||||
<div class="cols-2 left noflex">
|
||||
<input eiccheckbox class="required" type="checkbox" name="acceptTerms" data-path="declarations" data-type="ignore" value="true" />
|
||||
<div>
|
||||
We have read, understood and accepted the Funding & Tenders Portal Terms & Conditions
|
||||
and Privacy Statement that set out the conditions of use of the Portal and the scope,
|
||||
purposes, retention periods, etc. for the processing of personal data of all data
|
||||
subjects whose data we communicate for the purpose of the application, evaluation,
|
||||
award and subsequent management of our grant, prizes and contracts (including financial
|
||||
transactions and audits).
|
||||
</div>
|
||||
</div>
|
||||
<div class="cols-2 left noflex">
|
||||
<input eiccheckbox class="required" type="checkbox" name="ethicalPrinciples" data-path="declarations" data-type="ignore" value="true" />
|
||||
<div>
|
||||
<p>We declare that the proposal complies with ethical principles (including the highest
|
||||
standards of research integrity as set out in the ALLEA European Code of Conduct for
|
||||
Research Integrity, as well as applicable international and national law, including the
|
||||
Charter of Fundamental Rights of the European Union and the European Convention on
|
||||
Human Rights and its Supplementary Protocols).</p>
|
||||
<p>Appropriate procedures, policies and
|
||||
structures are in place to foster responsible research practices, to
|
||||
prevent questionable research practices and research misconduct, and to
|
||||
handle allegations of breaches of the principles and standards in the Code of Conduct.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cols-2 left noflex">
|
||||
<input eiccheckbox class="required" type="checkbox" name="exclusiveCivilApplications" data-path="declarations" data-type="ignore" value="true" />
|
||||
<div>
|
||||
We declare that the proposal has an exclusive focus on civil applications (activities
|
||||
intended to be used in military application or aiming to serve military purposes
|
||||
cannot be funded). If the project involves dual-use items in the sense of Regulation
|
||||
2021/821, or other items for which authorisation is required, we confirm that we will
|
||||
comply with the applicable regulatory framework (e.g. obtain export/import licences
|
||||
before these items are used).
|
||||
</div>
|
||||
</div>
|
||||
<div class="cols-2 left noflex">
|
||||
<input eiccheckbox class="required" type="checkbox" name="complyGeneticsRegulations" data-path="declarations" data-type="ignore" value="true" />
|
||||
<div>
|
||||
We confirm that the activities proposed do not
|
||||
<ul bulleted>
|
||||
<li>aim at human cloning for reproductive purposes;</li>
|
||||
<li>
|
||||
intend to modify the genetic heritage of human beings which could make such changes
|
||||
heritable (with the exception of research relating to cancer treatment of the gonads,
|
||||
which may be financed), or
|
||||
</li>
|
||||
<li>
|
||||
intend to create human embryos solely for the purpose of research or for the purpose of
|
||||
stem cell procurement, including by means of somatic cell nuclear transfer.
|
||||
</li>
|
||||
<li>lead to the destruction of human embryos (for example, for obtaining stem cells) These activities are excluded from funding.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cols-2 left noflex">
|
||||
<input eiccheckbox class="required" type="checkbox" name="complyLegalObligations" data-path="declarations" data-type="ignore" value="true" />
|
||||
<div>
|
||||
We confirm that for activities carried out outside the Union, the same activities would
|
||||
have been allowed in at least one EU Member State
|
||||
</div>
|
||||
</div>
|
||||
<hr/>
|
||||
</div>
|
||||
|
||||
<div class="submitting">
|
||||
<div eicalert info>
|
||||
Please note that only one Submission form can be submitted per Participant Identification Code
|
||||
(PIC). You will therefore not be able to submit another proposal with the same Participant
|
||||
Identification Code (PIC).
|
||||
</div>
|
||||
<div eicalert danger class="incomplete">Your form still contains some issues preventing submission</div>
|
||||
<div class="cols-1 center ">
|
||||
<button eicbutton large disabled success class="submit">Submit my proposal</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- For Mike: disabled after Val tickets from confused users & discussion with Mikekel.
|
||||
Nobody knows for sure if it was a temp msg from the release before (when we couldn't show ESRs) and can be kicked now,
|
||||
Or if it should stay and be workflow-related ? Because for now it shows when it shouldn't.
|
||||
=> Possible side-effect of some ui.show(this.find('.evaluation')) because class ".evaluation" used in different places
|
||||
|
||||
Consensus is to kick it for now.
|
||||
|
||||
<div class="cols-1 center evaluation">
|
||||
Evaluation report will be available soon
|
||||
</div>
|
||||
|
||||
-->
|
||||
@@ -0,0 +1,44 @@
|
||||
class SubmissionShortForm2023DisclaimerView extends SubmissionShortFormTabView {
|
||||
|
||||
setupRules() {
|
||||
if(this.model.data.resubmitted) {
|
||||
ui.show(this.find('.resubmission'));
|
||||
this.find('h2').innerHTML = 'Resubmission';
|
||||
this.find('textarea[name="changes"]').classList.add('required');
|
||||
this.find('textarea[name="changes"]').setAttribute('data-type', 'text');
|
||||
this.find('textarea[name="rebuttal"]').classList.add('required');
|
||||
this.find('textarea[name="rebuttal"]').setAttribute('data-type', 'text');
|
||||
|
||||
} else {
|
||||
ui.hide(this.find('.resubmission'));
|
||||
this.find('h2').innerHTML = 'Submission';
|
||||
this.find('textarea[name="changes"]').classList.remove('required');
|
||||
this.find('textarea[name="changes"]').setAttribute('data-type', 'ignore');
|
||||
this.find('textarea[name="rebuttal"]').classList.remove('required');
|
||||
this.find('textarea[name="rebuttal"]').setAttribute('data-type', 'ignore');
|
||||
}
|
||||
|
||||
this.submit = this.components.find(item => item.el.classList.contains('submit'));
|
||||
this.submit.addEventListener('click', this.onSubmit.bind(this))
|
||||
}
|
||||
|
||||
fill(mode) {
|
||||
super.fill(mode);
|
||||
|
||||
if(this.mode == 'edit') ui.show(this.find('.submitting'));
|
||||
}
|
||||
|
||||
switchSubmit(hasIssues) {
|
||||
if(hasIssues) {
|
||||
ui.show(this.find('.incomplete'))
|
||||
this.submit.disabled = true;
|
||||
} else {
|
||||
this.submit.disabled = false;
|
||||
ui.hide(this.find('.incomplete'))
|
||||
}
|
||||
}
|
||||
|
||||
async onSubmit(event) { this.el.dispatchEvent(new Event('submit')); }
|
||||
}
|
||||
|
||||
app.registerClass('SubmissionShortForm2023DisclaimerView', SubmissionShortForm2023DisclaimerView);
|
||||
@@ -0,0 +1,72 @@
|
||||
<style>
|
||||
.short-form [data-part="documents"] embed.EmbedDocument {
|
||||
min-height: 50vw;
|
||||
display: none;
|
||||
width: 100%;
|
||||
}
|
||||
.short-form [data-part="documents"] embed.EmbedVideo {
|
||||
min-height: 20vw;
|
||||
display: none;
|
||||
}
|
||||
.documentFiles {
|
||||
grid-template-rows: 1fr;
|
||||
}
|
||||
.documentFiles .deck, .documentFiles .video {
|
||||
min-height: 8vw;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
|
||||
<h2>Supporting documents</h2>
|
||||
|
||||
<div class="documentFiles cols-2">
|
||||
<input eicinput type="hidden" name="pitchName" data-path="documents.pitchDeck" value="" class="required" />
|
||||
<input eicinput type="hidden" name="fileName" data-path="documents.pitchDeck" value="" class="required" />
|
||||
<input eicinput type="hidden" name="pitchName" data-path="documents.pitchVideo" value="" class="required" />
|
||||
<input eicinput type="hidden" name="fileName" data-path="documents.pitchVideo" value="" class="required" />
|
||||
<article eiccard class="deck">
|
||||
<header>
|
||||
<h1>Pitch Deck</h1>
|
||||
</header>
|
||||
<section>
|
||||
<p>Make sure your pitch summarises your proposal, but more importantly, engage us with your story! Convey your message in a compelling manner and persuade us to support your innovative idea.
|
||||
(It should be provided in PDF and not exceed 10 pages)</p>
|
||||
<p>Be assured you will have the opportunity to upload the latest version of your pitch as part of the full (step 2) proposal.</p>
|
||||
<div eicalert danger>The file is missing.</div>
|
||||
<button eicbutton primary rounded small class="view-pdf" icon="icon-pdf"></button>
|
||||
</section>
|
||||
<footer>
|
||||
<button eicbutton primary small class="upload-pdf"></button>
|
||||
</footer>
|
||||
</article>
|
||||
<article eiccard class="video">
|
||||
<header>
|
||||
<h1>Pitch Video</h1>
|
||||
</header>
|
||||
<section>
|
||||
<p>Describe your company and your project in a 3 minutes video with up to 3 team members</p>
|
||||
<div eicalert danger class="missing">The file is missing.</div>
|
||||
<div eicalert warning class="notready">
|
||||
Your video has been uploaded and is being converted.
|
||||
This process can take a few minutes.
|
||||
You'll be able to view it once the conversion is complete.
|
||||
In order to be able to submit your proposal, you video must be converted.
|
||||
</div>
|
||||
<div eicalert danger class="convert-error">
|
||||
Your video could not be converted.
|
||||
This can be due to unsupported codecs.
|
||||
Please retry using a different format / encoding.
|
||||
</div>
|
||||
<button eicbutton primary rounded small class="view-video" icon="icon-youtube"></button>
|
||||
</section>
|
||||
<footer>
|
||||
<button eicbutton primary small class="upload-video"></button>
|
||||
</footer>
|
||||
</article>
|
||||
</div>
|
||||
<embed type="application/pdf" class="EmbedDocument" src=""/>
|
||||
<div class="videoStage">
|
||||
<video id="video" width="100%" controls autoplay class="EmbedVideo"></video>
|
||||
<div eicalert warning class="noStreamingWarn">Looks like your browser does not support video streaming.</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,314 @@
|
||||
class SubmissionShortForm2023DocumentsView extends SubmissionShortFormTabView {
|
||||
|
||||
options = {
|
||||
mode: 'read',
|
||||
conversionCheckDelay: 10 // seconds between each conversion check
|
||||
}
|
||||
setupRules() {
|
||||
|
||||
this.AwsDownload = new AwsFileDownload({
|
||||
pdf : { url: app.config.api['/S3Files'].viewDocument.uri,
|
||||
method: app.config.api['/S3Files'].viewDocument.method,
|
||||
headers: { 'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
credentials: 'include'
|
||||
},
|
||||
})
|
||||
|
||||
this.embedDocument = this.find('.EmbedDocument')
|
||||
this.videoStage = this.find('.videoStage')
|
||||
this.embedVideo = this.find('.EmbedVideo')
|
||||
this.noStreamingWarn = this.find('.noStreamingWarn')
|
||||
|
||||
// Tri-state: false = not yet or we don't know, true => converted,
|
||||
// 'error' => conversion crash => show bad format msg, stop checking.
|
||||
this.videoConverted = false
|
||||
|
||||
this.pdfViewButton = this.components.find(o => o.el.classList.contains('view-pdf'));
|
||||
this.pdfViewButton.el.addEventListener('click', this.showPdf.bind(this))
|
||||
this.pdfUploadButton = this.components.find(o => o.el.classList.contains('upload-pdf'));
|
||||
this.pdfUploadButton.el.addEventListener('click', this.uploadPdf.bind(this))
|
||||
|
||||
this.videoViewButton = this.components.find(o => o.el.classList.contains('view-video'));
|
||||
this.videoViewButton.el.addEventListener('click', this.showVideo.bind(this))
|
||||
this.videoUploadButton = this.components.find(o => o.el.classList.contains('upload-video'));
|
||||
this.videoUploadButton.el.addEventListener('click', this.uploadVideo.bind(this))
|
||||
}
|
||||
|
||||
DOMContentRemoved() { this.stopCheckVideoConvertion(); }
|
||||
|
||||
validate() {
|
||||
let report = { valid: true, issues:0}
|
||||
if(this.find('[name="pitchName"][data-path="documents.pitchDeck"]').value == '') {
|
||||
report.valid = false
|
||||
report.issues ++
|
||||
ui.show(this.find('.deck [eicalert]'))
|
||||
} else ui.hide(this.find('.deck [eicalert]'))
|
||||
|
||||
if(this.find('[name="pitchName"][data-path="documents.pitchVideo"]').value == '') {
|
||||
report.valid = false
|
||||
report.issues ++
|
||||
ui.show(this.find('.video [eicalert].missing'))
|
||||
} else ui.hide(this.find('.video [eicalert].missing'))
|
||||
|
||||
if(this.videoConverted!=true) {
|
||||
report.valid = false
|
||||
report.issues ++
|
||||
}
|
||||
|
||||
return(report)
|
||||
}
|
||||
|
||||
fill(mode) {
|
||||
|
||||
super.fill(mode);
|
||||
|
||||
this.findAll('[eicalert]').forEach(element => { ui.hide(element) });
|
||||
ui.hide(this.videoStage);
|
||||
ui.hide(this.embedDocument);
|
||||
ui.hide(this.noStreamingWarn);
|
||||
|
||||
//Temporary => change checkconverted mechanics for rel4
|
||||
ui.hide(this.find('.video [eicalert].convert-error'));
|
||||
|
||||
this.hasPitchDeck = this.model.data.documents.pitchDeck &&
|
||||
this.model.data.documents.pitchDeck.fileName &&
|
||||
this.model.data.documents.pitchDeck.pitchName
|
||||
|
||||
this.hasPitchVideo = this.model.data.documents.pitchVideo &&
|
||||
this.model.data.documents.pitchVideo.fileName &&
|
||||
this.model.data.documents.pitchVideo.pitchName
|
||||
|
||||
if(this.hasPitchVideo) this.checkVideoConvertion();
|
||||
|
||||
this.refreshButtons();
|
||||
}
|
||||
|
||||
refreshButtons() {
|
||||
if(this.hasPitchDeck) {
|
||||
ui.show(this.pdfViewButton.el);
|
||||
this.pdfViewButton.label = this.model.data.documents.pitchDeck.pitchName;
|
||||
} else {
|
||||
ui.hide(this.pdfViewButton.el);
|
||||
}
|
||||
|
||||
if(this.hasPitchVideo) {
|
||||
ui.show(this.videoViewButton.el);
|
||||
this.videoViewButton.disabled = false;
|
||||
this.videoViewButton.label = this.model.data.documents.pitchVideo.pitchName;
|
||||
|
||||
if(this.videoConverted==false) { // don't know or not converted
|
||||
this.startCheckVideoConvertion()
|
||||
this.videoViewButton.disabled = true
|
||||
ui.show(this.find('.video [eicalert].notready'))
|
||||
ui.hide(this.find('.video [eicalert].convert-error'))
|
||||
} else if(this.videoConverted=='error') { // conversion crash
|
||||
this.stopCheckVideoConvertion()
|
||||
ui.show(this.find('.video [eicalert].convert-error'))
|
||||
ui.hide(this.find('.video [eicalert].notready'))
|
||||
} else { // conversion success
|
||||
ui.hide(this.find('.video [eicalert].notready'))
|
||||
ui.hide(this.find('.video [eicalert].convert-error'))
|
||||
}
|
||||
|
||||
} else {
|
||||
this.stopCheckVideoConvertion();
|
||||
ui.hide(this.videoViewButton.el);
|
||||
}
|
||||
|
||||
switch(this.mode) {
|
||||
case 'read':
|
||||
ui.hide(this.find('.deck footer'))
|
||||
ui.hide(this.find('.video footer'))
|
||||
break;
|
||||
case 'edit':
|
||||
ui.show(this.find('.deck footer'))
|
||||
this.pdfUploadButton.label = this.hasPitchDeck ? 'replace document' : 'Upload document'
|
||||
this.pdfUploadButton.hint = this.hasPitchDeck ? 'Replace the current PDF document by a new version' : 'Upload your PDF document'
|
||||
ui.show(this.find('.video footer'))
|
||||
this.videoUploadButton.label = this.hasPitchVideo ? 'replace video': 'upload video';
|
||||
this.videoUploadButton.hint = this.hasPitchVideo ? 'Replace the current video by a new version' : 'Upload your video';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
startCheckVideoConvertion() {
|
||||
if((this.videoConverted==true) || this.checkVideoConvertTO) return;
|
||||
this.checkVideoConvertTO = setTimeout(this.checkVideoConvertion.bind(this), 1000 * this.options.conversionCheckDelay)
|
||||
}
|
||||
|
||||
stopCheckVideoConvertion() {
|
||||
clearTimeout(this.checkVideoConvertTO)
|
||||
this.checkVideoConvertTO = null;
|
||||
}
|
||||
|
||||
reStartCheckVideoConvertion() {
|
||||
this.stopCheckVideoConvertion()
|
||||
this.startCheckVideoConvertion()
|
||||
}
|
||||
|
||||
checkVideoConvertion() {
|
||||
fetch(app.config.api['/S3Files'].checkVideoConversion.uri+'?'+crypto.randomUUID(),{
|
||||
method: app.config.api['/S3Files'].checkVideoConversion.method,
|
||||
body: `{ "fileName" : "${this.model.data.documents.pitchVideo.fileName}" }`,
|
||||
credentials: 'include'
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(resp => {
|
||||
if(resp.payload.conversionStatus == 'COMPLETE') this.videoConverted = true
|
||||
else if(resp.payload.conversionStatus == 'ERROR') this.videoConverted = 'error'
|
||||
else this.videoConverted = false
|
||||
|
||||
if((this.videoConverted==true) || (this.videoConverted == 'error')) {
|
||||
this.refreshButtons();
|
||||
this.stopCheckVideoConvertion()
|
||||
} else {
|
||||
this.reStartCheckVideoConvertion()
|
||||
}
|
||||
},
|
||||
err => {
|
||||
// Checking a file that exists in ML, but not on S3 makes a 404, which arrives here (but could also be any Lambda crash of course)
|
||||
// Do as if we don't know, continue checking (there are often recoverable Lambda crashes).
|
||||
// Maybe in the future : if(err.code==404) => switch back to the 'error' mechanism ?
|
||||
this.videoConverted = false
|
||||
this.reStartCheckVideoConvertion()
|
||||
this.refreshButtons();
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
async showPdf(event) {
|
||||
if(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
if(this.hls && this.embedVideo) {
|
||||
this.embedVideo.pause();
|
||||
this.hls.stopLoad()
|
||||
this.hls.detachMedia()
|
||||
this.hls.destroy()
|
||||
}
|
||||
this.pdfViewButton.loading = true
|
||||
let awsUrl = await this.AwsDownload.getDownloadUrl('pdf', this.model.data.documents.pitchDeck.fileName)
|
||||
this.pdfViewButton.loading = false
|
||||
if(!awsUrl) return
|
||||
ui.hide(this.videoStage)
|
||||
|
||||
// Safari workaround : You can't just replace the src like with every other browser,
|
||||
// you need to create a new embed node with the src already in.
|
||||
let clone = this.embedDocument.cloneNode()
|
||||
clone.setAttribute('src',awsUrl)
|
||||
this.embedDocument.replaceWith(clone)
|
||||
this.embedDocument=clone
|
||||
ui.show(this.embedDocument)
|
||||
}
|
||||
|
||||
async showVideo(event) {
|
||||
if(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
}
|
||||
ui.show(this.videoStage);
|
||||
ui.hide(this.embedDocument);
|
||||
if(!Hls.isSupported()) {
|
||||
ui.show(this.noStreamingWarn);
|
||||
return
|
||||
}
|
||||
ui.hide(this.noStreamingWarn);
|
||||
let noextName = this.model.data.documents.pitchVideo.fileName.substr(0,this.model.data.documents.pitchVideo.fileName.lastIndexOf('.'))
|
||||
let videoUrl = app.config.api['/S3Files'].viewVideo.uri+`${noextName}.m3u8`
|
||||
let config = {
|
||||
debug: false,
|
||||
xhrSetup: function (xhr,url) {
|
||||
xhr.withCredentials = true; // do send cookie
|
||||
}
|
||||
};
|
||||
this.hls = new Hls(config);
|
||||
this.hls.loadSource(videoUrl)
|
||||
this.hls.attachMedia(this.embedVideo);
|
||||
this.hls.on(Hls.Events.MANIFEST_PARSED,(() => {
|
||||
this.embedVideo.play();
|
||||
}).bind(this));
|
||||
}
|
||||
|
||||
async uploadPdf(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
let filename = this.hasPitchDeck ? this.model.data.documents.pitchDeck.fileName: '';
|
||||
|
||||
let result = await this.openDialog(
|
||||
await this.loadContent(
|
||||
'projects/submissions/dialogs/SubmissionFormUploadDialog',
|
||||
{ title: 'Upload a pitch deck PDF...' },
|
||||
{ filename: filename,
|
||||
pic: this.model.data.organisation.pic,
|
||||
pid: this.model.data.proposal.number,
|
||||
allowedExtensions: ['pdf'],
|
||||
allowedMimes: ['application/pdf'],
|
||||
getSignedUrl : app.config.api['/S3Files'].uploadPdf.getSignedUrl,
|
||||
getSignedMethod : app.config.api['/S3Files'].uploadPdf.getSignedMethod,
|
||||
uploadUrl : app.config.api['/S3Files'].uploadPdf.uploadUrl,
|
||||
uploadMethod : app.config.api['/S3Files'].uploadPdf.uploadMethod,
|
||||
message: 'Drop your pitch deck PDF here !',
|
||||
}
|
||||
)
|
||||
);
|
||||
if(result) {
|
||||
this.find('[name="pitchName"][data-path="documents.pitchDeck"]').value = result.pitchName
|
||||
this.find('[name="fileName"][data-path="documents.pitchDeck"]').value = result.fileName
|
||||
this.model.data.documents.pitchDeck = {
|
||||
fileName : result.fileName,
|
||||
pitchName : result.pitchName
|
||||
}
|
||||
this.hasPitchDeck = true;
|
||||
this.refreshButtons()
|
||||
this.validate();
|
||||
this.el.dispatchEvent(new Event('save'))
|
||||
}
|
||||
}
|
||||
|
||||
async uploadVideo(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
let filename = this.hasPitchVideo ? this.model.data.documents.pitchVideo.fileName : '';
|
||||
|
||||
let result = await this.openDialog(
|
||||
await this.loadContent(
|
||||
'projects/submissions/dialogs/SubmissionFormUploadDialog',
|
||||
{ title: 'Upload a pitch video...' },
|
||||
{ filename: filename,
|
||||
pic: this.model.data.organisation.pic,
|
||||
pid: this.model.data.proposal.number,
|
||||
allowedExtensions: ['mp4', '3gp', 'mov', 'qt', 'avi', 'wmv', 'webm', '3g2', 'ogv', 'm4v'],
|
||||
allowedMimes: [ 'video/mp4', 'video/quicktime', 'video/3gpp', 'video/3gpp2', 'video/3gp2', 'video/x-msvideo', 'video/avi', 'video/x-ms-wmv',
|
||||
'video/webm', 'video/x-m4v'],
|
||||
getSignedUrl : app.config.api['/S3Files'].uploadVideo.getSignedUrl,
|
||||
getSignedMethod : app.config.api['/S3Files'].uploadVideo.getSignedMethod,
|
||||
uploadUrl : app.config.api['/S3Files'].uploadPdf.uploadUrl,
|
||||
uploadMethod : app.config.api['/S3Files'].uploadPdf.uploadMethod,
|
||||
message: 'Drop your pitch video here !'
|
||||
}
|
||||
)
|
||||
);
|
||||
if(result) {
|
||||
this.find('[name="pitchName"][data-path="documents.pitchVideo"]').value = result.pitchName
|
||||
this.find('[name="fileName"][data-path="documents.pitchVideo"]').value = result.fileName
|
||||
this.model.data.documents.pitchVideo = {
|
||||
fileName : result.fileName,
|
||||
pitchName : result.pitchName
|
||||
}
|
||||
this.hasPitchVideo = true;
|
||||
this.videoConverted = false;
|
||||
this.startCheckVideoConvertion();
|
||||
this.refreshButtons();
|
||||
this.validate();
|
||||
this.el.dispatchEvent(new Event('save'))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
app.registerClass('SubmissionShortForm2023DocumentsView', SubmissionShortForm2023DocumentsView);
|
||||
@@ -0,0 +1,33 @@
|
||||
<h2>Funding request</h2>
|
||||
<div>
|
||||
<label>Please indicate which EIC Support you intend to request</label>
|
||||
<select eicselect name="budgetType" data-path="funding" data-type="text" class="required">
|
||||
<option value=""></option>
|
||||
<option value="0">Blended Finance</option>
|
||||
<option value="1">Grant First</option>
|
||||
<option value="2">Grant Only</option>
|
||||
<option value="3">I don't know yet</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label>Total cost (up to TRL 8)</label>
|
||||
<input eicinput type="currency" name="totalCost" data-path="funding" data-type="text" min="0" class="required" />
|
||||
</div>
|
||||
<div>
|
||||
<label>Grant amount requested from EIC (maximum 70% of total cost and less than 2.5M€)</label>
|
||||
<input eicinput type="currency" name="requestedAmount" data-path="funding" data-type="text" min="2" max="2499999" class="required" />
|
||||
<div eicalert info>This amount is purely indicative and does not represent any obligation.</div>
|
||||
</div>
|
||||
<div>
|
||||
<label>Grant amount from other funding sources</label>
|
||||
<input eicinput type="currency" name="otherFunding" data-path="funding" data-type="ignore" disabled />
|
||||
<div eicalert info>This amount is the funding not covered by the EIC</div>
|
||||
</div>
|
||||
<div>
|
||||
<label>Investment amount requested from EIC ( From 500 000 euros up to 15 000 000 euros)</label>
|
||||
<input eicinput type="currency" name="InvestmentAmount" data-path="funding" data-type="text" min="500000" max="15000000" class="required" />
|
||||
</div>
|
||||
<div>
|
||||
<label>Describe your financial needs for grants and investment, explain why you have not been able to raise sufficient investment to carry out the project, and why you need the support of the EIC. Please note that the figures are indicative at this stage, and you will have the possibility to modify this within your full (step 2) proposal.</label>
|
||||
<textarea eictextarea name="needs" data-path="funding" data-type="text" maxlen="10000" class="required"></textarea>
|
||||
</div>
|
||||
@@ -0,0 +1,125 @@
|
||||
class SubmissionShortForm2023FundingView extends SubmissionShortFormTabView {
|
||||
|
||||
setupRules() {
|
||||
|
||||
this.totalCost = this.find('[name="totalCost"]');
|
||||
this.requestedAmount = this.find('[name="requestedAmount"]');
|
||||
this.otherFunding = this.find('[name="otherFunding"]');
|
||||
this.InvestmentAmount = this.find('[name="InvestmentAmount"]');
|
||||
|
||||
this.type = this.find('[name="budgetType"]');
|
||||
this.type.addEventListener('change', this.onTypeChange.bind(this));
|
||||
|
||||
this.total = this.find('[name="totalCost"]');
|
||||
this.invest = this.find('[name="InvestmentAmount"]');
|
||||
this.other = this.find('[name="otherFunding"]');
|
||||
this.requested = this.find('[name="requestedAmount"]');
|
||||
this.total.addEventListener('change', this.onTotalChange.bind(this));
|
||||
this.requested.addEventListener('change', this.onRequestedChange.bind(this));
|
||||
this.invest.addEventListener('change', this.onInvestChange.bind(this));
|
||||
|
||||
this.type.value = "";
|
||||
this.onTypeChange();
|
||||
}
|
||||
|
||||
fill(mode) {
|
||||
super.fill(mode);
|
||||
|
||||
this.maxRequested = Math.floor(Math.min(parseInt(this.total.value) * 0.7, 2499999));
|
||||
this.other.value = parseInt(this.total.value) - parseInt(this.requested.value);
|
||||
|
||||
this.other.disabled = true;
|
||||
|
||||
}
|
||||
|
||||
onTotalChange(event) {
|
||||
if(this.total.min && (parseInt(this.total.value) < this.total.min))
|
||||
this.total.value = this.total.min;
|
||||
|
||||
if(this.total.max && (parseInt(this.total.value) > this.total.max))
|
||||
this.total.value = this.total.max;
|
||||
|
||||
this.maxRequested = Math.floor(Math.min(parseInt(this.total.value) * 0.7, 2499999));
|
||||
|
||||
if(parseInt(this.requested.value) >= this.maxRequested) {
|
||||
this.requested.value = Math.floor(this.maxRequested);
|
||||
this.requested.max = this.maxRequested;
|
||||
}
|
||||
this.onRequestedChange(event);
|
||||
|
||||
this.other.value = parseInt(this.total.value) - parseInt(this.requested.value);
|
||||
}
|
||||
|
||||
onRequestedChange(event) {
|
||||
if(parseInt(this.requested.value) < this.requested.min)
|
||||
this.requested.value = this.requested.min;
|
||||
|
||||
if(parseInt(this.requested.value) > this.maxRequested) {
|
||||
this.requested.value = Math.floor(this.maxRequested);
|
||||
this.requested.max = this.maxRequested;
|
||||
}
|
||||
|
||||
this.other.value = parseInt(this.total.value) - parseInt(this.requested.value);
|
||||
}
|
||||
|
||||
onInvestChange(event) {
|
||||
if(parseInt(this.invest.value) > 15000000) this.invest.value = 15000000;
|
||||
if(parseInt(this.invest.value) < 500000) this.invest.value = 500000;
|
||||
}
|
||||
|
||||
onTypeChange(event) {
|
||||
if(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
let value = '';
|
||||
let option = this.type.querySelector('option[selected="selected"], option[selected]') // Safari shit
|
||||
if(option) value = option.value
|
||||
switch(value) {
|
||||
case '':
|
||||
ui.hide(this.totalCost.parentElement.parentElement);
|
||||
this.totalCost.classList.remove('required');
|
||||
ui.hide(this.requestedAmount.parentElement.parentElement);
|
||||
this.requestedAmount.classList.remove('required');
|
||||
ui.hide(this.otherFunding.parentElement.parentElement);
|
||||
ui.hide(this.InvestmentAmount.parentElement.parentElement);
|
||||
this.InvestmentAmount.classList.remove('required');
|
||||
|
||||
break;
|
||||
case '0':
|
||||
ui.show(this.totalCost.parentElement.parentElement);
|
||||
this.totalCost.classList.add('required');
|
||||
ui.show(this.requestedAmount.parentElement.parentElement);
|
||||
this.requestedAmount.classList.add('required');
|
||||
ui.show(this.otherFunding.parentElement.parentElement);
|
||||
ui.show(this.InvestmentAmount.parentElement.parentElement);
|
||||
this.InvestmentAmount.classList.add('required');
|
||||
|
||||
break;
|
||||
case '1':
|
||||
case '2':
|
||||
ui.show(this.totalCost.parentElement.parentElement);
|
||||
this.totalCost.classList.add('required');
|
||||
ui.show(this.requestedAmount.parentElement.parentElement);
|
||||
this.requestedAmount.classList.add('required');
|
||||
ui.show(this.otherFunding.parentElement.parentElement);
|
||||
ui.hide(this.InvestmentAmount.parentElement.parentElement);
|
||||
this.InvestmentAmount.classList.remove('required');
|
||||
|
||||
break;
|
||||
case '3':
|
||||
ui.hide(this.totalCost.parentElement.parentElement);
|
||||
this.totalCost.classList.remove('required');
|
||||
ui.hide(this.requestedAmount.parentElement.parentElement);
|
||||
this.requestedAmount.classList.remove('required');
|
||||
ui.hide(this.otherFunding.parentElement.parentElement);
|
||||
ui.hide(this.InvestmentAmount.parentElement.parentElement);
|
||||
this.InvestmentAmount.classList.remove('required');
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
app.registerClass('SubmissionShortForm2023FundingView', SubmissionShortForm2023FundingView);
|
||||
@@ -0,0 +1,60 @@
|
||||
<h2>General Information</h2>
|
||||
<div class="cols-2 left">
|
||||
<div>
|
||||
<label>Proposal Number</label>
|
||||
<input eicinput disabled name="number" data-path="proposal" data-type="text" />
|
||||
</div>
|
||||
<div>
|
||||
<label>Acronym</label>
|
||||
<input eicinput name="acronym" data-path="proposal" data-type="text" maxlen="50" class="required" />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label>Full Title</label>
|
||||
<input eicinput name="title" data-path="proposal" data-type="text" maxlen="200" class="required" />
|
||||
</div>
|
||||
<div>
|
||||
<label>Abstract</label>
|
||||
<textarea eictextarea name="abstract" data-path="proposal" data-type="text" maxlen="1000" class="required"></textarea>
|
||||
</div>
|
||||
<div>
|
||||
<label>Estimated duration of the project (in months)</label>
|
||||
<input eicinput type="number" name="estimatedDuration" data-path="proposal" data-type="number" min="1" max="60" class="required" />
|
||||
</div>
|
||||
<div>
|
||||
<label>Could you estimate the current TRL of your project ?</label>
|
||||
<select eicselect name="estimatedTRL" data-path="proposal" data-type="number" class="required">
|
||||
<option></option>
|
||||
<option value="1"><span><h5>TRL1: Basic Research</h5>Basic principles observed </span></option>
|
||||
<option value="2"><span><h5>TRL2: Technology Formulation</h5>Technology concept formulated </span></option>
|
||||
<option value="3"><span><h5>TRL3: Needs Validation</h5>Experimental proof of concept</span></option>
|
||||
<option value="4"><span><h5>TRL4: Small Scale Prototype</h5>Technology validated in lab</span></option>
|
||||
<option value="5"><span><h5>TRL5: Large Scale Prototype</h5>Technology validated in relevant environment (industrially relevant environment in the case of key enabling technologies) </span></option>
|
||||
<option value="6"><span><h5>TRL6: Prototype System</h5>Technology demonstrated in relevant environment (industrially relevant environment in the case of key enabling technologies) </span></option>
|
||||
<option value="7"><span><h5>TRL7: Demonstration System</h5>System prototype demonstration in operational environment </span></option>
|
||||
<option value="8"><span><h5>TRL8: First Of A Kind Commercial System</h5>System complete and qualified </span></option>
|
||||
<option value="9"><span><h5>TRL9: Full Commercial Application</h5>Actual system proven in operational environment (competitive manufacturing in the case of key enabling technologies; or in space) </span></option>
|
||||
</select>
|
||||
</div>
|
||||
<div><label>Relevant keywords for the proposal</label></div>
|
||||
<div class="cols-3">
|
||||
<div>
|
||||
<label>1st Keyword</label>
|
||||
<select eicselect name="keyword1Code" lookup data-path="proposal" data-type="array" class="required">
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label>2nd Keyword</label>
|
||||
<select eicselect name="keyword2Code" lookup data-path="proposal" data-type="array" class="required">
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label>3rd Keyword</label>
|
||||
<select eicselect name="keyword3Code" lookup data-path="proposal" data-type="array" class="required">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label>Additional free keywords</label>
|
||||
<select eicselect name="freeKeywords" editable data-path="proposal" data-type="array" class="" placeholder="Type in your keyword and press enter" />
|
||||
</div>
|
||||
@@ -0,0 +1,31 @@
|
||||
class SubmissionShortForm2023GeneralView extends SubmissionShortFormTabView {
|
||||
|
||||
setupRules() {
|
||||
this.find('[name="estimatedDuration"]').addEventListener('keypress', this.onDurationCheck.bind(this))
|
||||
}
|
||||
|
||||
fill(mode) {
|
||||
let keywords = [];
|
||||
|
||||
keywords = app.meta.toOptions('eic-keywords', null, true);
|
||||
keywords.forEach(item => this.find('select[name="keyword1Code"]').append(item));
|
||||
|
||||
keywords = app.meta.toOptions('eic-keywords', null, true);
|
||||
keywords.forEach(item => this.find('select[name="keyword2Code"]').append(item));
|
||||
|
||||
keywords = app.meta.toOptions('eic-keywords', null, true);
|
||||
keywords.forEach(item => this.find('select[name="keyword3Code"]').append(item));
|
||||
|
||||
super.fill(mode);
|
||||
|
||||
this.find('[name="number"]').setAttribute('disabled', '');
|
||||
|
||||
}
|
||||
|
||||
onDurationCheck(event) {
|
||||
if(!(/^[0-9]$/i.test(event.key))) event.preventDefault();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
app.registerClass('SubmissionShortForm2023GeneralView', SubmissionShortForm2023GeneralView);
|
||||
@@ -0,0 +1,5 @@
|
||||
<h2>Broad impacts</h2>
|
||||
<div>
|
||||
<label>Describe and quantify, if possible, the broad expected impact of your innovation on society, the environment and climate, the UN Sustainable Development Goals and on job creation. Refer to any relevant EU policy. </label>
|
||||
<textarea eictextarea name="impacts" data-path="narrative" data-type="text" maxlen="10000" class="required"></textarea>
|
||||
</div>
|
||||
@@ -0,0 +1,6 @@
|
||||
class SubmissionShortForm2023ImpactView extends SubmissionShortFormTabView {
|
||||
|
||||
setupRules() {}
|
||||
}
|
||||
|
||||
app.registerClass('SubmissionShortForm2023ImpactView', SubmissionShortForm2023ImpactView);
|
||||
@@ -0,0 +1,5 @@
|
||||
<h2>The problem/market opportunity</h2>
|
||||
<div>
|
||||
<label>Describe the problem you are trying to address from the customer/user point of view.</label>
|
||||
<textarea eictextarea name="opportunity" data-path="narrative" data-type="text" maxlen="5000" class="required"></textarea>
|
||||
</div>
|
||||
@@ -0,0 +1,6 @@
|
||||
class SubmissionShortForm2023ProblemView extends SubmissionShortFormTabView {
|
||||
|
||||
setupRules() {}
|
||||
}
|
||||
|
||||
app.registerClass('SubmissionShortForm2023ProblemView', SubmissionShortForm2023ProblemView);
|
||||
@@ -0,0 +1,5 @@
|
||||
<h2>The innovation: Solution/Product or Services (USP)</h2>
|
||||
<div>
|
||||
<label>Present the solution; explain how it works in practice, what it changes for potential users, the way(s) in which it is unique, why it has breakthrough potential, why it is better than existing solutions available on the market, explain concretely how you have achieved the current TRL level, and describe why now is the right time to bring it to the market.</label>
|
||||
<textarea eictextarea name="solution" data-path="narrative" data-type="text" maxlen="20000" class="required"></textarea>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
class SubmissionShortForm2023SolutionView extends SubmissionShortFormTabView {}
|
||||
|
||||
app.registerClass('SubmissionShortForm2023SolutionView', SubmissionShortForm2023SolutionView);
|
||||
@@ -0,0 +1,157 @@
|
||||
<h2>Submission status</h2>
|
||||
<div class="cols-1 withdrawing">
|
||||
<h5>Your proposal is on the way</h5>
|
||||
<div eicalert success>
|
||||
<p>We acknowledge the successful submission of your proposal on <span class="date"></span>. Thank you for taking the time to prepare and submit it to us.</p>
|
||||
<div class="cols-1 center"><button eicbutton primary class="view-pdf">View my proposal as PDF</button></div>
|
||||
</div>
|
||||
<p>At this stage, no further action is required from your side. Our team will now proceed with the evaluation process. Once the evaluation is completed, we will notify you about the outcome.</p>
|
||||
<h5>Withdrawing your proposal</h5>
|
||||
<p>If you choose to withdraw your proposal, it is taken out of the ongoing evaluation process without affecting the resubmission limits as per the current <a href="https://eic.ec.europa.eu/eic-2023-work-programme_en" target="_blank">EIC 2023 work programme</a>. As long as you remain eligible, you will still have the opportunity to resubmit another proposal in the future.</p>
|
||||
<div eicalert danger class="withdraw-confirm">
|
||||
<input eiccheckbox class="" type="checkbox" name="withdrawConfirmation" data-path="" data-type="ignore" value="true" label="Hereby, I confirm that I want to withdraw my proposal from the evaluation process" />
|
||||
</div>
|
||||
<div class="cols-1 center"><button eicbutton danger class="withdraw">Withdraw my proposal</button></div>
|
||||
<hr/>
|
||||
</div>
|
||||
<div class="withdrawn">
|
||||
<div eicalert warning>You withdrawn this proposal</div>
|
||||
<div class="cols-1 center">
|
||||
<button eicbutton primary class="clone1">Start over using this proposal</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cols-1 evaluation">
|
||||
|
||||
<div class="go">
|
||||
<div eicalert success>
|
||||
<h5>Congratulations! Your proposal has been evaluated</h5>
|
||||
<p>We are happy to inform you that your proposal submitted on <span class="date">${(new Date(model.data.updated.date)).toLocaleDateString("en-DE")}</span> has been awarded an overall GO by our experts.</p>
|
||||
<div class="cols-2">
|
||||
<button eicbutton class="view-submission-go" icon="icon-pdf"><span>Download the submission</span></button>
|
||||
<button eicbutton primary class="view-evaluation-go" icon="icon-pdf"><span>Download the evaluation</span></button>
|
||||
</div>
|
||||
</div>
|
||||
<p>You are on the eve of a new adventure. You now benefit of a new batch of services including:</p>
|
||||
<ul bulleted>
|
||||
<li>access to the full proposal submission (you have a full year to submit)</li>
|
||||
<li>3 days of coaching</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="no-go">
|
||||
<div eicalert danger>
|
||||
<p>We regret to inform you that your proposal submitted on <span class="date">${(new Date(model.data.updated.date)).toLocaleDateString("en-DE")}</span> has received an overall NO GO.</p>
|
||||
<div class="cols-2">
|
||||
<button eicbutton class="view-submission-no-go" icon="icon-pdf"><span>Download the submission</span></button>
|
||||
<button eicbutton primary class="view-evaluation-no-go" icon="icon-pdf"><span>Download the evaluation</span></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="first-submission">
|
||||
<!--
|
||||
<p>
|
||||
Please review the proposal evaluation comments as you will have the opportunity to rebut the experts' comments and summarise any changes made to the proposal, in the event that you decide to resubmit.
|
||||
Please note, that as per the <a href="https://ec.europa.eu/info/funding-tenders/opportunities/docs/2021-2027/horizon/wp-call/2023/wp_horizon-eic-2023_en.pdf" target="_blank" title="EIC Work Programme 2023">Work Programme 2023</a> (Table 8),
|
||||
applicants are limited to two unsuccessful attempts at this step, even if the innovations/ideas are different between attempts.
|
||||
You may start over with a blank template from scratch by returning to the dashboard and creating a new version or you can reuse this proposal as a basis for your next attempt.
|
||||
If you wish to reuse the proposal please click on the button below:
|
||||
</p>
|
||||
<div class="cols-1 center">
|
||||
<button eicbutton primary class="clone2">Start over using this proposal</button>
|
||||
</div>
|
||||
-->
|
||||
<p>Following the adoption of the new <a href="https://eic.ec.europa.eu/eic-2024-work-programme_en" target="_blank" title="EIC Work Programme 2024">EIC Work Programme 2024</a> you have 2 alternatives to resubmit your short proposal depending whether you do so in 2023 or in 2024.</p>
|
||||
<p><b>You intend to resubmit a short proposal in 2023</b></p>
|
||||
<p>You can still resubmit your short proposal under the <a href="https://eic.ec.europa.eu/system/files/2023-08/EIC-WP2023-amended.pdf" target="_blank" title="EIC Work Programme 2023">EIC Work Programme 2023</a> rules until <b>December 31st 2023 at 23:59 (GMT +1)</b>. In such a case, you have the possibility to modify your proposal to take into account experts' comments, where you see it fit directly on the current platform.</p>
|
||||
<p>You may start over with a blank template from scratch by returning to the dashboard and creating a new version or you can reuse this proposal as a basis for your next attempt. If you wish to reuse the proposal, please click on the button below.</p>
|
||||
<div class="cols-1 center">
|
||||
<button eicbutton primary class="clone2">Start over using this proposal</button>
|
||||
</div>
|
||||
<p><b>You intend to resubmit a short proposal in 2024</b></p>
|
||||
<p>Alternatively should you intend to resubmit your short proposal as of <b>January 3, 2024</b> you will have to do so via the <a href="https://ec.europa.eu/info/funding-tenders/opportunities/portal/screen/home" target="_blank" title="Horizon Europe Funding and Tenders Portal">Horizon Europe Funding and Tenders Portal</a> and in accordance with the rules of the newly adopted <a href="https://eic.ec.europa.eu/eic-2024-work-programme_en" target="_blank" title="EIC Work Programme 2024">EIC Work Programme 2024</a >, which comes into force on <b>January 1, 2024</b>.</p>
|
||||
<p>Please note that the templates and rules for the short proposal will change under the EIC Work Programme 2024. We invite you to read them carefully. </p>
|
||||
<p>To resubmit your proposal in 2024 please go <a href="https://ec.europa.eu/info/funding-tenders/opportunities/portal/screen/opportunities/topic-details/horizon-eic-2024-accelerator-01?tenders=false&openForSubmission=false&programmePeriod=2021%20-%202027&frameworkProgramme=43108390&programmePart=43121666&callIdentifier=HORIZON-EIC-2024-ACCELERATOR-01" target="_blank" title="Short proposals in SEP">here</a></p>
|
||||
|
||||
</div>
|
||||
<div class="second-submission">
|
||||
<div class="complaint">
|
||||
<!--
|
||||
<p>You may, until the <span class="limit"></span>, complain about the experts' "NO GO" recommendation of your Step1 short application on a limited number of grounds:</p>
|
||||
<ul bulleted>
|
||||
<li>A factual mistake of one or more experts. But remember that a fact is not an opinion.</li>
|
||||
<li>A manifest error of appreciation as to the purpose and scope of the Accelerator.
|
||||
E.g. considering that scaling-up an innovation already deployed means that it is not innovative anymore; considering a proposal as too risky; considering that since an innovation already exists outside the EU it should not be developed in the EU.
|
||||
</li>
|
||||
<li>Asking for detailed information or documents you were not deemed to submit at Step 1, but only later your Step 2 full application. Remember, you are still requested to provide sufficient information to enable evaluators to assess each criterion.
|
||||
E.g. asking for a detailed budget of the action
|
||||
</li>
|
||||
</ul>
|
||||
<p>These are very specific grounds. Be precise (which criteria, which expert(s), which ground(s)) and concise when filling this complaint form. Be straight to the point. A complaint only discussing experts’ opinions will not be taken into consideration.</p>
|
||||
<p>We will then let you know within 5 working days if your claim is rejected and the initial experts’ recommendation confirmed, or accepted. If accepted, we will send your complaint to the concerned experts, who will have 5 working days to assess it and deliver their final recommendation to the EIC, which will then be communicated to you.</p>
|
||||
<div class="cols-1 center">
|
||||
<button eicbutton danger class="complain">File a complaint</button>
|
||||
</div>
|
||||
-->
|
||||
<p>With the adoption of the <a href="https://eic.ec.europa.eu/eic-2024-work-programme_en" target="_blank" title="EIC Work Programme 2024">EIC Work Programme 2024</a> you are no longer barred to submit a short proposal for 12 months and you can start a new applicant as early as from <b>January 3, 2024</b>,
|
||||
via the <span ><a href="https://ec.europa.eu/info/funding-tenders/opportunities/portal/screen/home" target="_blank" title="Horizon Europe Funding and Tenders Portal">Horizon Europe Funding and Tenders Portal</a></span>. </p>
|
||||
<p>Please note that the templates and rules for the short proposal will change under the EIC Work Programme 2024. We invite you to read them carefully.</p>
|
||||
<p>To resubmit your proposal in 2024 please go <a href="https://ec.europa.eu/info/funding-tenders/opportunities/portal/screen/opportunities/topic-details/horizon-eic-2024-accelerator-01?tenders=false&openForSubmission=false&programmePeriod=2021%20-%202027&frameworkProgramme=43108390&programmePart=43121666&callIdentifier=HORIZON-EIC-2024-ACCELERATOR-01" target="_blank" title="Short proposals in SEP">here</a></p>
|
||||
</div>
|
||||
<div class="contested">
|
||||
<div eicalert warning>
|
||||
You filed a complaint about the evaluation. The issue of the complaint will be communicated soon.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cols-1 fast-track">
|
||||
<div eicalert success></div>
|
||||
<p>Your proposal is on the fast tracks</p>
|
||||
<p>
|
||||
We have the pleasure to inform you that you have been selected for the EIC Plug In / Fast track scheme.<br>
|
||||
You are now eligible to apply to the EIC Accelerator program and also benefit from coaching service.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cols-1 coaching">
|
||||
<h5>Coaching service</h5>
|
||||
<p>
|
||||
We encourage you to take advantage from 3 days of coaching to help improve your value proposition, business plan and investor pitch. The EIC offers you this service free of charge.<br>
|
||||
For more information visit
|
||||
<a href="https://eic.ec.europa.eu/eic-funding-opportunities/business-acceleration-services/coaching-under-eic_en" target="_blank" title="Coaching under the EIC">
|
||||
coaching under the EIC
|
||||
</a>.
|
||||
</p>
|
||||
</div>
|
||||
<div class="go-full">
|
||||
<h5>How to proceed to the Full Proposal?</h5>
|
||||
<p>Your next step is to submit a deeper detailed description of your proposal (known as the full proposal). </p>
|
||||
<!--<p>Details and submission links of the 2024 cut off dates will be provided once the EIC Work Programme 2024 has been adopted (indicatively in December).</p> -->
|
||||
<p>You may submit your full proposal for the EIC Accelerator Open and Challenge calls at a cut-off date of your choice via the specific links below on the Horizon Europe Funding and Tenders Opportunities Portal:</p>
|
||||
<ul bulleted>
|
||||
<li><a href="https://ec.europa.eu/research/participants/submission/manage/screen/submission/create-draft/39382?topic=HORIZON-EIC-2025-ACCELERATOR-02-OPEN-01" title="" target="_blank">HORIZON-EIC-2025-ACCELERATOR-02-OPEN-01</a></li>
|
||||
<li><a href="https://ec.europa.eu/research/participants/submission/manage/screen/submission/create-draft/39381?topic=HORIZON-EIC-2025-ACCELERATOR-02-CHALLENGES-01" title="" target="_blank">HORIZON-EIC-2025-ACCELERATOR-02-CHALLENGES-01- Acceleration of advanced materials development and upscaling along the value chain</a></li>
|
||||
<li><a href="https://ec.europa.eu/research/participants/submission/manage/screen/submission/create-draft/39381?topic=HORIZON-EIC-2025-ACCELERATOR-02-CHALLENGES-02" title="" target="_blank">HORIZON-EIC-2025-ACCELERATOR-02-CHALLENGES-02- Biotechnology driven low emission food and feed production systems</a></li>
|
||||
<li><a href="https://ec.europa.eu/research/participants/submission/manage/screen/submission/create-draft/39380?topic=HORIZON-EIC-2025-ACCELERATOR-02-CHALLENGES-03" title="" target="_blank">HORIZON-EIC-2025-ACCELERATOR-02-CHALLENGES-03- GenAI4EU: Creating European Champions in Generative AI</a></li>
|
||||
<li><a href="https://ec.europa.eu/research/participants/submission/manage/screen/submission/create-draft/39380?topic=HORIZON-EIC-2025-ACCELERATOR-02-CHALLENGES-04" title="" target="_blank">HORIZON-EIC-2025-ACCELERATOR-02-CHALLENGES-04- Innovative in-space servicing, operations, robotics and technologies for resilient EU space infrastructure</a></li>
|
||||
<li><a href="https://ec.europa.eu/research/participants/submission/manage/screen/submission/create-draft/39381?topic=HORIZON-EIC-2025-ACCELERATOR-02-CHALLENGES-05" title="" target="_blank">HORIZON-EIC-2025-ACCELERATOR-02-CHALLENGES-05- Breakthrough innovations for future mobility</a></li>
|
||||
</ul>
|
||||
<p>If your proposal fits into one of these Challenge calls, we highly encourage you to submit your proposal to the relevant challenge (rather than to the OPEN call). The Challenges have a significant budget earmarked for them, which can even be exceeded in case of many excellent proposals submitted to a given challenge. Your proposal will be evaluated by specific experts who are aware of the priority for these strategically important challenge areas. Proposals submitted to the Challenges and reaching the interview stage can also receive a <a href="https://strategic-technologies.europa.eu/investors_en" target="_blank">Sovereignty Seal</a>. And finally successful proposals submitted under the Challenges will benefit from specific support measures as part of a portfolio.</p>
|
||||
<p>For more information please see the specific descriptions of the <a href="https://eic.ec.europa.eu/document/download/5e1eb75f-e437-477f-9ee9-ef54ff6387fd_en?filename=EIC%20Work%20Programme%202025.pdf" target="_blank" title="Accelerator Challenges on pp. 79-95">Accelerator Challenges on pp. 81-95</a>, as well as the <a href="https://eic.ec.europa.eu/eic-funding-opportunities/eic-accelerator/eic-accelerator-challenges-2025_en" title="" target="_blank">presentations</a> and recordings of the <a href="https://eic.ec.europa.eu/events/european-innovation-council-online-info-day-work-programme-2025-2024-11-05_en" target="_blank" title="EIC Infoday">EIC Infoday</a> and specifically the <a href="https://eic.ec.europa.eu/events/european-innovation-council-accelerator-challenges-work-programme-2025-2024-11-06_en" target="_blank" title="Challenge Infoday">Challenge Infoday 2025</a>. Another important source of support for applicants are the <a href="https://ec.europa.eu/info/funding-tenders/opportunities/portal/screen/support/ncp;sortQuery=country;functions=13" target="_blank" title="National Contact Points">National Contact Points</a> for the EIC.</p>
|
||||
|
||||
<p>We advise you also to consult the following documents to assist your preparations for the next step of your application:</p>
|
||||
<ul bulleted>
|
||||
<li><a href="https://eic.ec.europa.eu/document/download/5e1eb75f-e437-477f-9ee9-ef54ff6387fd_en?filename=EIC%20Work%20Programme%202025.pdf" target="_blank" title="">EIC Work Programme 2025</a></li>
|
||||
<li><a href="https://ec.europa.eu/info/funding-tenders/opportunities/docs/2021-2027/horizon/guidance/programme-guide_horizon_en.pdf" target="_blank" title="">HE Programme Guide</a></li>
|
||||
<li><a href="https://ec.europa.eu/info/funding-tenders/opportunities/docs/2021-2027/common/agr-contr/general-mga_horizon-euratom_en.pdf" target="_blank" title="">Lump Sum MGA</a></li>
|
||||
<li><a href="https://ec.europa.eu/info/funding-tenders/opportunities/docs/2021-2027/common/temp-form/af/detailed-budget-table_he-ls-euratom_en.xlsm" target="_blank" title="">Detailed budget table (HE LS) </a></li>
|
||||
<li><a href="https://ec.europa.eu/info/funding-tenders/opportunities/docs/2021-2027/horizon/temp-form/af/information-on-clinical-studies_he_en.docx" target="_blank" title="">Information on clinical studies (HE) </a></li>
|
||||
<li><a href="https://ec.europa.eu/info/funding-tenders/opportunities/docs/2021-2027/horizon/guidance/ls-funding-what-do-i-need-to-know_he_en.pdf" target="_blank" title="">Guidance: "Lump sums - what do I need to know?"</a></li>
|
||||
<li><a href="https://ec.europa.eu/info/funding-tenders/opportunities/docs/2021-2027/horizon/wp-call/2023-2024/wp-13-general-annexes_horizon-2023-2024_en.pdf" target="_blank" title="">HE Main Work Programme 2023-2025 - 13. General Annexes</a></li>
|
||||
<li><a href="https://eur-lex.europa.eu/legal-content/EN/ALL/?uri=CELEX%3A32018R1046" target="_blank" title="">EU Financial Regulation 2018/1046</a></li>
|
||||
<li><a href="https://ec.europa.eu/info/funding-tenders/opportunities/docs/2021-2027/common/guidance/rules-lev-lear-fca_en.pdf" target="_blank" title="">Rules for Legal Entity Validation, LEAR Appointment and Financial Capacity Assessment</a></li>
|
||||
<li><a href="https://webgate.ec.europa.eu/funding-tenders-opportunities/display/OM/Online+Manual" target="_blank" title="">Funding & Tenders Portal Online Manual</a></li>
|
||||
<li><a href="https://ec.europa.eu/info/funding-tenders/opportunities/docs/2021-2027/common/ftp/tc_en.pdf" target="_blank" title="">Funding & Tenders Portal Terms and Conditions</a></li>
|
||||
<li><a href="https://ec.europa.eu/info/funding-tenders/opportunities/portal/screen/support/legalnotice" target="_blank" title="">Funding & Tenders Portal Privacy Statement</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,193 @@
|
||||
class SubmissionShortForm2023StatusView extends SubmissionShortFormTabView {
|
||||
|
||||
setupRules() {
|
||||
|
||||
//this.viewPdf = this.components.find(item => item.el.classList.contains('view-pdf'));
|
||||
//this.viewPdf.addEventListener('click', this.onViewPdf.bind(this))
|
||||
|
||||
this.AwsDownload = new AwsFileDownload({
|
||||
pdf : { url: app.config.api['/S3Files'].viewDocument.uri,
|
||||
method: app.config.api['/S3Files'].viewDocument.method,
|
||||
headers: { 'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
credentials: 'include'
|
||||
},
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
fill(mode) {
|
||||
super.fill(mode);
|
||||
|
||||
this.switchStatus(this.model.data.status);
|
||||
}
|
||||
|
||||
switchStatus(status) {
|
||||
ui.hide(this.find('.withdrawn'));
|
||||
ui.hide(this.find('.fast-track'));
|
||||
ui.hide(this.find('.withdrawing'));
|
||||
ui.hide(this.find('.evaluation'));
|
||||
ui.hide(this.find('.go-full'));
|
||||
ui.hide(this.find('.coaching'));
|
||||
|
||||
if(status == 'submitted') {
|
||||
let submissionBt = this.components.find(item => item.el.classList.contains('view-pdf'));
|
||||
submissionBt.addEventListener('click', this.onDocumentDownload.bind(this, this.model.data.documents.shortSubmission.fileName))
|
||||
|
||||
this.withdraw = this.components.find(item => item.el.classList.contains('withdraw'));
|
||||
this.withdraw.addEventListener('click', this.onWithdraw.bind(this))
|
||||
this.withdrawConfirm = this.components.find(item => item.el.name == 'withdrawConfirmation');
|
||||
this.withdrawConfirm.disabled = false;
|
||||
|
||||
ui.show(this.find('.withdrawing'));
|
||||
ui.hide(this.find('.withdraw-confirm'));
|
||||
|
||||
if(!this.model.hasPrivilege('withdraw')) {
|
||||
ui.hide(this.find('button.withdraw'))
|
||||
}
|
||||
|
||||
this.find('.withdrawing span.date').innerText = (new Date(this.model.data.updated.date)).toLocaleDateString("en-DE")
|
||||
}
|
||||
|
||||
if(status == 'withdrawn') {
|
||||
ui.show(this.find('.withdrawn'));
|
||||
this.clone = this.components.find(item => item.el.classList.contains('clone1'));
|
||||
this.clone.addEventListener('click', this.onClone.bind(this));
|
||||
|
||||
}
|
||||
|
||||
if(status == 'fast-track') {
|
||||
ui.show(this.find('.fast-track'));
|
||||
ui.show(this.find('.go-full'));
|
||||
ui.show(this.find('.coaching'));
|
||||
|
||||
ui.show(this.find('.evaluation'));
|
||||
ui.hide(this.find('.evaluation .go'));
|
||||
ui.hide(this.find('.evaluation .no-go'));
|
||||
}
|
||||
|
||||
if(['evaluated', 'contested'].includes(status)) {
|
||||
ui.show(this.find('.evaluation'));
|
||||
ui.hide(this.find('.evaluation .go'));
|
||||
ui.hide(this.find('.evaluation .no-go'));
|
||||
|
||||
if(this.model.data.evaluation) {
|
||||
|
||||
if(this.model.data.evaluation.outcome == 'go') {
|
||||
let submissionBt = this.components.find(item => item.el.classList.contains('view-submission-go'));
|
||||
if(this.model.data.documents.shortSubmission) {
|
||||
submissionBt.addEventListener('click', this.onDocumentDownload.bind(this, this.model.data.documents.shortSubmission.fileName))
|
||||
} else {
|
||||
submissionBt.disabled = true
|
||||
}
|
||||
|
||||
let evalBt = this.components.find(item => item.el.classList.contains('view-evaluation-go'));
|
||||
if(this.model.data.documents.esrShort) {
|
||||
evalBt.addEventListener('click', this.onDocumentDownload.bind(this, this.model.data.documents.esrShort.fileName))
|
||||
} else {
|
||||
evalBt.disabled = true
|
||||
}
|
||||
|
||||
ui.show(this.find('.evaluation .go'));
|
||||
ui.show(this.find('.go-full'));
|
||||
ui.show(this.find('.coaching'));
|
||||
|
||||
}
|
||||
|
||||
if(this.model.data.evaluation.outcome == 'no-go') {
|
||||
let submissionBt = this.components.find(item => item.el.classList.contains('view-submission-no-go'));
|
||||
submissionBt.addEventListener('click', this.onDocumentDownload.bind(this, this.model.data.documents.shortSubmission.fileName))
|
||||
|
||||
let evalBt = this.components.find(item => item.el.classList.contains('view-evaluation-no-go'));
|
||||
evalBt.addEventListener('click', this.onDocumentDownload.bind(this, this.model.data.documents.esrShort.fileName))
|
||||
|
||||
ui.hide(this.find('.evaluation .first-submission'));
|
||||
ui.hide(this.find('.evaluation .second-submission'));
|
||||
ui.hide(this.find('.evaluation .complaint'));
|
||||
ui.hide(this.find('.evaluation .contested'));
|
||||
ui.show(this.find('.evaluation .no-go'));
|
||||
|
||||
if(this.model.data.resubmitted) {
|
||||
|
||||
if(status == 'contested') {
|
||||
ui.show(this.find('.evaluation .contested'));
|
||||
} else {
|
||||
/*
|
||||
let today = new Date();
|
||||
// Fixing the limit to 7 full days ending at 17:00
|
||||
let evalDate = (new Date(this.model.data.evaluation.date.substr(0,11) + '17:00:00+0200'));
|
||||
let limit = (new Date(evalDate.toString()));
|
||||
limit.setDate(evalDate.getDate() + 8);
|
||||
console.log('',limit)
|
||||
|
||||
if(today.getTime() < limit.getTime() ) {
|
||||
ui.show(this.find('.evaluation .complaint'));
|
||||
|
||||
this.find('.complaint .limit').innerText = limit.toLocaleDateString("en-DE");
|
||||
ui.show(this.find('.evaluation .complaint'));
|
||||
ui.show(this.find('.evaluation .second-submission'));
|
||||
this.complain = this.components.find(item => item.el.classList.contains('complain'));
|
||||
this.complain.addEventListener('click', this.onComplain.bind(this));
|
||||
}
|
||||
*/
|
||||
ui.show(this.find('.evaluation .complaint'));
|
||||
ui.show(this.find('.evaluation .second-submission'));
|
||||
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
ui.show(this.find('.evaluation .first-submission'));
|
||||
|
||||
this.clone = this.components.find(item => item.el.classList.contains('clone2'));
|
||||
this.clone.addEventListener('click', this.onClone.bind(this));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.error('No evaluation provided')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async onWithdraw(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
ui.show(this.find('.withdraw-confirm'));
|
||||
if(this.withdrawConfirm.el.checked) {
|
||||
this.el.dispatchEvent(new Event('withdraw'));
|
||||
}
|
||||
}
|
||||
|
||||
async onClone(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
this.el.dispatchEvent(new Event('clone'));
|
||||
}
|
||||
|
||||
async onComplain(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
this.el.dispatchEvent(new Event('complain'));
|
||||
}
|
||||
|
||||
async onDocumentDownload(file, event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
if(!file) return
|
||||
let awsUrl = await this.AwsDownload.getDownloadUrl('pdf', file)
|
||||
|
||||
if(!awsUrl) {
|
||||
ui.growl.append('This document is unavailable', 'danger');
|
||||
return;
|
||||
}
|
||||
|
||||
window.open(awsUrl, '_blank');
|
||||
}
|
||||
}
|
||||
|
||||
app.registerClass('SubmissionShortForm2023StatusView', SubmissionShortForm2023StatusView);
|
||||
@@ -0,0 +1,27 @@
|
||||
<style>
|
||||
.submission.short-form .members {
|
||||
display: grid;
|
||||
grid-gap: 10px;
|
||||
margin-bottom: var(--eicui-base-spacing-l);
|
||||
grid-template-columns: repeat(auto-fill, 280px);
|
||||
}
|
||||
.submission.short-form .members article {
|
||||
width: 280px;
|
||||
height: auto;
|
||||
grid-template-rows: min-content auto min-content;
|
||||
display: grid;
|
||||
}
|
||||
</style>
|
||||
<h2>Team and management</h2>
|
||||
<div>
|
||||
<label>Present your team member, including: the track record of the founders and key managers; available skills and experience</label>
|
||||
<div eicalert danger class="ceo-check">You need at least one CEO in your team</div>
|
||||
<div class="cols-1 right">
|
||||
<button eicbutton small primary class="member-add"><span>add a team member</span></button>
|
||||
</div>
|
||||
<div class="members"></div>
|
||||
</div>
|
||||
<div>
|
||||
<label>how you plan to ensure gender balance among your team members, including those in executive positions (at least CEO, CSO and CTO); the missing skills identified (target recruitment); recruitment plans and employee retention plans designed to address those missing skills which are identified. </label>
|
||||
<textarea eictextarea name="genderBalance" data-path="organisation" data-type="text" maxlen="10000" class="required"></textarea>
|
||||
</div>
|
||||
@@ -0,0 +1,162 @@
|
||||
class SubmissionShortForm2023TeamView extends SubmissionShortFormTabView {
|
||||
|
||||
DOMContentLoaded(options) {
|
||||
super.DOMContentLoaded(options);
|
||||
this.team = options.team;
|
||||
|
||||
this.pic = options.pic;
|
||||
this.number = options.number;
|
||||
|
||||
this.find('.member-add').addEventListener('click', this.createMember.bind(this));
|
||||
|
||||
|
||||
}
|
||||
|
||||
setupRules() {}
|
||||
|
||||
validate() {
|
||||
let report = super.validate();
|
||||
|
||||
let ceo = false;
|
||||
for(let id in this.members) {
|
||||
if(this.members[id].position.indexOf('CEO') == 0) ceo = true;
|
||||
}
|
||||
if(!ceo) {
|
||||
report.valid = false;
|
||||
report.issues++;
|
||||
ui.show(this.find('.ceo-check'))
|
||||
|
||||
} else {
|
||||
ui.hide(this.find('.ceo-check'))
|
||||
}
|
||||
|
||||
return report;
|
||||
}
|
||||
|
||||
fill(mode) {
|
||||
|
||||
super.fill(mode);
|
||||
|
||||
if(this.mode == 'read') {
|
||||
ui.hide(this.find('.member-add'));
|
||||
} else {
|
||||
ui.show(this.find('.member-add'));
|
||||
}
|
||||
|
||||
ui.hide(this.find('.ceo-check'));
|
||||
|
||||
this.list = this.find('.members');
|
||||
this.list.innerHTML = '';
|
||||
this.members = {};
|
||||
for(let member of this.model.data.team) {
|
||||
this.members[member.id] = member;
|
||||
this.list.append(this.createMemberCard(member));
|
||||
}
|
||||
}
|
||||
|
||||
getMember(id) { return this.members[id]; }
|
||||
|
||||
async createMember(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
let member = await this.openDialog(
|
||||
await this.loadContent(
|
||||
'projects/submissions/dialogs/SubmissionFormTeamMemberDialog',
|
||||
{ title: 'Add a team member' },
|
||||
{
|
||||
model: this.team,
|
||||
mode: 'create',
|
||||
pic: this.pic,
|
||||
number: this.number
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
if(member) {
|
||||
this.members[member.id] = member;
|
||||
this.list.append(this.createMemberCard(member));
|
||||
}
|
||||
}
|
||||
|
||||
async editMember(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
let id = event.currentTarget.dataset.id;
|
||||
|
||||
let member = await this.openDialog(
|
||||
await this.loadContent(
|
||||
'projects/submissions/dialogs/SubmissionFormTeamMemberDialog',
|
||||
{ title: 'Edit a team member' },
|
||||
{
|
||||
member: this.getMember(id),
|
||||
model: this.team,
|
||||
mode: 'update',
|
||||
pic: this.pic,
|
||||
number: this.number
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
if(member) {
|
||||
this.members[member.id] = member;
|
||||
this.updateMember(member);
|
||||
}
|
||||
}
|
||||
|
||||
createMemberCard(member) {
|
||||
|
||||
let index = member.id;
|
||||
let severity = member.position && member.position.indexOf('CEO') == 0 ? 'primary': ''
|
||||
let card = ui.create(`<article eiccard ${severity} data-id="${member.id}" data-index="${index}">
|
||||
<header>
|
||||
<h1>${app.meta.toString('organisation-genders', member.gender)} ${member.firstname} ${member.lastname}</h1>
|
||||
<h2>${member.position}</h2>
|
||||
</header>
|
||||
<section>
|
||||
<div>
|
||||
<label>Area of Expertise(s)</label>
|
||||
<span>${member.expertises.join(', ')}</span>
|
||||
</div>
|
||||
<p><i>"${member.justification}"</i></p>
|
||||
</section>
|
||||
<footer>
|
||||
<button eicbutton small primary data-id="${index}" class="edit">edit</button>
|
||||
<button eicbutton small danger data-id="${index}" class="remove">remove</button>
|
||||
</footer>
|
||||
</article`);
|
||||
|
||||
if(this.mode == 'read') ui.hide(card.querySelector('footer'));
|
||||
|
||||
if(this.mode == 'edit') {
|
||||
card.querySelector('button.edit').addEventListener('click', this.editMember.bind(this));
|
||||
card.querySelector('button.remove').addEventListener('click', this.removeMember.bind(this));
|
||||
}
|
||||
|
||||
return card;
|
||||
}
|
||||
|
||||
updateMember(member) {
|
||||
|
||||
let old = this.list.querySelector(`article[data-id="${member.id}"]`);
|
||||
let card = this.createMemberCard(member);
|
||||
old.after(card);
|
||||
old.remove();
|
||||
}
|
||||
|
||||
removeMember(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
let id = event.currentTarget.dataset.id;
|
||||
|
||||
this.team.delete(this.pic, this.number, id)
|
||||
.then( async payload => {
|
||||
delete this.members[id];
|
||||
this.find(`article[data-index="${id}"]`).remove();
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
app.registerClass('SubmissionShortForm2023TeamView', SubmissionShortForm2023TeamView);
|
||||
Reference in New Issue
Block a user