Files
ResInsight/ApplicationLibCode/ProjectDataModel/Workflow/RimWorkflowTaskInput.cpp
T
Kristian Bendiksen 3a7b8f6be8 Workflows: Add UI for taskmaestro workflows
Discover taskmaestro workflows under ~/.taskmaestro/workflows/ and surface
them as a "Workflows" collection in the project tree alongside Scripts.
Each workflow's task input schema is auto-generated by introspecting the
Pydantic models via a Python helper (rips.taskmaestro_helper) and rendered
as PDM field bindings - scalars for str/int/float/bool, and PdmPtrField
pickers for fields typed as rips.Case / rips.WellPath / rips.View.

The Run button on a RimWorkflow writes input.yaml from current bindings
(rips object references serialized as __resinsight_ref__ maps), spawns
the helper's run subcommand, and streams output to a modeless log dialog.
The helper resolves __resinsight_ref__ markers back to live rips objects
via the running ResInsight's gRPC server before driving taskmaestro.
2026-10-05 19:56:36 +02:00

120 lines
3.8 KiB
C++

/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2026 Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RimWorkflowTaskInput.h"
#include "RimWorkflowBoolBinding.h"
#include "RimWorkflowCaseBinding.h"
#include "RimWorkflowDateBinding.h"
#include "RimWorkflowFilePathBinding.h"
#include "RimWorkflowFloatBinding.h"
#include "RimWorkflowIntBinding.h"
#include "RimWorkflowStringBinding.h"
#include "RimWorkflowViewBinding.h"
#include "RimWorkflowWellPathBinding.h"
#include "cafPdmUiOrdering.h"
#include "cafPdmUiTreeOrdering.h"
#include <QJsonArray>
#include <QJsonObject>
CAF_PDM_SOURCE_INIT( RimWorkflowTaskInput, "WorkflowTaskInput" );
namespace
{
RimWorkflowFieldBinding* createBinding( const QJsonObject& schema )
{
const QString resinsightType = schema.value( "resinsight_type" ).toString();
if ( resinsightType == "EclipseCase" ) return new RimWorkflowCaseBinding;
if ( resinsightType == "WellPath" ) return new RimWorkflowWellPathBinding;
if ( resinsightType == "View" ) return new RimWorkflowViewBinding;
const QString type = schema.value( "type" ).toString( "string" );
const QString format = schema.value( "format" ).toString();
if ( type == "string" && format == "date" ) return new RimWorkflowDateBinding;
if ( type == "string" && ( format == "path" || format == "file-path" || format == "directory-path" ) )
return new RimWorkflowFilePathBinding;
if ( type == "boolean" ) return new RimWorkflowBoolBinding;
if ( type == "integer" ) return new RimWorkflowIntBinding;
if ( type == "number" ) return new RimWorkflowFloatBinding;
return new RimWorkflowStringBinding;
}
} // namespace
RimWorkflowTaskInput::RimWorkflowTaskInput()
{
CAF_PDM_InitObject( "Task", ":/Bullet.png" );
CAF_PDM_InitFieldNoDefault( &m_items, "Bindings", "" );
CAF_PDM_InitFieldNoDefault( &m_taskName, "TaskName", "Task" );
m_taskName.uiCapability()->setUiReadOnly( true );
}
QString RimWorkflowTaskInput::taskName() const
{
return m_taskName();
}
void RimWorkflowTaskInput::setTaskName( const QString& name )
{
m_taskName = name;
setUiName( name );
}
void RimWorkflowTaskInput::buildFromSchema( const QJsonArray& configFields )
{
deleteAllItems();
for ( const QJsonValue& v : configFields )
{
const QJsonObject schema = v.toObject();
auto* binding = createBinding( schema );
binding->applySchema( schema );
addItem( binding );
}
}
void RimWorkflowTaskInput::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
for ( RimWorkflowFieldBinding* b : items() )
{
if ( b && b->valueField() ) uiOrdering.add( b->valueField() );
}
uiOrdering.skipRemainingFields( true );
}
void RimWorkflowTaskInput::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName )
{
uiTreeOrdering.skipRemainingChildren( true );
}
QString RimWorkflowTaskInput::toTaskYamlBlock() const
{
QString out = m_taskName() + ":\n";
if ( count() == 0 )
{
out += " {}\n";
return out;
}
for ( const RimWorkflowFieldBinding* b : items() )
{
out += QString( " %1: %2\n" ).arg( b->fieldName(), b->toYamlValue() );
}
return out;
}