unclean SPARC

This commit is contained in:
STEINNI
2025-08-27 07:03:09 +00:00
commit f308460931
430 changed files with 54426 additions and 0 deletions
@@ -0,0 +1,625 @@
/**
*
*/
class ProjectFundingTechDDView extends EICDomContent {
_autoSave = null;
// save every 10s
_autoSaveDelay = 10000;
// validate every 2s
_autoValidateDelay = 2000;
// state flag avoiding saving form currently beeing loaded
_busy = false;
get autoSave() { return this._autoSave != null; }
set autoSave(value) {
if(value) {
if(!this._autoSave) {
this._autoSave = setInterval(this.onAutoSave.bind(this), this._autoSaveDelay)
}
} else {
clearInterval(this._autoSave);
this._autoSave = null;
}
}
DOMContentLoaded(options) {
this.components = ui.eicfy(this.el);
this.projectNumber = options.projectNumber
this.nodeId = options.nodeId;
this.nodeType = 'techdd';
this.mode = options.mode;
for(let model in options.models) this[model] = options.models[model];
this.container = this.components.find(o => o.el.classList.contains('funding-node'))
this.container.loading = true;
this._busy = true;
this.techdd.get(this.projectNumber,this.nodeType, this.nodeId)
.then(this.fill.bind(this))
}
DOMContentBlured() {
if(this.autoSave) { this.autoSave = false; }
if(this.validationCheck) {
clearInterval(this.validationCheck);
this.validationCheck = null;
}
}
DOMContentRemoved() {
if(this.autoSave) {
this.autoSave = false;
if((this.mode == 'edit')) this.save();
};
if(this.validationCheck) {
clearInterval(this.validationCheck);
this.validationCheck = null;
}
}
DOMContentFocused() {
if(this.mode == 'edit') {
if(this.saveToggler && this.saveToggler.value == 'true') { this.autoSave = true }
if(!this.validationCheck) {
this.validationCheck = setInterval(this.validateForm.bind(this), this._autoValidateDelay);
}
}
}
setupFormActions() {
let saveControl = this.find('.autosave-control');
this.availableActions = [];
this.reviewActions = [];
ui.hide(saveControl);
if(this.techdd.hasPrivilege('read')) {
this.mode = 'read'
}
if(this.techdd.hasPrivilege('update')) {
this.mode = 'edit';
ui.show(saveControl);
this.availableActions.push({
id: 'cancel',
ctrl: new Button(null, {
severity: 'secondary',
onclick: this.cancel.bind(this),
label: 'discard changes'
})
})
this.availableActions.push({
id: 'save',
ctrl: new Button(null, {
severity: 'primary',
onclick: this.save.bind(this),
label: 'save' })
})
this.autosave = true
this.saveToggler.onToggle("true", this.saveToggler);
}
if(this.techdd.hasPrivilege('submit')) {
this.availableActions.push({
id: 'submit',
ctrl: new Button(null, {
severity: 'primary',
onclick: this.submit.bind(this),
label: 'submit' })
})
}
if(this.techdd.hasPrivilege('reject')) {
this.mode = 'review';
this.availableActions.push({
id: 'reject',
ctrl: new Button(null, {
severity: 'primary',
onclick: this.reject.bind(this),
label: 'Reopen' })
})
this.reviewActions.push({
id: 'cancelReview',
ctrl: new Button(null, {
severity: 'secondary',
onclick: this.cancelReview.bind(this),
label: 'cancel' })
})
this.reviewActions.push({
id: 'commitReview',
ctrl: new Button(null, {
severity: 'primary',
onclick: this.commitReview.bind(this),
label: 'send remarks' })
})
}
if(this.techdd.hasPrivilege('sendforreview')) {
this.mode = 'review';
this.availableActions.push({
id: 'review',
ctrl: new Button(null, {
severity: 'primary',
onclick: this.review.bind(this),
label: 'send for consultation' })
})
}
if(this.techdd.hasPrivilege('validate')) {
this.mode = 'review';
this.availableActions.push({
id: 'validate',
ctrl: new Button(null, {
severity: 'success',
onclick: this.validate.bind(this),
label: 'validate' })
})
}
if(this.techdd.hasPrivilege('cancel')) {
this.mode = 'review';
this.availableActions.push({
id: 'abort',
ctrl: new Button(null, {
severity: 'danger',
onclick: this.abort.bind(this),
label: 'abort' })
})
}
if(this.techdd.hasPrivilege('review')) {
this.mode = 'review';
this.availableActions.push({
id: 'reject',
ctrl: new Button(null, {
severity: 'primary',
onclick: this.reject.bind(this),
label: 'add remarks' })
})
this.availableActions.push({
id: 'approve',
ctrl: new Button(null, {
severity: 'success',
onclick: this.approve.bind(this),
label: 'approve' })
})
this.reviewActions.push({
id: 'cancelReview',
ctrl: new Button(null, {
severity: 'secondary',
onclick: this.cancelReview.bind(this),
label: 'cancel' })
})
this.reviewActions.push({
id: 'commitReview',
ctrl: new Button(null, {
severity: 'primary',
onclick: this.commitConsult.bind(this),
label: 'send remarks' })
})
}
let container = this.find('footer .actions');
container.innerHTML = '';
for(let action of this.availableActions) { container.append(action.ctrl.el) }
}
fill(data) {
let path = 'projects/icmp/project/forms/'
let view = 'ICMPFormTechddV1View';
let versionLabel = 'regular report'
switch(data.form.version) {
case 'techdd-report-v1-full':
view = 'ICMPFormTechddV1FullView';
versionLabel = 'full report'
break;
case 'techdd-report-v1-enhanced':
view = 'ICMPFormTechddV1EnhancedView'
versionLabel = 'enhanced report'
break;
default:
break;
}
let tags = [];
this.find('header .version').innerHTML = `<span eicchip primary>${versionLabel}</span>`
if(data.experts.length > 0) {
tags.push(`<span eicchip info>reporting assigned to ${data.experts[0].information.name.firstName} ${data.experts[0].information.name.lastName}</span>`)
}
tags.push(`<span eicchip accent>${app.meta.getItem('icmp-techdd-status', data.statusHistory[0].value).label}</span>`)
this.find('header h2').innerHTML = tags.join('');
this.originalForm = JSON.parse(JSON.stringify(data))
this.loadContent(path + view, {})
.then(view => {
this.find('.form').append(view.el)
view.fill(data);
this.formView = view;
this.form = view.form;
this.formComponents = view.components;
this.setupForm(data)
}
)
}
setupForm(data) {
this.saveToggler = this.components.find(o => o.el.name == 'autosave');
this.saveToggler.onToggle = this.onAutoSaveToggle.bind(this)
this.setupFormActions();
switch(this.mode) {
case 'read':
this.enableEditing(false);
this.enableReviewing(false);
break;
case 'edit':
this.enableEditing(true);
this.enableReviewing(false);
if(!this.validationCheck) {
this.validationCheck = setInterval(this.validateForm.bind(this), this._autoValidateDelay);
}
break;
case 'review':
this.enableEditing(false);
this.enableReviewing(false);
break;
}
let comments = this.findAll('[data-path^="comments."]')
for(let comment of comments) {
let chunks = comment.dataset.path.split('.')
if(chunks.length > 2 && comment.value != '') {
let trigger = this.find(`li[data-target=${chunks[2]}]`)
if(trigger) trigger.setAttribute('warning', '')
}
}
if(data.documents && data.documents.length > 0) {
for(let document of data.documents[0].attachments) {
let url = app.config.api['/files'].get.uri
url = url.replace('{id}', document.id)
let alert = ui.create(`<div eicalert info><a href="${url}" noroute target="_blank">Download report as PDF</a></div>`)
this.find('.files').append(alert);
}
}
this.container.loading = false;
this._busy = false;
}
enableEditing(value) {
let fields = this.form.scan(true);
for(let field of fields) {
let component = this.form.element2component(this.formComponents, field.el.name, field.el.dataset.path)
if(component && component.el && component.el.dataset.path.search('form') == 0) {
if(value) {
component.el.dataset.type = component.el.nodeName == 'SELECT' ? 'boolean': 'text'
component.disabled = false;
} else {
component.el.dataset.type = 'ignore'
component.disabled = true;
}
}
}
}
enableReviewing(value) {
let fields = this.form.scan(true);
this.originalComments = [];
for(let field of fields) {
let component = this.form.element2component(this.formComponents, field.el.name, field.el.dataset.path)
if(component && component.el.dataset.path.search('comment') == 0) {
if(value) {
this.originalComments.push({
component: component,
value: component.value
})
component.el.dataset.type = 'text'
component.disabled = false
component.show()
} else {
component.el.dataset.type = 'ignore'
component.disabled = true
component.hide()
let alerts = component.el.parentElement.querySelectorAll('[eicalert]');
for(let alert of alerts) {
alert.remove();
}
if(component.value != '') {
component.el.parentElement.append((new Alert(null, {message: component.value,severity: 'warning'})).el)
}
}
}
}
}
validateForm() {
//let valid = true;
let valid = this.form.validate();
// init tab badges
//let triggers = [].concat( this.formView.tabTech.triggers, this.formView.tabMarket.triggers )
console.log(this.formView.getTriggers())
let triggers = this.formView.getTriggers();
for(let trigger of triggers) {
let badge = new Badge(trigger.querySelector('[eicbadge]'))
badge.value = ''
}
// mark tabs on error
if(!valid) {
let errors = this.findAll('.validation-failed textarea, .validation-failed select')
for(let error of errors) {
let path = error.dataset.path.split('.')
let trigger = triggers.find(el => el.dataset.target == path[2]);
// todo make it count
if(trigger) {
let badge = new Badge(trigger.querySelector('[eicbadge]'))
badge.value = parseInt(badge.value || 0) + 1;
}
}
}
/**/
return valid;
}
autoValidate() { this.validateForm(); }
reject() {
let container = this.find('footer .actions');
container.innerHTML = '';
for(let action of this.reviewActions) container.append(action.ctrl.el)
this.enableReviewing(true);
}
cancelReview() {
let container = this.find('footer .actions');
container.innerHTML = '';
for(let comment of this.originalComments) {
comment.component.value = comment.value;
}
for(let action of this.availableActions) container.append(action.ctrl.el)
this.enableReviewing(false);
}
commitReview() {
for(let action of this.reviewActions) action.ctrl.disabled = true;
this.reviewActions.find(o => o.id == 'commitReview').ctrl.loading = true;
let payload = this.form.value;
this.techdd.comment('rejecting', this.projectNumber, this.nodeType, this.nodeId, payload)
.then( () => {
for(let action of this.reviewActions) action.ctrl.disabled = false;
this.reviewActions.find(o => o.id == 'commitReview').ctrl.loading = false;
this.reviewActions.find(o => o.id == 'commitReview').ctrl.disabled = this.autoSave;
app.events.trigger('project_node_updated', {node: this.nodeType, nodeId: this.nodeId});
},
() => {
for(let action of this.reviewActions) action.ctrl.disabled = false;
this.reviewActions.find(o => o.id == 'commitReview').ctrl.loading = false;
this.reviewActions.find(o => o.id == 'commitReview').ctrl.disabled = this.autoSave;
})
}
approve() {
for(let action of this.availableActions) action.ctrl.disabled = true;
this.availableActions.find(o => o.id == 'approve').ctrl.loading = true;
let payload = this.form.value;
payload.comments = {};
this.techdd.comment('reviewing', this.projectNumber, this.nodeType, this.nodeId, payload)
.then( () => {
for(let action of this.availableActions) action.ctrl.disabled = false;
this.availableActions.find(o => o.id == 'approve').ctrl.loading = false;
app.events.trigger('project_node_updated', {node: this.nodeType, nodeId: this.nodeId});
},
() => {
for(let action of this.availableActions) action.ctrl.disabled = false;
this.availableActions.find(o => o.id == 'approve').ctrl.loading = false;
})
}
commitConsult() {
for(let action of this.reviewActions) action.ctrl.disabled = true;
this.reviewActions.find(o => o.id == 'commitReview').ctrl.loading = true;
let payload = this.form.value;
this.techdd.comment('reviewing', this.projectNumber, this.nodeType, this.nodeId, payload)
.then( () => {
for(let action of this.reviewActions) action.ctrl.disabled = false;
this.reviewActions.find(o => o.id == 'commitReview').ctrl.loading = false;
app.events.trigger('project_node_updated', {node: this.nodeType, nodeId: this.nodeId});
},
() => {
for(let action of this.reviewActions) action.ctrl.disabled = false;
this.reviewActions.find(o => o.id == 'commitReview').ctrl.loading = false;
})
}
save() {
if(!app.User.isAuthenticated || this._busy) return;
this.validateForm()
for(let action of this.availableActions) action.ctrl.disabled = true;
this.availableActions.find(o => o.id == 'save').ctrl.loading = true;
let payload = this.form.value;
this.techdd.process('saving', this.projectNumber, this.nodeType, this.nodeId, payload)
.then( payload => {
for(let action of this.availableActions) action.ctrl.disabled = false;
this.availableActions.find(o => o.id == 'save').ctrl.loading = false;
this.availableActions.find(o => o.id == 'save').ctrl.disabled = this.autoSave;
this.availableActions.find(o => o.id == 'cancel').ctrl.disabled = this.autoSave;
this.originalForm.form = payload.form;
},
() => {
for(let action of this.availableActions) action.ctrl.disabled = false;
this.availableActions.find(o => o.id == 'save').ctrl.loading = false;
this.availableActions.find(o => o.id == 'save').ctrl.disabled = this.autoSave;
this.availableActions.find(o => o.id == 'cancel').ctrl.disabled = this.autoSave;
})
}
submit() {
for(let action of this.availableActions) action.ctrl.disabled = true;
this.availableActions.find(o => o.id == 'submit').ctrl.loading = true;
if(this.validateForm()) {
let payload = this.form.value;
this.autoSave = false;
this.techdd.process('submitting', this.projectNumber, this.nodeType, this.nodeId, payload)
.then( () => {
for(let action of this.availableActions) action.ctrl.disabled = false;
this.availableActions.find(o => o.id == 'submit').ctrl.loading = false;
app.events.trigger('project_node_updated', {node: this.nodeType, nodeId: this.nodeId});
},
() => {
for(let action of this.availableActions) action.ctrl.disabled = false;
this.availableActions.find(o => o.id == 'submit').ctrl.loading = false;
})
} else {
for(let action of this.availableActions) action.ctrl.disabled = false;
this.availableActions.find(o => o.id == 'submit').ctrl.loading = false;
ui.growl.append('The form still contains issues', 'danger')
}
}
cancel() {
this.form.fill(this.components,this.originalForm)
}
async abort() {
let success = await this.openDialog(
await this.loadContent(
'projects/icmp/project/dialogs/ICMPNodeActionConfirmDialog',
{
title: 'Dismiss expert and report',
subtitle: 'You are about to dismiss this report. Another expert will be assigned to this task.'
},
{
models: {
node: this.techdd
},
number: this.projectNumber,
type: this.nodeType,
nodeId: this.nodeId,
report: this.form.value,
action: 'aborting'
}
)
);
if(success) {
app.events.trigger('project_node_updated', {node: this.nodeType, nodeId: this.nodeId});
}
}
async validate() {
let success = await this.openDialog(
await this.loadContent(
'projects/icmp/project/dialogs/ICMPNodeActionConfirmDialog',
{
title: 'Validate this report',
subtitle: 'You are about to approve this report and complete Technical Due Diligence'
},
{
models: {
node: this.techdd
},
number: this.projectNumber,
type: this.nodeType,
nodeId: this.nodeId,
report: this.form.value,
action: 'validating'
}
)
);
if(success) {
app.events.trigger('project_node_updated', {node: this.nodeType, nodeId: this.nodeId});
}
}
async review() {
let success = await this.openDialog(
await this.loadContent(
'projects/icmp/project/dialogs/ICMPNodeActionConfirmDialog',
{ title: 'Send this report for reviewing' },
{
models: {
node: this.techdd
},
number: this.projectNumber,
type: this.nodeType,
nodeId: this.nodeId,
report: this.form.value,
action: 'reviewing'
}
)
)
if(success) {
app.events.trigger('project_node_updated', {node: this.nodeType, nodeId: this.nodeId});
}
}
onAutoSaveToggle(value, toggler) {
if(value == 'true') {
toggler.severity = 'primary'
this.autoSave = true;
} else {
toggler.severity = 'secondary'
this.autoSave = false;
}
this.availableActions.find(o => o.id == 'save').ctrl.disabled = this.autoSave;
this.availableActions.find(o => o.id == 'cancel').ctrl.disabled = this.autoSave;
}
onAutoSave() { this.save(); }
}
app.registerClass('ProjectFundingTechDDView',ProjectFundingTechDDView);