Merge remote-tracking branch 'origin/main' into feature/interstitial
This commit is contained in:
commit
d73baedcbe
|
@ -56,7 +56,7 @@ jobs:
|
|||
run: echo "date=$(date -u +'%Y-%m-%d_%H-%M-%S')" >> "$GITHUB_OUTPUT"
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4.3.0
|
||||
uses: docker/metadata-action@v4.4.0
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
tags: |
|
||||
|
@ -100,7 +100,7 @@ jobs:
|
|||
run: echo "date=$(date -u +'%Y-%m-%d_%H-%M-%S')" >> "$GITHUB_OUTPUT"
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4.3.0
|
||||
uses: docker/metadata-action@v4.4.0
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
tags: |
|
||||
|
|
|
@ -25,7 +25,7 @@ jobs:
|
|||
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4.3.0
|
||||
uses: docker/metadata-action@v4.4.0
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
|
||||
|
@ -58,7 +58,7 @@ jobs:
|
|||
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4.3.0
|
||||
uses: docker/metadata-action@v4.4.0
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
|
||||
|
@ -92,7 +92,7 @@ jobs:
|
|||
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4.3.0
|
||||
uses: docker/metadata-action@v4.4.0
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
|
||||
|
|
|
@ -5,3 +5,4 @@ t
|
|||
.dccache
|
||||
*~
|
||||
version_info.json
|
||||
.coverage*
|
|
@ -19,3 +19,4 @@ node_modules
|
|||
/bin/import_secrets.py
|
||||
/src/spiffworkflow_backend/config/secrets.py
|
||||
*null-ls_*
|
||||
/local_wheels/*.whl
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
# Local Wheels
|
||||
|
||||
If you have any wheels you wish to test locally, copy them into this folder then run:
|
||||
|
||||
```
|
||||
poetry add local_wheels/my.whl
|
||||
```
|
||||
|
||||
Alternatively you can sideload it:
|
||||
|
||||
```
|
||||
poetry run pip install local_wheels/*.whl
|
||||
```
|
||||
|
||||
when you boot the backend.
|
|
@ -14,15 +14,30 @@ config = context.config
|
|||
fileConfig(config.config_file_name)
|
||||
logger = logging.getLogger('alembic.env')
|
||||
|
||||
|
||||
def get_engine():
|
||||
try:
|
||||
# this works with Flask-SQLAlchemy<3 and Alchemical
|
||||
return current_app.extensions['migrate'].db.get_engine()
|
||||
except TypeError:
|
||||
# this works with Flask-SQLAlchemy>=3
|
||||
return current_app.extensions['migrate'].db.engine
|
||||
|
||||
|
||||
def get_engine_url():
|
||||
try:
|
||||
return get_engine().url.render_as_string(hide_password=False).replace(
|
||||
'%', '%%')
|
||||
except AttributeError:
|
||||
return str(get_engine().url).replace('%', '%%')
|
||||
|
||||
|
||||
# add your model's MetaData object here
|
||||
# for 'autogenerate' support
|
||||
# from myapp import mymodel
|
||||
# target_metadata = mymodel.Base.metadata
|
||||
config.set_main_option(
|
||||
'sqlalchemy.url',
|
||||
str(current_app.extensions['migrate'].db.get_engine().url).replace(
|
||||
'%', '%%'))
|
||||
target_metadata = current_app.extensions['migrate'].db.metadata
|
||||
config.set_main_option('sqlalchemy.url', get_engine_url())
|
||||
target_db = current_app.extensions['migrate'].db
|
||||
|
||||
# other values from the config, defined by the needs of env.py,
|
||||
# can be acquired:
|
||||
|
@ -30,6 +45,12 @@ target_metadata = current_app.extensions['migrate'].db.metadata
|
|||
# ... etc.
|
||||
|
||||
|
||||
def get_metadata():
|
||||
if hasattr(target_db, 'metadatas'):
|
||||
return target_db.metadatas[None]
|
||||
return target_db.metadata
|
||||
|
||||
|
||||
def run_migrations_offline():
|
||||
"""Run migrations in 'offline' mode.
|
||||
|
||||
|
@ -44,7 +65,7 @@ def run_migrations_offline():
|
|||
"""
|
||||
url = config.get_main_option("sqlalchemy.url")
|
||||
context.configure(
|
||||
url=url, target_metadata=target_metadata, literal_binds=True
|
||||
url=url, target_metadata=get_metadata(), literal_binds=True
|
||||
)
|
||||
|
||||
with context.begin_transaction():
|
||||
|
@ -69,12 +90,12 @@ def run_migrations_online():
|
|||
directives[:] = []
|
||||
logger.info('No changes in schema detected.')
|
||||
|
||||
connectable = current_app.extensions['migrate'].db.get_engine()
|
||||
connectable = get_engine()
|
||||
|
||||
with connectable.connect() as connection:
|
||||
context.configure(
|
||||
connection=connection,
|
||||
target_metadata=target_metadata,
|
||||
target_metadata=get_metadata(),
|
||||
process_revision_directives=process_revision_directives,
|
||||
**current_app.extensions['migrate'].configure_args
|
||||
)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
"""empty message
|
||||
|
||||
Revision ID: 0b5dd14bfbac
|
||||
Revision ID: 44a8f46cc508
|
||||
Revises:
|
||||
Create Date: 2023-03-23 16:25:33.288500
|
||||
Create Date: 2023-04-17 15:40:28.658588
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
|
@ -10,7 +10,7 @@ import sqlalchemy as sa
|
|||
from sqlalchemy.dialects import mysql
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '0b5dd14bfbac'
|
||||
revision = '44a8f46cc508'
|
||||
down_revision = None
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
@ -20,7 +20,8 @@ def upgrade():
|
|||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('bpmn_process_definition',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('hash', sa.String(length=255), nullable=False),
|
||||
sa.Column('single_process_hash', sa.String(length=255), nullable=False),
|
||||
sa.Column('full_process_model_hash', sa.String(length=255), nullable=True),
|
||||
sa.Column('bpmn_identifier', sa.String(length=255), nullable=False),
|
||||
sa.Column('bpmn_name', sa.String(length=255), nullable=True),
|
||||
sa.Column('properties_json', sa.JSON(), nullable=False),
|
||||
|
@ -29,10 +30,13 @@ def upgrade():
|
|||
sa.Column('updated_at_in_seconds', sa.Integer(), nullable=True),
|
||||
sa.Column('created_at_in_seconds', sa.Integer(), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('hash')
|
||||
sa.UniqueConstraint('full_process_model_hash'),
|
||||
sa.UniqueConstraint('full_process_model_hash', 'single_process_hash', name='process_hash_unique')
|
||||
)
|
||||
op.create_index(op.f('ix_bpmn_process_definition_bpmn_identifier'), 'bpmn_process_definition', ['bpmn_identifier'], unique=False)
|
||||
op.create_index(op.f('ix_bpmn_process_definition_bpmn_name'), 'bpmn_process_definition', ['bpmn_name'], unique=False)
|
||||
with op.batch_alter_table('bpmn_process_definition', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_bpmn_process_definition_bpmn_identifier'), ['bpmn_identifier'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_bpmn_process_definition_bpmn_name'), ['bpmn_name'], unique=False)
|
||||
|
||||
op.create_table('correlation_property_cache',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('name', sa.String(length=50), nullable=False),
|
||||
|
@ -41,16 +45,20 @@ def upgrade():
|
|||
sa.Column('retrieval_expression', sa.String(length=255), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_index(op.f('ix_correlation_property_cache_message_name'), 'correlation_property_cache', ['message_name'], unique=False)
|
||||
op.create_index(op.f('ix_correlation_property_cache_name'), 'correlation_property_cache', ['name'], unique=False)
|
||||
with op.batch_alter_table('correlation_property_cache', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_correlation_property_cache_message_name'), ['message_name'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_correlation_property_cache_name'), ['name'], unique=False)
|
||||
|
||||
op.create_table('group',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('name', sa.String(length=255), nullable=True),
|
||||
sa.Column('identifier', sa.String(length=255), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_index(op.f('ix_group_identifier'), 'group', ['identifier'], unique=False)
|
||||
op.create_index(op.f('ix_group_name'), 'group', ['name'], unique=False)
|
||||
with op.batch_alter_table('group', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_group_identifier'), ['identifier'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_group_name'), ['name'], unique=False)
|
||||
|
||||
op.create_table('json_data',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('hash', sa.String(length=255), nullable=False),
|
||||
|
@ -66,8 +74,10 @@ def upgrade():
|
|||
sa.Column('created_at_in_seconds', sa.Integer(), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_index(op.f('ix_message_triggerable_process_model_message_name'), 'message_triggerable_process_model', ['message_name'], unique=False)
|
||||
op.create_index(op.f('ix_message_triggerable_process_model_process_model_identifier'), 'message_triggerable_process_model', ['process_model_identifier'], unique=False)
|
||||
with op.batch_alter_table('message_triggerable_process_model', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_message_triggerable_process_model_message_name'), ['message_name'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_message_triggerable_process_model_process_model_identifier'), ['process_model_identifier'], unique=False)
|
||||
|
||||
op.create_table('permission_target',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('uri', sa.String(length=255), nullable=False),
|
||||
|
@ -88,10 +98,12 @@ def upgrade():
|
|||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('identifier', 'type', name='_identifier_type_unique')
|
||||
)
|
||||
op.create_index(op.f('ix_spec_reference_cache_display_name'), 'spec_reference_cache', ['display_name'], unique=False)
|
||||
op.create_index(op.f('ix_spec_reference_cache_identifier'), 'spec_reference_cache', ['identifier'], unique=False)
|
||||
op.create_index(op.f('ix_spec_reference_cache_process_model_id'), 'spec_reference_cache', ['process_model_id'], unique=False)
|
||||
op.create_index(op.f('ix_spec_reference_cache_type'), 'spec_reference_cache', ['type'], unique=False)
|
||||
with op.batch_alter_table('spec_reference_cache', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_spec_reference_cache_display_name'), ['display_name'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_spec_reference_cache_identifier'), ['identifier'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_spec_reference_cache_process_model_id'), ['process_model_id'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_spec_reference_cache_type'), ['type'], unique=False)
|
||||
|
||||
op.create_table('user',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('username', sa.String(length=255), nullable=False),
|
||||
|
@ -108,9 +120,11 @@ def upgrade():
|
|||
sa.UniqueConstraint('service', 'service_id', name='service_key'),
|
||||
sa.UniqueConstraint('username')
|
||||
)
|
||||
op.create_index(op.f('ix_user_email'), 'user', ['email'], unique=False)
|
||||
op.create_index(op.f('ix_user_service'), 'user', ['service'], unique=False)
|
||||
op.create_index(op.f('ix_user_service_id'), 'user', ['service_id'], unique=False)
|
||||
with op.batch_alter_table('user', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_user_email'), ['email'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_user_service'), ['service'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_user_service_id'), ['service_id'], unique=False)
|
||||
|
||||
op.create_table('bpmn_process',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('guid', sa.String(length=36), nullable=True),
|
||||
|
@ -127,10 +141,12 @@ def upgrade():
|
|||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('guid')
|
||||
)
|
||||
op.create_index(op.f('ix_bpmn_process_bpmn_process_definition_id'), 'bpmn_process', ['bpmn_process_definition_id'], unique=False)
|
||||
op.create_index(op.f('ix_bpmn_process_direct_parent_process_id'), 'bpmn_process', ['direct_parent_process_id'], unique=False)
|
||||
op.create_index(op.f('ix_bpmn_process_json_data_hash'), 'bpmn_process', ['json_data_hash'], unique=False)
|
||||
op.create_index(op.f('ix_bpmn_process_top_level_process_id'), 'bpmn_process', ['top_level_process_id'], unique=False)
|
||||
with op.batch_alter_table('bpmn_process', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_bpmn_process_bpmn_process_definition_id'), ['bpmn_process_definition_id'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_bpmn_process_direct_parent_process_id'), ['direct_parent_process_id'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_bpmn_process_json_data_hash'), ['json_data_hash'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_bpmn_process_top_level_process_id'), ['top_level_process_id'], unique=False)
|
||||
|
||||
op.create_table('bpmn_process_definition_relationship',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('bpmn_process_definition_parent_id', sa.Integer(), nullable=False),
|
||||
|
@ -140,8 +156,10 @@ def upgrade():
|
|||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('bpmn_process_definition_parent_id', 'bpmn_process_definition_child_id', name='bpmn_process_definition_relationship_unique')
|
||||
)
|
||||
op.create_index(op.f('ix_bpmn_process_definition_relationship_bpmn_process_definition_parent_id'), 'bpmn_process_definition_relationship', ['bpmn_process_definition_parent_id'], unique=False)
|
||||
op.create_index(op.f('ix_bpmn_process_definition_relationship_bpmn_process_definition_child_id'), 'bpmn_process_definition_relationship', ['bpmn_process_definition_child_id'], unique=False)
|
||||
with op.batch_alter_table('bpmn_process_definition_relationship', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_bpmn_process_definition_relationship_bpmn_process_definition_parent_id'), ['bpmn_process_definition_parent_id'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_bpmn_process_definition_relationship_bpmn_process_definition_child_id'), ['bpmn_process_definition_child_id'], unique=False)
|
||||
|
||||
op.create_table('principal',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('user_id', sa.Integer(), nullable=True),
|
||||
|
@ -164,8 +182,10 @@ def upgrade():
|
|||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('created_by_id', 'identifier', name='process_instance_report_unique')
|
||||
)
|
||||
op.create_index(op.f('ix_process_instance_report_created_by_id'), 'process_instance_report', ['created_by_id'], unique=False)
|
||||
op.create_index(op.f('ix_process_instance_report_identifier'), 'process_instance_report', ['identifier'], unique=False)
|
||||
with op.batch_alter_table('process_instance_report', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_process_instance_report_created_by_id'), ['created_by_id'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_process_instance_report_identifier'), ['identifier'], unique=False)
|
||||
|
||||
op.create_table('refresh_token',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('user_id', sa.Integer(), nullable=False),
|
||||
|
@ -185,7 +205,9 @@ def upgrade():
|
|||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('key')
|
||||
)
|
||||
op.create_index(op.f('ix_secret_user_id'), 'secret', ['user_id'], unique=False)
|
||||
with op.batch_alter_table('secret', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_secret_user_id'), ['user_id'], unique=False)
|
||||
|
||||
op.create_table('task_definition',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('bpmn_process_definition_id', sa.Integer(), nullable=False),
|
||||
|
@ -199,10 +221,12 @@ def upgrade():
|
|||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('bpmn_process_definition_id', 'bpmn_identifier', name='task_definition_unique')
|
||||
)
|
||||
op.create_index(op.f('ix_task_definition_bpmn_identifier'), 'task_definition', ['bpmn_identifier'], unique=False)
|
||||
op.create_index(op.f('ix_task_definition_bpmn_name'), 'task_definition', ['bpmn_name'], unique=False)
|
||||
op.create_index(op.f('ix_task_definition_bpmn_process_definition_id'), 'task_definition', ['bpmn_process_definition_id'], unique=False)
|
||||
op.create_index(op.f('ix_task_definition_typename'), 'task_definition', ['typename'], unique=False)
|
||||
with op.batch_alter_table('task_definition', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_task_definition_bpmn_identifier'), ['bpmn_identifier'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_task_definition_bpmn_name'), ['bpmn_name'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_task_definition_bpmn_process_definition_id'), ['bpmn_process_definition_id'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_task_definition_typename'), ['typename'], unique=False)
|
||||
|
||||
op.create_table('user_group_assignment',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('user_id', sa.Integer(), nullable=False),
|
||||
|
@ -212,8 +236,10 @@ def upgrade():
|
|||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('user_id', 'group_id', name='user_group_assignment_unique')
|
||||
)
|
||||
op.create_index(op.f('ix_user_group_assignment_group_id'), 'user_group_assignment', ['group_id'], unique=False)
|
||||
op.create_index(op.f('ix_user_group_assignment_user_id'), 'user_group_assignment', ['user_id'], unique=False)
|
||||
with op.batch_alter_table('user_group_assignment', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_user_group_assignment_group_id'), ['group_id'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_user_group_assignment_user_id'), ['user_id'], unique=False)
|
||||
|
||||
op.create_table('user_group_assignment_waiting',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('username', sa.String(length=255), nullable=False),
|
||||
|
@ -222,7 +248,9 @@ def upgrade():
|
|||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('username', 'group_id', name='user_group_assignment_staged_unique')
|
||||
)
|
||||
op.create_index(op.f('ix_user_group_assignment_waiting_group_id'), 'user_group_assignment_waiting', ['group_id'], unique=False)
|
||||
with op.batch_alter_table('user_group_assignment_waiting', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_user_group_assignment_waiting_group_id'), ['group_id'], unique=False)
|
||||
|
||||
op.create_table('permission_assignment',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('principal_id', sa.Integer(), nullable=False),
|
||||
|
@ -234,8 +262,10 @@ def upgrade():
|
|||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('principal_id', 'permission_target_id', 'permission', name='permission_assignment_uniq')
|
||||
)
|
||||
op.create_index(op.f('ix_permission_assignment_permission_target_id'), 'permission_assignment', ['permission_target_id'], unique=False)
|
||||
op.create_index(op.f('ix_permission_assignment_principal_id'), 'permission_assignment', ['principal_id'], unique=False)
|
||||
with op.batch_alter_table('permission_assignment', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_permission_assignment_permission_target_id'), ['permission_target_id'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_permission_assignment_principal_id'), ['principal_id'], unique=False)
|
||||
|
||||
op.create_table('process_instance',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('process_model_identifier', sa.String(length=255), nullable=False),
|
||||
|
@ -256,14 +286,16 @@ def upgrade():
|
|||
sa.ForeignKeyConstraint(['process_initiator_id'], ['user.id'], ),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_index(op.f('ix_process_instance_bpmn_process_definition_id'), 'process_instance', ['bpmn_process_definition_id'], unique=False)
|
||||
op.create_index(op.f('ix_process_instance_bpmn_process_id'), 'process_instance', ['bpmn_process_id'], unique=False)
|
||||
op.create_index(op.f('ix_process_instance_end_in_seconds'), 'process_instance', ['end_in_seconds'], unique=False)
|
||||
op.create_index(op.f('ix_process_instance_process_initiator_id'), 'process_instance', ['process_initiator_id'], unique=False)
|
||||
op.create_index(op.f('ix_process_instance_process_model_display_name'), 'process_instance', ['process_model_display_name'], unique=False)
|
||||
op.create_index(op.f('ix_process_instance_process_model_identifier'), 'process_instance', ['process_model_identifier'], unique=False)
|
||||
op.create_index(op.f('ix_process_instance_start_in_seconds'), 'process_instance', ['start_in_seconds'], unique=False)
|
||||
op.create_index(op.f('ix_process_instance_status'), 'process_instance', ['status'], unique=False)
|
||||
with op.batch_alter_table('process_instance', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_process_instance_bpmn_process_definition_id'), ['bpmn_process_definition_id'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_process_instance_bpmn_process_id'), ['bpmn_process_id'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_process_instance_end_in_seconds'), ['end_in_seconds'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_process_instance_process_initiator_id'), ['process_initiator_id'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_process_instance_process_model_display_name'), ['process_model_display_name'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_process_instance_process_model_identifier'), ['process_model_identifier'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_process_instance_start_in_seconds'), ['start_in_seconds'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_process_instance_status'), ['status'], unique=False)
|
||||
|
||||
op.create_table('message_instance',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('process_instance_id', sa.Integer(), nullable=True),
|
||||
|
@ -281,9 +313,11 @@ def upgrade():
|
|||
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_index(op.f('ix_message_instance_process_instance_id'), 'message_instance', ['process_instance_id'], unique=False)
|
||||
op.create_index(op.f('ix_message_instance_status'), 'message_instance', ['status'], unique=False)
|
||||
op.create_index(op.f('ix_message_instance_user_id'), 'message_instance', ['user_id'], unique=False)
|
||||
with op.batch_alter_table('message_instance', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_message_instance_process_instance_id'), ['process_instance_id'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_message_instance_status'), ['status'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_message_instance_user_id'), ['user_id'], unique=False)
|
||||
|
||||
op.create_table('process_instance_event',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('task_guid', sa.String(length=36), nullable=True),
|
||||
|
@ -295,11 +329,13 @@ def upgrade():
|
|||
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_index(op.f('ix_process_instance_event_event_type'), 'process_instance_event', ['event_type'], unique=False)
|
||||
op.create_index(op.f('ix_process_instance_event_process_instance_id'), 'process_instance_event', ['process_instance_id'], unique=False)
|
||||
op.create_index(op.f('ix_process_instance_event_task_guid'), 'process_instance_event', ['task_guid'], unique=False)
|
||||
op.create_index(op.f('ix_process_instance_event_timestamp'), 'process_instance_event', ['timestamp'], unique=False)
|
||||
op.create_index(op.f('ix_process_instance_event_user_id'), 'process_instance_event', ['user_id'], unique=False)
|
||||
with op.batch_alter_table('process_instance_event', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_process_instance_event_event_type'), ['event_type'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_process_instance_event_process_instance_id'), ['process_instance_id'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_process_instance_event_task_guid'), ['task_guid'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_process_instance_event_timestamp'), ['timestamp'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_process_instance_event_user_id'), ['user_id'], unique=False)
|
||||
|
||||
op.create_table('process_instance_file_data',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('process_instance_id', sa.Integer(), nullable=False),
|
||||
|
@ -314,8 +350,10 @@ def upgrade():
|
|||
sa.ForeignKeyConstraint(['process_instance_id'], ['process_instance.id'], ),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_index(op.f('ix_process_instance_file_data_digest'), 'process_instance_file_data', ['digest'], unique=False)
|
||||
op.create_index(op.f('ix_process_instance_file_data_process_instance_id'), 'process_instance_file_data', ['process_instance_id'], unique=False)
|
||||
with op.batch_alter_table('process_instance_file_data', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_process_instance_file_data_digest'), ['digest'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_process_instance_file_data_process_instance_id'), ['process_instance_id'], unique=False)
|
||||
|
||||
op.create_table('process_instance_metadata',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('process_instance_id', sa.Integer(), nullable=False),
|
||||
|
@ -327,8 +365,10 @@ def upgrade():
|
|||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('process_instance_id', 'key', name='process_instance_metadata_unique')
|
||||
)
|
||||
op.create_index(op.f('ix_process_instance_metadata_key'), 'process_instance_metadata', ['key'], unique=False)
|
||||
op.create_index(op.f('ix_process_instance_metadata_process_instance_id'), 'process_instance_metadata', ['process_instance_id'], unique=False)
|
||||
with op.batch_alter_table('process_instance_metadata', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_process_instance_metadata_key'), ['key'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_process_instance_metadata_process_instance_id'), ['process_instance_id'], unique=False)
|
||||
|
||||
op.create_table('process_instance_queue',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('process_instance_id', sa.Integer(), nullable=False),
|
||||
|
@ -343,9 +383,11 @@ def upgrade():
|
|||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('process_instance_id')
|
||||
)
|
||||
op.create_index(op.f('ix_process_instance_queue_locked_at_in_seconds'), 'process_instance_queue', ['locked_at_in_seconds'], unique=False)
|
||||
op.create_index(op.f('ix_process_instance_queue_locked_by'), 'process_instance_queue', ['locked_by'], unique=False)
|
||||
op.create_index(op.f('ix_process_instance_queue_status'), 'process_instance_queue', ['status'], unique=False)
|
||||
with op.batch_alter_table('process_instance_queue', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_process_instance_queue_locked_at_in_seconds'), ['locked_at_in_seconds'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_process_instance_queue_locked_by'), ['locked_by'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_process_instance_queue_status'), ['status'], unique=False)
|
||||
|
||||
op.create_table('task',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('guid', sa.String(length=36), nullable=False),
|
||||
|
@ -364,12 +406,14 @@ def upgrade():
|
|||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('guid')
|
||||
)
|
||||
op.create_index(op.f('ix_task_bpmn_process_id'), 'task', ['bpmn_process_id'], unique=False)
|
||||
op.create_index(op.f('ix_task_json_data_hash'), 'task', ['json_data_hash'], unique=False)
|
||||
op.create_index(op.f('ix_task_process_instance_id'), 'task', ['process_instance_id'], unique=False)
|
||||
op.create_index(op.f('ix_task_python_env_data_hash'), 'task', ['python_env_data_hash'], unique=False)
|
||||
op.create_index(op.f('ix_task_state'), 'task', ['state'], unique=False)
|
||||
op.create_index(op.f('ix_task_task_definition_id'), 'task', ['task_definition_id'], unique=False)
|
||||
with op.batch_alter_table('task', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_task_bpmn_process_id'), ['bpmn_process_id'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_task_json_data_hash'), ['json_data_hash'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_task_process_instance_id'), ['process_instance_id'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_task_python_env_data_hash'), ['python_env_data_hash'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_task_state'), ['state'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_task_task_definition_id'), ['task_definition_id'], unique=False)
|
||||
|
||||
op.create_table('human_task',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('process_instance_id', sa.Integer(), nullable=False),
|
||||
|
@ -396,12 +440,14 @@ def upgrade():
|
|||
sa.ForeignKeyConstraint(['task_model_id'], ['task.id'], ),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_index(op.f('ix_human_task_actual_owner_id'), 'human_task', ['actual_owner_id'], unique=False)
|
||||
op.create_index(op.f('ix_human_task_completed'), 'human_task', ['completed'], unique=False)
|
||||
op.create_index(op.f('ix_human_task_completed_by_user_id'), 'human_task', ['completed_by_user_id'], unique=False)
|
||||
op.create_index(op.f('ix_human_task_lane_assignment_id'), 'human_task', ['lane_assignment_id'], unique=False)
|
||||
op.create_index(op.f('ix_human_task_process_instance_id'), 'human_task', ['process_instance_id'], unique=False)
|
||||
op.create_index(op.f('ix_human_task_task_model_id'), 'human_task', ['task_model_id'], unique=False)
|
||||
with op.batch_alter_table('human_task', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_human_task_actual_owner_id'), ['actual_owner_id'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_human_task_completed'), ['completed'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_human_task_completed_by_user_id'), ['completed_by_user_id'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_human_task_lane_assignment_id'), ['lane_assignment_id'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_human_task_process_instance_id'), ['process_instance_id'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_human_task_task_model_id'), ['task_model_id'], unique=False)
|
||||
|
||||
op.create_table('message_instance_correlation_rule',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('message_instance_id', sa.Integer(), nullable=False),
|
||||
|
@ -413,8 +459,10 @@ def upgrade():
|
|||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('message_instance_id', 'name', name='message_instance_id_name_unique')
|
||||
)
|
||||
op.create_index(op.f('ix_message_instance_correlation_rule_message_instance_id'), 'message_instance_correlation_rule', ['message_instance_id'], unique=False)
|
||||
op.create_index(op.f('ix_message_instance_correlation_rule_name'), 'message_instance_correlation_rule', ['name'], unique=False)
|
||||
with op.batch_alter_table('message_instance_correlation_rule', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_message_instance_correlation_rule_message_instance_id'), ['message_instance_id'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_message_instance_correlation_rule_name'), ['name'], unique=False)
|
||||
|
||||
op.create_table('human_task_user',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('human_task_id', sa.Integer(), nullable=False),
|
||||
|
@ -424,111 +472,161 @@ def upgrade():
|
|||
sa.PrimaryKeyConstraint('id'),
|
||||
sa.UniqueConstraint('human_task_id', 'user_id', name='human_task_user_unique')
|
||||
)
|
||||
op.create_index(op.f('ix_human_task_user_human_task_id'), 'human_task_user', ['human_task_id'], unique=False)
|
||||
op.create_index(op.f('ix_human_task_user_user_id'), 'human_task_user', ['user_id'], unique=False)
|
||||
with op.batch_alter_table('human_task_user', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_human_task_user_human_task_id'), ['human_task_id'], unique=False)
|
||||
batch_op.create_index(batch_op.f('ix_human_task_user_user_id'), ['user_id'], unique=False)
|
||||
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_index(op.f('ix_human_task_user_user_id'), table_name='human_task_user')
|
||||
op.drop_index(op.f('ix_human_task_user_human_task_id'), table_name='human_task_user')
|
||||
with op.batch_alter_table('human_task_user', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_human_task_user_user_id'))
|
||||
batch_op.drop_index(batch_op.f('ix_human_task_user_human_task_id'))
|
||||
|
||||
op.drop_table('human_task_user')
|
||||
op.drop_index(op.f('ix_message_instance_correlation_rule_name'), table_name='message_instance_correlation_rule')
|
||||
op.drop_index(op.f('ix_message_instance_correlation_rule_message_instance_id'), table_name='message_instance_correlation_rule')
|
||||
with op.batch_alter_table('message_instance_correlation_rule', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_message_instance_correlation_rule_name'))
|
||||
batch_op.drop_index(batch_op.f('ix_message_instance_correlation_rule_message_instance_id'))
|
||||
|
||||
op.drop_table('message_instance_correlation_rule')
|
||||
op.drop_index(op.f('ix_human_task_task_model_id'), table_name='human_task')
|
||||
op.drop_index(op.f('ix_human_task_process_instance_id'), table_name='human_task')
|
||||
op.drop_index(op.f('ix_human_task_lane_assignment_id'), table_name='human_task')
|
||||
op.drop_index(op.f('ix_human_task_completed_by_user_id'), table_name='human_task')
|
||||
op.drop_index(op.f('ix_human_task_completed'), table_name='human_task')
|
||||
op.drop_index(op.f('ix_human_task_actual_owner_id'), table_name='human_task')
|
||||
with op.batch_alter_table('human_task', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_human_task_task_model_id'))
|
||||
batch_op.drop_index(batch_op.f('ix_human_task_process_instance_id'))
|
||||
batch_op.drop_index(batch_op.f('ix_human_task_lane_assignment_id'))
|
||||
batch_op.drop_index(batch_op.f('ix_human_task_completed_by_user_id'))
|
||||
batch_op.drop_index(batch_op.f('ix_human_task_completed'))
|
||||
batch_op.drop_index(batch_op.f('ix_human_task_actual_owner_id'))
|
||||
|
||||
op.drop_table('human_task')
|
||||
op.drop_index(op.f('ix_task_task_definition_id'), table_name='task')
|
||||
op.drop_index(op.f('ix_task_state'), table_name='task')
|
||||
op.drop_index(op.f('ix_task_python_env_data_hash'), table_name='task')
|
||||
op.drop_index(op.f('ix_task_process_instance_id'), table_name='task')
|
||||
op.drop_index(op.f('ix_task_json_data_hash'), table_name='task')
|
||||
op.drop_index(op.f('ix_task_bpmn_process_id'), table_name='task')
|
||||
with op.batch_alter_table('task', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_task_task_definition_id'))
|
||||
batch_op.drop_index(batch_op.f('ix_task_state'))
|
||||
batch_op.drop_index(batch_op.f('ix_task_python_env_data_hash'))
|
||||
batch_op.drop_index(batch_op.f('ix_task_process_instance_id'))
|
||||
batch_op.drop_index(batch_op.f('ix_task_json_data_hash'))
|
||||
batch_op.drop_index(batch_op.f('ix_task_bpmn_process_id'))
|
||||
|
||||
op.drop_table('task')
|
||||
op.drop_index(op.f('ix_process_instance_queue_status'), table_name='process_instance_queue')
|
||||
op.drop_index(op.f('ix_process_instance_queue_locked_by'), table_name='process_instance_queue')
|
||||
op.drop_index(op.f('ix_process_instance_queue_locked_at_in_seconds'), table_name='process_instance_queue')
|
||||
with op.batch_alter_table('process_instance_queue', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_process_instance_queue_status'))
|
||||
batch_op.drop_index(batch_op.f('ix_process_instance_queue_locked_by'))
|
||||
batch_op.drop_index(batch_op.f('ix_process_instance_queue_locked_at_in_seconds'))
|
||||
|
||||
op.drop_table('process_instance_queue')
|
||||
op.drop_index(op.f('ix_process_instance_metadata_process_instance_id'), table_name='process_instance_metadata')
|
||||
op.drop_index(op.f('ix_process_instance_metadata_key'), table_name='process_instance_metadata')
|
||||
with op.batch_alter_table('process_instance_metadata', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_process_instance_metadata_process_instance_id'))
|
||||
batch_op.drop_index(batch_op.f('ix_process_instance_metadata_key'))
|
||||
|
||||
op.drop_table('process_instance_metadata')
|
||||
op.drop_index(op.f('ix_process_instance_file_data_process_instance_id'), table_name='process_instance_file_data')
|
||||
op.drop_index(op.f('ix_process_instance_file_data_digest'), table_name='process_instance_file_data')
|
||||
with op.batch_alter_table('process_instance_file_data', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_process_instance_file_data_process_instance_id'))
|
||||
batch_op.drop_index(batch_op.f('ix_process_instance_file_data_digest'))
|
||||
|
||||
op.drop_table('process_instance_file_data')
|
||||
op.drop_index(op.f('ix_process_instance_event_user_id'), table_name='process_instance_event')
|
||||
op.drop_index(op.f('ix_process_instance_event_timestamp'), table_name='process_instance_event')
|
||||
op.drop_index(op.f('ix_process_instance_event_task_guid'), table_name='process_instance_event')
|
||||
op.drop_index(op.f('ix_process_instance_event_process_instance_id'), table_name='process_instance_event')
|
||||
op.drop_index(op.f('ix_process_instance_event_event_type'), table_name='process_instance_event')
|
||||
with op.batch_alter_table('process_instance_event', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_process_instance_event_user_id'))
|
||||
batch_op.drop_index(batch_op.f('ix_process_instance_event_timestamp'))
|
||||
batch_op.drop_index(batch_op.f('ix_process_instance_event_task_guid'))
|
||||
batch_op.drop_index(batch_op.f('ix_process_instance_event_process_instance_id'))
|
||||
batch_op.drop_index(batch_op.f('ix_process_instance_event_event_type'))
|
||||
|
||||
op.drop_table('process_instance_event')
|
||||
op.drop_index(op.f('ix_message_instance_user_id'), table_name='message_instance')
|
||||
op.drop_index(op.f('ix_message_instance_status'), table_name='message_instance')
|
||||
op.drop_index(op.f('ix_message_instance_process_instance_id'), table_name='message_instance')
|
||||
with op.batch_alter_table('message_instance', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_message_instance_user_id'))
|
||||
batch_op.drop_index(batch_op.f('ix_message_instance_status'))
|
||||
batch_op.drop_index(batch_op.f('ix_message_instance_process_instance_id'))
|
||||
|
||||
op.drop_table('message_instance')
|
||||
op.drop_index(op.f('ix_process_instance_status'), table_name='process_instance')
|
||||
op.drop_index(op.f('ix_process_instance_start_in_seconds'), table_name='process_instance')
|
||||
op.drop_index(op.f('ix_process_instance_process_model_identifier'), table_name='process_instance')
|
||||
op.drop_index(op.f('ix_process_instance_process_model_display_name'), table_name='process_instance')
|
||||
op.drop_index(op.f('ix_process_instance_process_initiator_id'), table_name='process_instance')
|
||||
op.drop_index(op.f('ix_process_instance_end_in_seconds'), table_name='process_instance')
|
||||
op.drop_index(op.f('ix_process_instance_bpmn_process_id'), table_name='process_instance')
|
||||
op.drop_index(op.f('ix_process_instance_bpmn_process_definition_id'), table_name='process_instance')
|
||||
with op.batch_alter_table('process_instance', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_process_instance_status'))
|
||||
batch_op.drop_index(batch_op.f('ix_process_instance_start_in_seconds'))
|
||||
batch_op.drop_index(batch_op.f('ix_process_instance_process_model_identifier'))
|
||||
batch_op.drop_index(batch_op.f('ix_process_instance_process_model_display_name'))
|
||||
batch_op.drop_index(batch_op.f('ix_process_instance_process_initiator_id'))
|
||||
batch_op.drop_index(batch_op.f('ix_process_instance_end_in_seconds'))
|
||||
batch_op.drop_index(batch_op.f('ix_process_instance_bpmn_process_id'))
|
||||
batch_op.drop_index(batch_op.f('ix_process_instance_bpmn_process_definition_id'))
|
||||
|
||||
op.drop_table('process_instance')
|
||||
op.drop_index(op.f('ix_permission_assignment_principal_id'), table_name='permission_assignment')
|
||||
op.drop_index(op.f('ix_permission_assignment_permission_target_id'), table_name='permission_assignment')
|
||||
with op.batch_alter_table('permission_assignment', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_permission_assignment_principal_id'))
|
||||
batch_op.drop_index(batch_op.f('ix_permission_assignment_permission_target_id'))
|
||||
|
||||
op.drop_table('permission_assignment')
|
||||
op.drop_index(op.f('ix_user_group_assignment_waiting_group_id'), table_name='user_group_assignment_waiting')
|
||||
with op.batch_alter_table('user_group_assignment_waiting', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_user_group_assignment_waiting_group_id'))
|
||||
|
||||
op.drop_table('user_group_assignment_waiting')
|
||||
op.drop_index(op.f('ix_user_group_assignment_user_id'), table_name='user_group_assignment')
|
||||
op.drop_index(op.f('ix_user_group_assignment_group_id'), table_name='user_group_assignment')
|
||||
with op.batch_alter_table('user_group_assignment', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_user_group_assignment_user_id'))
|
||||
batch_op.drop_index(batch_op.f('ix_user_group_assignment_group_id'))
|
||||
|
||||
op.drop_table('user_group_assignment')
|
||||
op.drop_index(op.f('ix_task_definition_typename'), table_name='task_definition')
|
||||
op.drop_index(op.f('ix_task_definition_bpmn_process_definition_id'), table_name='task_definition')
|
||||
op.drop_index(op.f('ix_task_definition_bpmn_name'), table_name='task_definition')
|
||||
op.drop_index(op.f('ix_task_definition_bpmn_identifier'), table_name='task_definition')
|
||||
with op.batch_alter_table('task_definition', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_task_definition_typename'))
|
||||
batch_op.drop_index(batch_op.f('ix_task_definition_bpmn_process_definition_id'))
|
||||
batch_op.drop_index(batch_op.f('ix_task_definition_bpmn_name'))
|
||||
batch_op.drop_index(batch_op.f('ix_task_definition_bpmn_identifier'))
|
||||
|
||||
op.drop_table('task_definition')
|
||||
op.drop_index(op.f('ix_secret_user_id'), table_name='secret')
|
||||
with op.batch_alter_table('secret', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_secret_user_id'))
|
||||
|
||||
op.drop_table('secret')
|
||||
op.drop_table('refresh_token')
|
||||
op.drop_index(op.f('ix_process_instance_report_identifier'), table_name='process_instance_report')
|
||||
op.drop_index(op.f('ix_process_instance_report_created_by_id'), table_name='process_instance_report')
|
||||
with op.batch_alter_table('process_instance_report', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_process_instance_report_identifier'))
|
||||
batch_op.drop_index(batch_op.f('ix_process_instance_report_created_by_id'))
|
||||
|
||||
op.drop_table('process_instance_report')
|
||||
op.drop_table('principal')
|
||||
op.drop_index(op.f('ix_bpmn_process_definition_relationship_bpmn_process_definition_child_id'), table_name='bpmn_process_definition_relationship')
|
||||
op.drop_index(op.f('ix_bpmn_process_definition_relationship_bpmn_process_definition_parent_id'), table_name='bpmn_process_definition_relationship')
|
||||
with op.batch_alter_table('bpmn_process_definition_relationship', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_bpmn_process_definition_relationship_bpmn_process_definition_child_id'))
|
||||
batch_op.drop_index(batch_op.f('ix_bpmn_process_definition_relationship_bpmn_process_definition_parent_id'))
|
||||
|
||||
op.drop_table('bpmn_process_definition_relationship')
|
||||
op.drop_index(op.f('ix_bpmn_process_top_level_process_id'), table_name='bpmn_process')
|
||||
op.drop_index(op.f('ix_bpmn_process_json_data_hash'), table_name='bpmn_process')
|
||||
op.drop_index(op.f('ix_bpmn_process_direct_parent_process_id'), table_name='bpmn_process')
|
||||
op.drop_index(op.f('ix_bpmn_process_bpmn_process_definition_id'), table_name='bpmn_process')
|
||||
with op.batch_alter_table('bpmn_process', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_bpmn_process_top_level_process_id'))
|
||||
batch_op.drop_index(batch_op.f('ix_bpmn_process_json_data_hash'))
|
||||
batch_op.drop_index(batch_op.f('ix_bpmn_process_direct_parent_process_id'))
|
||||
batch_op.drop_index(batch_op.f('ix_bpmn_process_bpmn_process_definition_id'))
|
||||
|
||||
op.drop_table('bpmn_process')
|
||||
op.drop_index(op.f('ix_user_service_id'), table_name='user')
|
||||
op.drop_index(op.f('ix_user_service'), table_name='user')
|
||||
op.drop_index(op.f('ix_user_email'), table_name='user')
|
||||
with op.batch_alter_table('user', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_user_service_id'))
|
||||
batch_op.drop_index(batch_op.f('ix_user_service'))
|
||||
batch_op.drop_index(batch_op.f('ix_user_email'))
|
||||
|
||||
op.drop_table('user')
|
||||
op.drop_index(op.f('ix_spec_reference_cache_type'), table_name='spec_reference_cache')
|
||||
op.drop_index(op.f('ix_spec_reference_cache_process_model_id'), table_name='spec_reference_cache')
|
||||
op.drop_index(op.f('ix_spec_reference_cache_identifier'), table_name='spec_reference_cache')
|
||||
op.drop_index(op.f('ix_spec_reference_cache_display_name'), table_name='spec_reference_cache')
|
||||
with op.batch_alter_table('spec_reference_cache', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_spec_reference_cache_type'))
|
||||
batch_op.drop_index(batch_op.f('ix_spec_reference_cache_process_model_id'))
|
||||
batch_op.drop_index(batch_op.f('ix_spec_reference_cache_identifier'))
|
||||
batch_op.drop_index(batch_op.f('ix_spec_reference_cache_display_name'))
|
||||
|
||||
op.drop_table('spec_reference_cache')
|
||||
op.drop_table('permission_target')
|
||||
op.drop_index(op.f('ix_message_triggerable_process_model_process_model_identifier'), table_name='message_triggerable_process_model')
|
||||
op.drop_index(op.f('ix_message_triggerable_process_model_message_name'), table_name='message_triggerable_process_model')
|
||||
with op.batch_alter_table('message_triggerable_process_model', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_message_triggerable_process_model_process_model_identifier'))
|
||||
batch_op.drop_index(batch_op.f('ix_message_triggerable_process_model_message_name'))
|
||||
|
||||
op.drop_table('message_triggerable_process_model')
|
||||
op.drop_table('json_data')
|
||||
op.drop_index(op.f('ix_group_name'), table_name='group')
|
||||
op.drop_index(op.f('ix_group_identifier'), table_name='group')
|
||||
with op.batch_alter_table('group', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_group_name'))
|
||||
batch_op.drop_index(batch_op.f('ix_group_identifier'))
|
||||
|
||||
op.drop_table('group')
|
||||
op.drop_index(op.f('ix_correlation_property_cache_name'), table_name='correlation_property_cache')
|
||||
op.drop_index(op.f('ix_correlation_property_cache_message_name'), table_name='correlation_property_cache')
|
||||
with op.batch_alter_table('correlation_property_cache', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_correlation_property_cache_name'))
|
||||
batch_op.drop_index(batch_op.f('ix_correlation_property_cache_message_name'))
|
||||
|
||||
op.drop_table('correlation_property_cache')
|
||||
op.drop_index(op.f('ix_bpmn_process_definition_bpmn_name'), table_name='bpmn_process_definition')
|
||||
op.drop_index(op.f('ix_bpmn_process_definition_bpmn_identifier'), table_name='bpmn_process_definition')
|
||||
with op.batch_alter_table('bpmn_process_definition', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_bpmn_process_definition_bpmn_name'))
|
||||
batch_op.drop_index(batch_op.f('ix_bpmn_process_definition_bpmn_identifier'))
|
||||
|
||||
op.drop_table('bpmn_process_definition')
|
||||
# ### end Alembic commands ###
|
|
@ -1,36 +0,0 @@
|
|||
"""empty message
|
||||
|
||||
Revision ID: 5d8e49f9c560
|
||||
Revises: 0b5dd14bfbac
|
||||
Create Date: 2023-04-17 11:28:39.714193
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.dialects import mysql
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '5d8e49f9c560'
|
||||
down_revision = '0b5dd14bfbac'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
with op.batch_alter_table('bpmn_process_definition', schema=None) as batch_op:
|
||||
batch_op.alter_column('hash', existing_type=sa.String(length=255), new_column_name='single_process_hash')
|
||||
batch_op.add_column(sa.Column('full_process_model_hash', sa.String(length=255), nullable=True))
|
||||
batch_op.create_unique_constraint(None, ['full_process_model_hash'])
|
||||
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
with op.batch_alter_table('bpmn_process_definition', schema=None) as batch_op:
|
||||
batch_op.drop_constraint('full_process_model_hash', type_='unique')
|
||||
batch_op.drop_column('full_process_model_hash')
|
||||
batch_op.alter_column('single_process_hash', existing_type=sa.String(length=255), new_column_name='hash')
|
||||
|
||||
# ### end Alembic commands ###
|
|
@ -1898,6 +1898,14 @@ python-versions = ">=3.5"
|
|||
lint = ["docutils-stubs", "flake8", "mypy"]
|
||||
test = ["pytest"]
|
||||
|
||||
[[package]]
|
||||
name = "spiff-element-units"
|
||||
version = "0.1.0"
|
||||
description = ""
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[[package]]
|
||||
name = "SpiffWorkflow"
|
||||
version = "1.2.1"
|
||||
|
@ -1916,7 +1924,7 @@ lxml = "*"
|
|||
type = "git"
|
||||
url = "https://github.com/sartography/SpiffWorkflow"
|
||||
reference = "main"
|
||||
resolved_reference = "162a1c5f56cf12fc589a1e368704c0819bfcc0cd"
|
||||
resolved_reference = "7211e67ee0dfecbabaeb7cec8f0e0373bd7cdc10"
|
||||
|
||||
[[package]]
|
||||
name = "sqlalchemy"
|
||||
|
@ -2299,7 +2307,7 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more
|
|||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = ">=3.9,<3.12"
|
||||
content-hash = "554d5da592e80f26a3f6bb2322a397a6512c09b1a3891584d4d38a21fedc0445"
|
||||
content-hash = "994c36ab39238500b4fd05bc1ccdd2d729dd5f66749ab77b1028371147bdf753"
|
||||
|
||||
[metadata.files]
|
||||
alabaster = [
|
||||
|
@ -3661,6 +3669,19 @@ sphinxcontrib-serializinghtml = [
|
|||
{file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"},
|
||||
{file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"},
|
||||
]
|
||||
spiff-element-units = [
|
||||
{file = "spiff_element_units-0.1.0-cp39-abi3-macosx_10_7_x86_64.whl", hash = "sha256:fc34e1012a922037cf5d04c154a37119bc1ba83cc536d79fde601da42703d5f7"},
|
||||
{file = "spiff_element_units-0.1.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:664197124c2a81c780d83a60750ad4411dda22a31e0db7615007a3905393fa4b"},
|
||||
{file = "spiff_element_units-0.1.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34409c2a1f24dfca99afafd3b1caa9e2fba66c81864954f7f9ebf8030bc632c8"},
|
||||
{file = "spiff_element_units-0.1.0-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dcc1307447f30f597d31224d855c979f5c8cca5906792cbf7d9418ee2bcac54b"},
|
||||
{file = "spiff_element_units-0.1.0-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f40788203884db9d15e1e2c6b5d7b019b38606750f3df75f66d6c14fe492b5b4"},
|
||||
{file = "spiff_element_units-0.1.0-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78afa90e8ee48dfe84b8accb3399212297cb2b05f7e5288ae57614f68a2cffd8"},
|
||||
{file = "spiff_element_units-0.1.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aab909b3d8f896eb2f2ed64273a7e013564a708e875883dafe76cdb34e459cb3"},
|
||||
{file = "spiff_element_units-0.1.0-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a264c4ad717d83fe1d7b31d4c9a26143a3a9eff9cfdb09216f4fc1ef029e178"},
|
||||
{file = "spiff_element_units-0.1.0-cp39-abi3-win32.whl", hash = "sha256:9b2e25b8b18ae006c39cd0b8bac11b08d60bf0e53b60a9cca9a3cec3750f0176"},
|
||||
{file = "spiff_element_units-0.1.0-cp39-abi3-win_amd64.whl", hash = "sha256:825594fa95496db3a9a7826c9cbf95b90b6a5676838bbd9fe23c5ff32a2d2920"},
|
||||
{file = "spiff_element_units-0.1.0.tar.gz", hash = "sha256:807e207562220f350cd0f0b6a46484c7b976c4effe4b194701179add7abe871a"},
|
||||
]
|
||||
SpiffWorkflow = []
|
||||
sqlalchemy = [
|
||||
{file = "SQLAlchemy-2.0.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:734805708632e3965c2c40081f9a59263c29ffa27cba9b02d4d92dfd57ba869f"},
|
||||
|
|
|
@ -86,6 +86,7 @@ prometheus-flask-exporter = "^0.22.3"
|
|||
safety = "^2.3.5"
|
||||
sqlalchemy = "^2.0.7"
|
||||
marshmallow-sqlalchemy = "^0.29.0"
|
||||
spiff-element-units = "^0.1.0"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
pytest = "^7.1.2"
|
||||
|
|
|
@ -1980,10 +1980,34 @@ paths:
|
|||
description: Show the detailed view, which includes all log entries
|
||||
schema:
|
||||
type: boolean
|
||||
- name: bpmn_name
|
||||
in: query
|
||||
required: false
|
||||
description: The bpmn name of the task to search for.
|
||||
schema:
|
||||
type: string
|
||||
- name: bpmn_identifier
|
||||
in: query
|
||||
required: false
|
||||
description: The bpmn identifier of the task to search for.
|
||||
schema:
|
||||
type: string
|
||||
- name: task_type
|
||||
in: query
|
||||
required: false
|
||||
description: The task type of the task to search for.
|
||||
schema:
|
||||
type: string
|
||||
- name: event_type
|
||||
in: query
|
||||
required: false
|
||||
description: The type of the event to search for.
|
||||
schema:
|
||||
type: string
|
||||
get:
|
||||
tags:
|
||||
- Process Instances
|
||||
operationId: spiffworkflow_backend.routes.process_instances_controller.process_instance_log_list
|
||||
- Process Instance Events
|
||||
operationId: spiffworkflow_backend.routes.process_instance_events_controller.log_list
|
||||
summary: returns a list of logs associated with the process instance
|
||||
responses:
|
||||
"200":
|
||||
|
@ -1993,6 +2017,20 @@ paths:
|
|||
schema:
|
||||
$ref: "#/components/schemas/ProcessInstanceLog"
|
||||
|
||||
/logs/types:
|
||||
get:
|
||||
tags:
|
||||
- Process Instance Events
|
||||
operationId: spiffworkflow_backend.routes.process_instance_events_controller.types
|
||||
summary: returns a list of task types and event typs. useful for building log queries.
|
||||
responses:
|
||||
"200":
|
||||
description: list of types
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ProcessInstanceLog"
|
||||
|
||||
/secrets:
|
||||
parameters:
|
||||
- name: page
|
||||
|
|
|
@ -145,3 +145,11 @@ SPIFFWORKFLOW_BACKEND_ENGINE_STEP_DEFAULT_STRATEGY_WEB = environ.get(
|
|||
|
||||
# this is only used in CI. use SPIFFWORKFLOW_BACKEND_DATABASE_URI instead for real configuration
|
||||
SPIFFWORKFLOW_BACKEND_DATABASE_PASSWORD = environ.get("SPIFFWORKFLOW_BACKEND_DATABASE_PASSWORD", default=None)
|
||||
|
||||
SPIFFWORKFLOW_BACKEND_FEATURE_ELEMENT_UNITS_ENABLED = (
|
||||
environ.get("SPIFFWORKFLOW_BACKEND_FEATURE_ELEMENT_UNITS_ENABLED", default="false") == "true"
|
||||
)
|
||||
|
||||
SPIFFWORKFLOW_BACKEND_ELEMENT_UNITS_CACHE_DIR = environ.get(
|
||||
"SPIFFWORKFLOW_BACKEND_ELEMENT_UNITS_CACHE_DIR", default=None
|
||||
)
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
"""Spiff_enum."""
|
||||
import enum
|
||||
|
||||
|
||||
class SpiffEnum(enum.Enum):
|
||||
"""SpiffEnum."""
|
||||
|
||||
@classmethod
|
||||
def list(cls) -> list[str]:
|
||||
"""List."""
|
||||
return [el.value for el in cls]
|
||||
|
|
|
@ -2,6 +2,8 @@ from __future__ import annotations
|
|||
|
||||
from dataclasses import dataclass
|
||||
|
||||
from sqlalchemy import UniqueConstraint
|
||||
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||
|
||||
|
@ -15,17 +17,25 @@ from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
|||
@dataclass
|
||||
class BpmnProcessDefinitionModel(SpiffworkflowBaseDBModel):
|
||||
__tablename__ = "bpmn_process_definition"
|
||||
__table_args__ = (
|
||||
UniqueConstraint(
|
||||
"full_process_model_hash",
|
||||
"single_process_hash",
|
||||
name="process_hash_unique",
|
||||
),
|
||||
)
|
||||
|
||||
id: int = db.Column(db.Integer, primary_key=True)
|
||||
|
||||
# this is a sha256 hash of spec and serializer_version
|
||||
# note that a call activity is its own row in this table, with its own hash,
|
||||
# and therefore it only gets stored once per version, and can be reused
|
||||
# by multiple calling processes.
|
||||
single_process_hash: str = db.Column(db.String(255), nullable=False, unique=True)
|
||||
single_process_hash: str = db.Column(db.String(255), nullable=False)
|
||||
|
||||
# only the top level parent will have this set
|
||||
# it includes all subprocesses and call activities
|
||||
full_process_model_hash: str | None = db.Column(db.String(255), nullable=True, unique=True, default=None)
|
||||
full_process_model_hash: str | None = db.Column(db.String(255), nullable=True, unique=True)
|
||||
|
||||
bpmn_identifier: str = db.Column(db.String(255), nullable=False, index=True)
|
||||
bpmn_name: str = db.Column(db.String(255), nullable=True, index=True)
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
from typing import Optional
|
||||
|
||||
import flask.wrappers
|
||||
from flask import jsonify
|
||||
from flask import make_response
|
||||
from sqlalchemy import and_
|
||||
|
||||
from spiffworkflow_backend.models.bpmn_process_definition import BpmnProcessDefinitionModel
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from spiffworkflow_backend.models.process_instance_event import ProcessInstanceEventModel
|
||||
from spiffworkflow_backend.models.process_instance_event import ProcessInstanceEventType
|
||||
from spiffworkflow_backend.models.task import TaskModel # noqa: F401
|
||||
from spiffworkflow_backend.models.task_definition import TaskDefinitionModel
|
||||
from spiffworkflow_backend.models.user import UserModel
|
||||
from spiffworkflow_backend.routes.process_api_blueprint import (
|
||||
_find_process_instance_by_id_or_raise,
|
||||
)
|
||||
|
||||
|
||||
def log_list(
|
||||
modified_process_model_identifier: str,
|
||||
process_instance_id: int,
|
||||
page: int = 1,
|
||||
per_page: int = 100,
|
||||
detailed: bool = False,
|
||||
bpmn_name: Optional[str] = None,
|
||||
bpmn_identifier: Optional[str] = None,
|
||||
task_type: Optional[str] = None,
|
||||
event_type: Optional[str] = None,
|
||||
) -> flask.wrappers.Response:
|
||||
# to make sure the process instance exists
|
||||
process_instance = _find_process_instance_by_id_or_raise(process_instance_id)
|
||||
|
||||
log_query = (
|
||||
ProcessInstanceEventModel.query.filter_by(process_instance_id=process_instance.id)
|
||||
.outerjoin(TaskModel, TaskModel.guid == ProcessInstanceEventModel.task_guid)
|
||||
.outerjoin(TaskDefinitionModel, TaskDefinitionModel.id == TaskModel.task_definition_id)
|
||||
.outerjoin(
|
||||
BpmnProcessDefinitionModel,
|
||||
BpmnProcessDefinitionModel.id == TaskDefinitionModel.bpmn_process_definition_id,
|
||||
)
|
||||
)
|
||||
if not detailed:
|
||||
log_query = log_query.filter(
|
||||
and_(
|
||||
TaskModel.state.in_(["COMPLETED"]), # type: ignore
|
||||
TaskDefinitionModel.typename.in_(["IntermediateThrowEvent"]), # type: ignore
|
||||
)
|
||||
)
|
||||
|
||||
if bpmn_name is not None:
|
||||
log_query = log_query.filter(TaskDefinitionModel.bpmn_name == bpmn_name)
|
||||
if bpmn_identifier is not None:
|
||||
log_query = log_query.filter(TaskDefinitionModel.bpmn_identifier == bpmn_identifier)
|
||||
if task_type is not None:
|
||||
log_query = log_query.filter(TaskDefinitionModel.typename == task_type)
|
||||
if event_type is not None:
|
||||
log_query = log_query.filter(ProcessInstanceEventModel.event_type == event_type)
|
||||
|
||||
logs = (
|
||||
log_query.order_by(
|
||||
ProcessInstanceEventModel.timestamp.desc(), ProcessInstanceEventModel.id.desc() # type: ignore
|
||||
)
|
||||
.outerjoin(UserModel, UserModel.id == ProcessInstanceEventModel.user_id)
|
||||
.add_columns(
|
||||
TaskModel.guid.label("spiff_task_guid"), # type: ignore
|
||||
UserModel.username,
|
||||
BpmnProcessDefinitionModel.bpmn_identifier.label("bpmn_process_definition_identifier"), # type: ignore
|
||||
BpmnProcessDefinitionModel.bpmn_name.label("bpmn_process_definition_name"), # type: ignore
|
||||
TaskDefinitionModel.bpmn_identifier.label("task_definition_identifier"), # type: ignore
|
||||
TaskDefinitionModel.bpmn_name.label("task_definition_name"), # type: ignore
|
||||
TaskDefinitionModel.typename.label("bpmn_task_type"), # type: ignore
|
||||
)
|
||||
.paginate(page=page, per_page=per_page, error_out=False)
|
||||
)
|
||||
|
||||
response_json = {
|
||||
"results": logs.items,
|
||||
"pagination": {
|
||||
"count": len(logs.items),
|
||||
"total": logs.total,
|
||||
"pages": logs.pages,
|
||||
},
|
||||
}
|
||||
|
||||
return make_response(jsonify(response_json), 200)
|
||||
|
||||
|
||||
def types() -> flask.wrappers.Response:
|
||||
query = db.session.query(TaskDefinitionModel.typename).distinct() # type: ignore
|
||||
task_types = [t.typename for t in query]
|
||||
event_types = ProcessInstanceEventType.list()
|
||||
return make_response(jsonify({"task_types": task_types, "event_types": event_types}), 200)
|
|
@ -30,9 +30,6 @@ from spiffworkflow_backend.models.process_instance import (
|
|||
)
|
||||
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
|
||||
from spiffworkflow_backend.models.process_instance import ProcessInstanceModelSchema
|
||||
from spiffworkflow_backend.models.process_instance_event import (
|
||||
ProcessInstanceEventModel,
|
||||
)
|
||||
from spiffworkflow_backend.models.process_instance_metadata import (
|
||||
ProcessInstanceMetadataModel,
|
||||
)
|
||||
|
@ -47,7 +44,6 @@ from spiffworkflow_backend.models.spec_reference import SpecReferenceCache
|
|||
from spiffworkflow_backend.models.spec_reference import SpecReferenceNotFoundError
|
||||
from spiffworkflow_backend.models.task import TaskModel
|
||||
from spiffworkflow_backend.models.task_definition import TaskDefinitionModel
|
||||
from spiffworkflow_backend.models.user import UserModel
|
||||
from spiffworkflow_backend.routes.process_api_blueprint import (
|
||||
_find_process_instance_by_id_or_raise,
|
||||
)
|
||||
|
@ -224,63 +220,6 @@ def process_instance_resume(
|
|||
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def process_instance_log_list(
|
||||
modified_process_model_identifier: str,
|
||||
process_instance_id: int,
|
||||
page: int = 1,
|
||||
per_page: int = 100,
|
||||
detailed: bool = False,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_log_list."""
|
||||
# to make sure the process instance exists
|
||||
process_instance = _find_process_instance_by_id_or_raise(process_instance_id)
|
||||
|
||||
log_query = (
|
||||
ProcessInstanceEventModel.query.filter_by(process_instance_id=process_instance.id)
|
||||
.outerjoin(TaskModel, TaskModel.guid == ProcessInstanceEventModel.task_guid)
|
||||
.outerjoin(TaskDefinitionModel, TaskDefinitionModel.id == TaskModel.task_definition_id)
|
||||
.outerjoin(
|
||||
BpmnProcessDefinitionModel,
|
||||
BpmnProcessDefinitionModel.id == TaskDefinitionModel.bpmn_process_definition_id,
|
||||
)
|
||||
)
|
||||
if not detailed:
|
||||
log_query = log_query.filter(
|
||||
and_(
|
||||
TaskModel.state.in_(["COMPLETED"]), # type: ignore
|
||||
TaskDefinitionModel.typename.in_(["IntermediateThrowEvent"]), # type: ignore
|
||||
)
|
||||
)
|
||||
|
||||
logs = (
|
||||
log_query.order_by(
|
||||
ProcessInstanceEventModel.timestamp.desc(), ProcessInstanceEventModel.id.desc() # type: ignore
|
||||
)
|
||||
.outerjoin(UserModel, UserModel.id == ProcessInstanceEventModel.user_id)
|
||||
.add_columns(
|
||||
TaskModel.guid.label("spiff_task_guid"), # type: ignore
|
||||
UserModel.username,
|
||||
BpmnProcessDefinitionModel.bpmn_identifier.label("bpmn_process_definition_identifier"), # type: ignore
|
||||
BpmnProcessDefinitionModel.bpmn_name.label("bpmn_process_definition_name"), # type: ignore
|
||||
TaskDefinitionModel.bpmn_identifier.label("task_definition_identifier"), # type: ignore
|
||||
TaskDefinitionModel.bpmn_name.label("task_definition_name"), # type: ignore
|
||||
TaskDefinitionModel.typename.label("bpmn_task_type"), # type: ignore
|
||||
)
|
||||
.paginate(page=page, per_page=per_page, error_out=False)
|
||||
)
|
||||
|
||||
response_json = {
|
||||
"results": logs.items,
|
||||
"pagination": {
|
||||
"count": len(logs.items),
|
||||
"total": logs.total,
|
||||
"pages": logs.pages,
|
||||
},
|
||||
}
|
||||
|
||||
return make_response(jsonify(response_json), 200)
|
||||
|
||||
|
||||
def process_instance_list_for_me(
|
||||
process_model_identifier: Optional[str] = None,
|
||||
page: int = 1,
|
||||
|
@ -691,19 +630,29 @@ def process_instance_task_list(
|
|||
task_models = task_model_query.all()
|
||||
if most_recent_tasks_only:
|
||||
most_recent_tasks = {}
|
||||
most_recent_subprocesses = set()
|
||||
|
||||
# if you have a loop and there is a subprocess, and you are going around for the second time,
|
||||
# ignore the tasks in the "first loop" subprocess
|
||||
relevant_subprocess_guids = {bpmn_process_guid, None}
|
||||
|
||||
bpmn_process_cache: dict[str, list[str]] = {}
|
||||
for task_model in task_models:
|
||||
bpmn_process_guid = task_model.bpmn_process_guid or "TOP"
|
||||
row_key = f"{bpmn_process_guid}:::{task_model.bpmn_identifier}"
|
||||
if task_model.bpmn_process_guid not in bpmn_process_cache:
|
||||
bpmn_process = BpmnProcessModel.query.filter_by(guid=task_model.bpmn_process_guid).first()
|
||||
full_bpmn_process_path = TaskService.full_bpmn_process_path(bpmn_process)
|
||||
bpmn_process_cache[task_model.bpmn_process_guid] = full_bpmn_process_path
|
||||
else:
|
||||
full_bpmn_process_path = bpmn_process_cache[task_model.bpmn_process_guid]
|
||||
|
||||
row_key = f"{':::'.join(full_bpmn_process_path)}:::{task_model.bpmn_identifier}"
|
||||
if row_key not in most_recent_tasks:
|
||||
most_recent_tasks[row_key] = task_model
|
||||
if task_model.typename in ["SubWorkflowTask", "CallActivity"]:
|
||||
most_recent_subprocesses.add(task_model.guid)
|
||||
|
||||
relevant_subprocess_guids.add(task_model.guid)
|
||||
task_models = [
|
||||
task_model
|
||||
for task_model in most_recent_tasks.values()
|
||||
if task_model.bpmn_process_guid in most_recent_subprocesses or task_model.bpmn_process_guid is None
|
||||
if task_model.bpmn_process_guid in relevant_subprocess_guids
|
||||
]
|
||||
|
||||
if to_task_model is not None:
|
||||
|
|
|
@ -567,6 +567,7 @@ class AuthorizationService:
|
|||
permissions_to_assign.append(PermissionToAssign(permission="read", target_uri="/processes"))
|
||||
permissions_to_assign.append(PermissionToAssign(permission="read", target_uri="/service-tasks"))
|
||||
permissions_to_assign.append(PermissionToAssign(permission="read", target_uri="/user-groups/for-current-user"))
|
||||
permissions_to_assign.append(PermissionToAssign(permission="read", target_uri="/logs/types"))
|
||||
permissions_to_assign.append(PermissionToAssign(permission="create", target_uri="/users/exists/by-username"))
|
||||
permissions_to_assign.append(
|
||||
PermissionToAssign(permission="read", target_uri="/process-instances/find-by-id/*")
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
import json
|
||||
from typing import Any
|
||||
from typing import Dict
|
||||
from typing import Optional
|
||||
|
||||
from flask import current_app
|
||||
|
||||
BpmnSpecDict = Dict[str, Any]
|
||||
|
||||
|
||||
class ElementUnitsService:
|
||||
"""Feature gated glue between the backend and spiff-element-units."""
|
||||
|
||||
@classmethod
|
||||
def _cache_dir(cls) -> Optional[str]:
|
||||
return current_app.config["SPIFFWORKFLOW_BACKEND_ELEMENT_UNITS_CACHE_DIR"] # type: ignore
|
||||
|
||||
@classmethod
|
||||
def _enabled(cls) -> bool:
|
||||
enabled = current_app.config["SPIFFWORKFLOW_BACKEND_FEATURE_ELEMENT_UNITS_ENABLED"]
|
||||
return enabled and cls._cache_dir() is not None
|
||||
|
||||
@classmethod
|
||||
def cache_element_units_for_workflow(cls, cache_key: str, bpmn_spec_dict: BpmnSpecDict) -> None:
|
||||
if not cls._enabled():
|
||||
return None
|
||||
|
||||
try:
|
||||
# for now we are importing inside each of these functions, not sure the best
|
||||
# way to do this in an overall feature flagged strategy but this gets things
|
||||
# moving
|
||||
import spiff_element_units # type: ignore
|
||||
|
||||
bpmn_spec_json = json.dumps(bpmn_spec_dict)
|
||||
spiff_element_units.cache_element_units_for_workflow(cls._cache_dir(), cache_key, bpmn_spec_json)
|
||||
except Exception as e:
|
||||
current_app.logger.exception(e)
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def workflow_from_cached_element_unit(cls, cache_key: str, element_id: str) -> Optional[BpmnSpecDict]:
|
||||
if not cls._enabled():
|
||||
return None
|
||||
|
||||
try:
|
||||
# for now we are importing inside each of these functions, not sure the best
|
||||
# way to do this in an overall feature flagged strategy but this gets things
|
||||
# moving
|
||||
import spiff_element_units
|
||||
|
||||
bpmn_spec_json = spiff_element_units.workflow_from_cached_element_unit(
|
||||
cls._cache_dir(), cache_key, element_id
|
||||
)
|
||||
return json.loads(bpmn_spec_json) # type: ignore
|
||||
except Exception as e:
|
||||
current_app.logger.exception(e)
|
||||
return None
|
|
@ -129,7 +129,7 @@ def setup_logger(app: Flask) -> None:
|
|||
spiff_logger_filehandler.setFormatter(log_formatter)
|
||||
|
||||
# these loggers have been deemed too verbose to be useful
|
||||
garbage_loggers_to_exclude = ["connexion"]
|
||||
garbage_loggers_to_exclude = ["connexion", "flask_cors.extension"]
|
||||
|
||||
# make all loggers act the same
|
||||
for name in logging.root.manager.loggerDict:
|
||||
|
|
|
@ -91,6 +91,9 @@ from spiffworkflow_backend.models.task_definition import TaskDefinitionModel
|
|||
from spiffworkflow_backend.models.user import UserModel
|
||||
from spiffworkflow_backend.scripts.script import Script
|
||||
from spiffworkflow_backend.services.custom_parser import MyCustomParser
|
||||
from spiffworkflow_backend.services.element_units_service import (
|
||||
ElementUnitsService,
|
||||
)
|
||||
from spiffworkflow_backend.services.file_system_service import FileSystemService
|
||||
from spiffworkflow_backend.services.process_instance_queue_service import ProcessInstanceQueueService
|
||||
from spiffworkflow_backend.services.process_model_service import ProcessModelService
|
||||
|
@ -673,6 +676,25 @@ class ProcessInstanceProcessor:
|
|||
bpmn_definition_to_task_definitions_mappings,
|
||||
)
|
||||
|
||||
#
|
||||
# see if we have any cached element units and if so step on the spec and subprocess_specs.
|
||||
# in the early stages of development this will return the full workflow when the feature
|
||||
# flag is set to on. as time goes we will need to think about how this plays in with the
|
||||
# bpmn definition tables more.
|
||||
#
|
||||
|
||||
element_unit_process_dict = None
|
||||
full_process_model_hash = bpmn_process_definition.full_process_model_hash
|
||||
|
||||
if full_process_model_hash is not None:
|
||||
element_unit_process_dict = ElementUnitsService.workflow_from_cached_element_unit(
|
||||
full_process_model_hash,
|
||||
bpmn_process_definition.bpmn_identifier,
|
||||
)
|
||||
if element_unit_process_dict is not None:
|
||||
spiff_bpmn_process_dict["spec"] = element_unit_process_dict["spec"]
|
||||
spiff_bpmn_process_dict["subprocess_specs"] = element_unit_process_dict["subprocess_specs"]
|
||||
|
||||
bpmn_process = process_instance_model.bpmn_process
|
||||
if bpmn_process is not None:
|
||||
single_bpmn_process_dict = cls._get_bpmn_process_dict(bpmn_process, get_tasks=True)
|
||||
|
@ -1073,6 +1095,26 @@ class ProcessInstanceProcessor:
|
|||
)
|
||||
self.process_instance_model.bpmn_process_definition = bpmn_process_definition_parent
|
||||
|
||||
#
|
||||
# builds and caches the element units for the parent bpmn process defintion. these
|
||||
# element units can then be queried using the same hash for later execution.
|
||||
#
|
||||
# TODO: this seems to be run each time a process instance is started, so element
|
||||
# units will only be queried after a save/resume point. the hash used as the key
|
||||
# can be anything, so possibly some hash of all files required to form the process
|
||||
# definition and their hashes could be used? Not sure how that plays in with the
|
||||
# bpmn_process_defintion hash though.
|
||||
#
|
||||
|
||||
# TODO: first time through for an instance the bpmn_spec_dict seems to get mutated,
|
||||
# so for now we don't seed the cache until the second instance. not immediately a
|
||||
# problem and can be part of the larger discussion mentioned in the TODO above.
|
||||
|
||||
full_process_model_hash = bpmn_process_definition_parent.full_process_model_hash
|
||||
|
||||
if full_process_model_hash is not None and "task_specs" in bpmn_spec_dict["spec"]:
|
||||
ElementUnitsService.cache_element_units_for_workflow(full_process_model_hash, bpmn_spec_dict)
|
||||
|
||||
def save(self) -> None:
|
||||
"""Saves the current state of this processor to the database."""
|
||||
self.process_instance_model.spiff_serializer_version = self.SERIALIZER_VERSION
|
||||
|
|
|
@ -617,6 +617,10 @@ class ProcessInstanceReportService:
|
|||
HumanTaskUserModel,
|
||||
and_(HumanTaskUserModel.human_task_id == HumanTaskModel.id, HumanTaskUserModel.user_id == user.id),
|
||||
)
|
||||
if report_filter.has_active_status:
|
||||
process_instance_query = process_instance_query.filter(
|
||||
HumanTaskModel.completed.is_(False) # type: ignore
|
||||
)
|
||||
|
||||
if report_filter.with_tasks_assigned_to_my_group is True:
|
||||
group_model_join_conditions = [GroupModel.id == HumanTaskModel.lane_assignment_id]
|
||||
|
|
|
@ -511,6 +511,17 @@ class TaskService:
|
|||
return (bpmn_processes + b, [parent_task_model] + t)
|
||||
return (bpmn_processes, task_models)
|
||||
|
||||
@classmethod
|
||||
def full_bpmn_process_path(cls, bpmn_process: BpmnProcessModel) -> list[str]:
|
||||
"""Returns a list of bpmn process identifiers pointing the given bpmn_process."""
|
||||
bpmn_process_identifiers: list[str] = [bpmn_process.bpmn_process_definition.bpmn_identifier]
|
||||
if bpmn_process.direct_parent_process_id is not None:
|
||||
parent_bpmn_process = BpmnProcessModel.query.filter_by(id=bpmn_process.direct_parent_process_id).first()
|
||||
if parent_bpmn_process is not None:
|
||||
# always prepend new identifiers since they come first in the path
|
||||
bpmn_process_identifiers = cls.full_bpmn_process_path(parent_bpmn_process) + bpmn_process_identifiers
|
||||
return bpmn_process_identifiers
|
||||
|
||||
@classmethod
|
||||
def reset_task_model_dict(
|
||||
cls,
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
{
|
||||
"serializer_version": "spiff-element-units-integration",
|
||||
"spec": {
|
||||
"correlation_keys": {},
|
||||
"data_objects": {},
|
||||
"description": "No Tasks",
|
||||
"file": "tests/data/process-models/test-cases/no-tasks/no-tasks.bpmn",
|
||||
"io_specification": null,
|
||||
"name": "no_tasks",
|
||||
"task_specs": {
|
||||
"End": {
|
||||
"description": "",
|
||||
"id": "no_tasks_3",
|
||||
"inputs": [
|
||||
"no_tasks.EndJoin"
|
||||
],
|
||||
"internal": false,
|
||||
"lookahead": 2,
|
||||
"manual": false,
|
||||
"name": "End",
|
||||
"outputs": [],
|
||||
"typename": "Simple"
|
||||
},
|
||||
"Event_0qq9il3": {
|
||||
"data_input_associations": [],
|
||||
"data_output_associations": [],
|
||||
"description": null,
|
||||
"documentation": null,
|
||||
"event_definition": {
|
||||
"external": false,
|
||||
"internal": false,
|
||||
"typename": "NoneEventDefinition"
|
||||
},
|
||||
"extensions": {},
|
||||
"id": "no_tasks_5",
|
||||
"inputs": [
|
||||
"StartEvent_1"
|
||||
],
|
||||
"internal": false,
|
||||
"io_specification": null,
|
||||
"lane": null,
|
||||
"lookahead": 2,
|
||||
"manual": false,
|
||||
"name": "Event_0qq9il3",
|
||||
"outputs": [
|
||||
"no_tasks.EndJoin"
|
||||
],
|
||||
"position": {
|
||||
"x": 272.0,
|
||||
"y": 159.0
|
||||
},
|
||||
"typename": "EndEvent"
|
||||
},
|
||||
"Start": {
|
||||
"description": "",
|
||||
"id": "no_tasks_1",
|
||||
"inputs": [],
|
||||
"internal": false,
|
||||
"lookahead": 2,
|
||||
"manual": false,
|
||||
"name": "Start",
|
||||
"outputs": [
|
||||
"StartEvent_1"
|
||||
],
|
||||
"typename": "StartTask"
|
||||
},
|
||||
"StartEvent_1": {
|
||||
"data_input_associations": [],
|
||||
"data_output_associations": [],
|
||||
"description": null,
|
||||
"documentation": null,
|
||||
"event_definition": {
|
||||
"external": false,
|
||||
"internal": false,
|
||||
"typename": "NoneEventDefinition"
|
||||
},
|
||||
"extensions": {},
|
||||
"id": "no_tasks_4",
|
||||
"inputs": [
|
||||
"Start"
|
||||
],
|
||||
"internal": false,
|
||||
"io_specification": null,
|
||||
"lane": null,
|
||||
"lookahead": 2,
|
||||
"manual": false,
|
||||
"name": "StartEvent_1",
|
||||
"outputs": [
|
||||
"Event_0qq9il3"
|
||||
],
|
||||
"position": {
|
||||
"x": 179.0,
|
||||
"y": 159.0
|
||||
},
|
||||
"typename": "StartEvent"
|
||||
},
|
||||
"no_tasks.EndJoin": {
|
||||
"description": "",
|
||||
"id": "no_tasks_2",
|
||||
"inputs": [
|
||||
"Event_0qq9il3"
|
||||
],
|
||||
"internal": false,
|
||||
"lookahead": 2,
|
||||
"manual": false,
|
||||
"name": "no_tasks.EndJoin",
|
||||
"outputs": [
|
||||
"End"
|
||||
],
|
||||
"typename": "_EndJoin"
|
||||
}
|
||||
},
|
||||
"typename": "BpmnProcessSpec"
|
||||
},
|
||||
"subprocess_specs": {}
|
||||
}
|
|
@ -275,6 +275,7 @@ class TestAuthorizationService(BaseTest):
|
|||
) -> None:
|
||||
"""Test_explode_permissions_basic."""
|
||||
expected_permissions = [
|
||||
("/logs/types", "read"),
|
||||
("/process-instances/find-by-id/*", "read"),
|
||||
("/process-instances/for-me", "read"),
|
||||
("/process-instances/reports/*", "create"),
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
import json
|
||||
import os
|
||||
import tempfile
|
||||
from typing import Generator
|
||||
|
||||
import pytest
|
||||
from flask.app import Flask
|
||||
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
|
||||
|
||||
from spiffworkflow_backend.services.element_units_service import BpmnSpecDict
|
||||
from spiffworkflow_backend.services.element_units_service import ElementUnitsService
|
||||
|
||||
#
|
||||
# we don't want to fully flex every aspect of the spiff-element-units
|
||||
# library here, mainly just checking that our interaction with it is
|
||||
# as expected.
|
||||
#
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def app_no_cache_dir(app: Flask) -> Generator[Flask, None, None]:
|
||||
app.config["SPIFFWORKFLOW_BACKEND_ELEMENT_UNITS_CACHE_DIR"] = None
|
||||
yield app
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def app_some_cache_dir(app: Flask) -> Generator[Flask, None, None]:
|
||||
app.config["SPIFFWORKFLOW_BACKEND_ELEMENT_UNITS_CACHE_DIR"] = "some_cache_dir"
|
||||
yield app
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def app_disabled(app: Flask) -> Generator[Flask, None, None]:
|
||||
app.config["SPIFFWORKFLOW_BACKEND_FEATURE_ELEMENT_UNITS_ENABLED"] = False
|
||||
yield app
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def app_enabled(app_some_cache_dir: Flask) -> Generator[Flask, None, None]:
|
||||
app_some_cache_dir.config["SPIFFWORKFLOW_BACKEND_FEATURE_ELEMENT_UNITS_ENABLED"] = True
|
||||
yield app_some_cache_dir
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def app_enabled_tmp_cache_dir(app_enabled: Flask) -> Generator[Flask, None, None]:
|
||||
with tempfile.TemporaryDirectory() as tmpdirname:
|
||||
app_enabled.config["SPIFFWORKFLOW_BACKEND_ELEMENT_UNITS_CACHE_DIR"] = tmpdirname
|
||||
yield app_enabled
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def example_specs_dict(app: Flask) -> Generator[BpmnSpecDict, None, None]:
|
||||
path = os.path.join(app.instance_path, "..", "..", "tests", "data", "specs-json", "no-tasks.json")
|
||||
with open(path) as f:
|
||||
yield json.loads(f.read())
|
||||
|
||||
|
||||
class TestElementUnitsService(BaseTest):
|
||||
"""Tests the ElementUnitsService."""
|
||||
|
||||
def test_cache_dir_env_is_respected(
|
||||
self,
|
||||
app_some_cache_dir: Flask,
|
||||
) -> None:
|
||||
assert ElementUnitsService._cache_dir() == "some_cache_dir"
|
||||
|
||||
def test_feature_disabled_if_env_is_false(
|
||||
self,
|
||||
app_disabled: Flask,
|
||||
) -> None:
|
||||
assert not ElementUnitsService._enabled()
|
||||
|
||||
def test_feature_enabled_if_env_is_true(
|
||||
self,
|
||||
app_enabled: Flask,
|
||||
) -> None:
|
||||
assert ElementUnitsService._enabled()
|
||||
|
||||
def test_is_disabled_when_no_cache_dir(
|
||||
self,
|
||||
app_no_cache_dir: Flask,
|
||||
) -> None:
|
||||
assert not ElementUnitsService._enabled()
|
||||
|
||||
def test_ok_to_cache_when_disabled(
|
||||
self,
|
||||
app_disabled: Flask,
|
||||
) -> None:
|
||||
result = ElementUnitsService.cache_element_units_for_workflow("", {})
|
||||
assert result is None
|
||||
|
||||
def test_ok_to_read_workflow_from_cached_element_unit_when_disabled(
|
||||
self,
|
||||
app_disabled: Flask,
|
||||
) -> None:
|
||||
result = ElementUnitsService.workflow_from_cached_element_unit("", "")
|
||||
assert result is None
|
||||
|
||||
def test_can_write_to_cache(
|
||||
self,
|
||||
app_enabled_tmp_cache_dir: Flask,
|
||||
example_specs_dict: BpmnSpecDict,
|
||||
) -> None:
|
||||
result = ElementUnitsService.cache_element_units_for_workflow("testing", example_specs_dict)
|
||||
assert result is None
|
||||
|
||||
def test_can_write_to_cache_multiple_times(
|
||||
self,
|
||||
app_enabled_tmp_cache_dir: Flask,
|
||||
example_specs_dict: BpmnSpecDict,
|
||||
) -> None:
|
||||
result = ElementUnitsService.cache_element_units_for_workflow("testing", example_specs_dict)
|
||||
assert result is None
|
||||
result = ElementUnitsService.cache_element_units_for_workflow("testing", example_specs_dict)
|
||||
assert result is None
|
||||
result = ElementUnitsService.cache_element_units_for_workflow("testing", example_specs_dict)
|
||||
assert result is None
|
||||
|
||||
def test_can_read_element_unit_for_process_from_cache(
|
||||
self,
|
||||
app_enabled_tmp_cache_dir: Flask,
|
||||
example_specs_dict: BpmnSpecDict,
|
||||
) -> None:
|
||||
ElementUnitsService.cache_element_units_for_workflow("testing", example_specs_dict)
|
||||
cached_specs_dict = ElementUnitsService.workflow_from_cached_element_unit("testing", "no_tasks")
|
||||
assert cached_specs_dict == example_specs_dict
|
||||
|
||||
def test_reading_element_unit_for_uncached_process_returns_none(
|
||||
self,
|
||||
app_enabled_tmp_cache_dir: Flask,
|
||||
) -> None:
|
||||
cached_specs_dict = ElementUnitsService.workflow_from_cached_element_unit("testing", "no_tasks")
|
||||
assert cached_specs_dict is None
|
|
@ -82,9 +82,9 @@ const submitWithUser = (
|
|||
|
||||
//Consulting Fees Path - Without Files
|
||||
describe('Consulting Fees Path - Without Files', () => {
|
||||
Cypress._.times(5, () => {
|
||||
Cypress._.times(1, () => {
|
||||
//Budget owner approves the request
|
||||
it('Budget owner approves', () => {
|
||||
it.only('Budget owner approves', () => {
|
||||
let username = Cypress.env('requestor_username');
|
||||
let password = Cypress.env('requestor_password');
|
||||
cy.log('=====username : ' + username);
|
||||
|
@ -94,24 +94,25 @@ describe('Consulting Fees Path - Without Files', () => {
|
|||
cy.visit('/');
|
||||
|
||||
cy.contains('Start New +').click();
|
||||
cy.contains('Raise New Demand Request');
|
||||
cy.contains('Request Goods/Services');
|
||||
|
||||
cy.runPrimaryBpmnFile(true);
|
||||
|
||||
cy.contains('Please select the type of request to start the process.');
|
||||
// wait a second to ensure we can click the radio button
|
||||
|
||||
cy.wait(2000);
|
||||
cy.get('input#root-procurement').click();
|
||||
cy.wait(2000);
|
||||
|
||||
|
||||
cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
/* cy.contains('Please select the type of request to start the process.');
|
||||
// wait a second to ensure we can click the radio button
|
||||
|
||||
cy.wait(2000);
|
||||
cy.get('input#root-procurement').click();
|
||||
cy.wait(2000);
|
||||
|
||||
|
||||
cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
*/
|
||||
|
||||
cy.contains(
|
||||
'Submit a new demand request for the procurement of needed items',
|
||||
'Request Goods/Services',
|
||||
{ timeout: 60000 }
|
||||
);
|
||||
|
||||
|
@ -121,45 +122,47 @@ describe('Consulting Fees Path - Without Files', () => {
|
|||
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
||||
cy.log('==###############===processInstanceId : ', processInstanceId);
|
||||
let projectId = Cypress.env('project_id');
|
||||
cy.wait(2000);
|
||||
cy.get('#root_project').select(projectId);
|
||||
cy.get('#root_category').select('consult_fees');
|
||||
cy.get('#root_purpose').clear().type('Consulting ==== Management consulting includes a broad range of activities, and the many firms and their members often define these practices quite differently. One way to categorize the activities is in terms of the professional’s area of expertise.');
|
||||
cy.get('#root_criticality').select('High');
|
||||
cy.get('#root_period').clear().type('2025-12-25');
|
||||
cy.get('#root_period').clear().type('25-12-2025');
|
||||
cy.get('body').click();
|
||||
cy.get('#root_vendor').clear().type('Embassar');
|
||||
cy.get('#root_payment_method').select('Bank Transfer');
|
||||
cy.get('button')
|
||||
/*cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
|
||||
cy.contains('Task: Enter NDR Items', { timeout: 60000 });
|
||||
cy.contains('Task: Enter NDR Items', { timeout: 60000 });*/
|
||||
//item 0
|
||||
cy.get('#root_0_sub_category').select('ambassadors');
|
||||
cy.get('#root_0_item').clear().type('An ambassador is an official envoy, especially a high-ranking diplomat who represents a state.');
|
||||
cy.get('#root_0_qty').clear().type('4');
|
||||
cy.get('#root_0_currency_type').select('Crypto');
|
||||
cy.get('#root_0_currency').select('ETH');
|
||||
cy.get('#root_0_unit_price').type('1.15');
|
||||
cy.get('#root_item_0_sub_category').select('ambassadors');
|
||||
cy.get('#root_item_0_item_name').clear().type('An ambassador is an official envoy, especially a high-ranking diplomat who represents a state.');
|
||||
cy.get('#root_item_0_qty').clear().type('4');
|
||||
cy.get('#root_item_0_currency_type').select('Crypto');
|
||||
cy.get('#root_item_0_currency').select('ETH');
|
||||
cy.get('#root_item_0_unit_price').type('1.15');
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.get('#root_item > div:nth-child(3) > p > button').click();
|
||||
|
||||
//item 1
|
||||
cy.get('#root_1_sub_category').select('consultants');
|
||||
cy.get('#root_1_item').clear().type('A consultant (from Latin: consultare "to deliberate") is a professional');
|
||||
cy.get('#root_1_qty').clear().type('1');
|
||||
cy.get('#root_1_currency_type').select('Fiat');
|
||||
cy.get('#root_1_currency').select('CAD');
|
||||
cy.get('#root_1_unit_price').type('1355');
|
||||
cy.get('#root_item_1_sub_category').select('consultants');
|
||||
cy.get('#root_item_1_item_name').clear().type('A consultant (from Latin: consultare "to deliberate") is a professional');
|
||||
cy.get('#root_item_1_qty').clear().type('1');
|
||||
cy.get('#root_item_1_currency_type').select('Fiat');
|
||||
cy.get('#root_item_1_currency').select('CAD');
|
||||
cy.get('#root_item_1_unit_price').type('1355');
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.get('#root_item > div:nth-child(3) > p > button').click();
|
||||
|
||||
//item 2
|
||||
cy.get('#root_2_sub_category').select('freelancers');
|
||||
cy.get('#root_2_item').clear().type('Find & hire top freelancers, web developers & designers inexpensively. ');
|
||||
cy.get('#root_2_qty').clear().type('6');
|
||||
cy.get('#root_2_currency_type').select('Crypto');
|
||||
cy.get('#root_2_currency').select('SNT');
|
||||
cy.get('#root_2_unit_price').type('2300');
|
||||
cy.get('#root_item_2_sub_category').select('freelancers');
|
||||
cy.get('#root_item_2_item_name').clear().type('Find & hire top freelancers, web developers & designers inexpensively. ');
|
||||
cy.get('#root_item_2_qty').clear().type('6');
|
||||
cy.get('#root_item_2_currency_type').select('Crypto');
|
||||
cy.get('#root_item_2_currency').select('SNT');
|
||||
cy.get('#root_item_2_unit_price').type('2300');
|
||||
|
||||
|
||||
cy.get('button')
|
||||
|
@ -183,8 +186,9 @@ describe('Consulting Fees Path - Without Files', () => {
|
|||
.click();
|
||||
|
||||
|
||||
cy.contains('Tasks for my open instances', { timeout: 60000 });
|
||||
cy.contains('Started by me', { timeout: 60000 });
|
||||
cy.logout();
|
||||
cy.wait(1000);
|
||||
|
||||
let budgetOwnerUsername = Cypress.env('budgetowner_username');
|
||||
let budgetOwnerPassword = Cypress.env('budgetowner_password');
|
||||
|
@ -195,7 +199,7 @@ describe('Consulting Fees Path - Without Files', () => {
|
|||
budgetOwnerUsername,
|
||||
budgetOwnerPassword,
|
||||
processInstanceId,
|
||||
'Task: Reminder: Request Additional Budget',
|
||||
'Task: Reminder: Check Existing Budget',
|
||||
"approve"
|
||||
);
|
||||
|
||||
|
@ -213,24 +217,25 @@ describe('Consulting Fees Path - Without Files', () => {
|
|||
cy.visit('/');
|
||||
|
||||
cy.contains('Start New +').click();
|
||||
cy.contains('Raise New Demand Request');
|
||||
cy.contains('Request Goods/Services');
|
||||
|
||||
cy.runPrimaryBpmnFile(true);
|
||||
|
||||
cy.contains('Please select the type of request to start the process.');
|
||||
// wait a second to ensure we can click the radio button
|
||||
|
||||
cy.wait(2000);
|
||||
cy.get('input#root-procurement').click();
|
||||
cy.wait(2000);
|
||||
|
||||
|
||||
cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
/* cy.contains('Please select the type of request to start the process.');
|
||||
// wait a second to ensure we can click the radio button
|
||||
|
||||
cy.wait(2000);
|
||||
cy.get('input#root-procurement').click();
|
||||
cy.wait(2000);
|
||||
|
||||
|
||||
cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
*/
|
||||
|
||||
cy.contains(
|
||||
'Submit a new demand request for the procurement of needed items',
|
||||
'Request Goods/Services',
|
||||
{ timeout: 60000 }
|
||||
);
|
||||
|
||||
|
@ -240,46 +245,48 @@ describe('Consulting Fees Path - Without Files', () => {
|
|||
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
||||
cy.log('==###############===processInstanceId : ', processInstanceId);
|
||||
let projectId = Cypress.env('project_id');
|
||||
cy.wait(2000);
|
||||
cy.get('#root_project').select(projectId);
|
||||
cy.get('#root_category').select('consult_fees');
|
||||
cy.get('#root_purpose').clear().type('Consulting is defined as the practise of providing a third party with expertise on a matter in exchange for a fee. The service may involve either advisory or implementation services.');
|
||||
cy.get('#root_criticality').select('Medium');
|
||||
cy.get('#root_period').clear().type('2024-10-02');
|
||||
cy.get('#root_period').clear().type('24-10-2032');
|
||||
cy.get('body').click();
|
||||
cy.get('#root_vendor').clear().type('Consultancy.uk');
|
||||
cy.get('#root_payment_method').select('Crypto Transfer');
|
||||
cy.get('button')
|
||||
/*cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
|
||||
cy.contains('Task: Enter NDR Items', { timeout: 60000 });
|
||||
cy.contains('Task: Enter NDR Items', { timeout: 60000 });*/
|
||||
|
||||
//Item 0
|
||||
cy.get('#root_0_sub_category').select('consultants');
|
||||
cy.get('#root_0_item').clear().type('Software development consultants with Python background');
|
||||
cy.get('#root_0_qty').clear().type('5');
|
||||
cy.get('#root_0_currency_type').select('Crypto');
|
||||
cy.get('#root_0_currency').select('DAI');
|
||||
cy.get('#root_0_unit_price').type('1500');
|
||||
cy.get('#root_item_0_sub_category').select('consultants');
|
||||
cy.get('#root_item_0_item_name').clear().type('Software development consultants with Python background');
|
||||
cy.get('#root_item_0_qty').clear().type('5');
|
||||
cy.get('#root_item_0_currency_type').select('Crypto');
|
||||
cy.get('#root_item_0_currency').select('DAI');
|
||||
cy.get('#root_item_0_unit_price').type('1500');
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.get('#root_item > div:nth-child(3) > p > button').click();
|
||||
|
||||
//item 1
|
||||
cy.get('#root_1_sub_category').select('consultants');
|
||||
cy.get('#root_1_item').clear().type('A consultant (from Latin: consultare "to deliberate") is a professional');
|
||||
cy.get('#root_1_qty').clear().type('1');
|
||||
cy.get('#root_1_currency_type').select('Fiat');
|
||||
cy.get('#root_1_currency').select('CAD');
|
||||
cy.get('#root_1_unit_price').type('1355');
|
||||
cy.get('#root_item_1_sub_category').select('consultants');
|
||||
cy.get('#root_item_1_item_name').clear().type('A consultant (from Latin: consultare "to deliberate") is a professional');
|
||||
cy.get('#root_item_1_qty').clear().type('1');
|
||||
cy.get('#root_item_1_currency_type').select('Fiat');
|
||||
cy.get('#root_item_1_currency').select('CAD');
|
||||
cy.get('#root_item_1_unit_price').type('1355');
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.get('#root_item > div:nth-child(3) > p > button').click();
|
||||
|
||||
//item 2
|
||||
cy.get('#root_2_sub_category').select('freelancers');
|
||||
cy.get('#root_2_item').clear().type('Find & hire top freelancers, web developers & designers inexpensively. ');
|
||||
cy.get('#root_2_qty').clear().type('6');
|
||||
cy.get('#root_2_currency_type').select('Crypto');
|
||||
cy.get('#root_2_currency').select('SNT');
|
||||
cy.get('#root_2_unit_price').type('2300');
|
||||
cy.get('#root_item_2_sub_category').select('freelancers');
|
||||
cy.get('#root_item_2_item_name').clear().type('Find & hire top freelancers, web developers & designers inexpensively. ');
|
||||
cy.get('#root_item_2_qty').clear().type('6');
|
||||
cy.get('#root_item_2_currency_type').select('Crypto');
|
||||
cy.get('#root_item_2_currency').select('SNT');
|
||||
cy.get('#root_item_2_unit_price').type('2300');
|
||||
|
||||
|
||||
cy.get('button')
|
||||
|
@ -302,8 +309,9 @@ describe('Consulting Fees Path - Without Files', () => {
|
|||
.contains(/^Submit$/)
|
||||
.click();
|
||||
|
||||
cy.contains('Tasks for my open instances', { timeout: 60000 });
|
||||
cy.contains('Started by me', { timeout: 60000 });
|
||||
cy.logout();
|
||||
cy.wait(1000);
|
||||
|
||||
let budgetOwnerUsername = Cypress.env('budgetowner_username');
|
||||
let budgetOwnerPassword = Cypress.env('budgetowner_password');
|
||||
|
@ -332,24 +340,25 @@ describe('Consulting Fees Path - Without Files', () => {
|
|||
cy.visit('/');
|
||||
|
||||
cy.contains('Start New +').click();
|
||||
cy.contains('Raise New Demand Request');
|
||||
cy.contains('Request Goods/Services');
|
||||
|
||||
cy.runPrimaryBpmnFile(true);
|
||||
|
||||
cy.contains('Please select the type of request to start the process.');
|
||||
// wait a second to ensure we can click the radio button
|
||||
|
||||
cy.wait(2000);
|
||||
cy.get('input#root-procurement').click();
|
||||
cy.wait(2000);
|
||||
|
||||
|
||||
cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
/* cy.contains('Please select the type of request to start the process.');
|
||||
// wait a second to ensure we can click the radio button
|
||||
|
||||
cy.wait(2000);
|
||||
cy.get('input#root-procurement').click();
|
||||
cy.wait(2000);
|
||||
|
||||
|
||||
cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
*/
|
||||
|
||||
cy.contains(
|
||||
'Submit a new demand request for the procurement of needed items',
|
||||
'Request Goods/Services',
|
||||
{ timeout: 60000 }
|
||||
);
|
||||
|
||||
|
@ -359,46 +368,48 @@ describe('Consulting Fees Path - Without Files', () => {
|
|||
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
||||
cy.log('==###############===processInstanceId : ', processInstanceId);
|
||||
let projectId = Cypress.env('project_id');
|
||||
cy.wait(2000);
|
||||
cy.get('#root_project').select(projectId);
|
||||
cy.get('#root_category').select('consult_fees');
|
||||
cy.get('#root_purpose').clear().type('Freelancing - Freelancing is doing specific work for clients without committing to full-time employment. Freelancers often take on multiple projects with different clients simultaneously. IRS considers freelancers to be self-employed individuals.');
|
||||
cy.get('#root_criticality').select('Low');
|
||||
cy.get('#root_period').clear().type('2025-04-15');
|
||||
cy.get('#root_period').clear().type('05-04-2028');
|
||||
cy.get('body').click();
|
||||
cy.get('#root_vendor').clear().type('Upwork');
|
||||
cy.get('#root_payment_method').select('Debit Card');
|
||||
cy.get('button')
|
||||
/*cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
|
||||
cy.contains('Task: Enter NDR Items', { timeout: 60000 });
|
||||
cy.contains('Task: Enter NDR Items', { timeout: 60000 });*/
|
||||
|
||||
//item 0
|
||||
cy.get('#root_0_sub_category').select('freelancers');
|
||||
cy.get('#root_0_item').clear().type('Freelancers to do the Python development and front end react app development');
|
||||
cy.get('#root_0_qty').clear().type('4');
|
||||
cy.get('#root_0_currency_type').select('Crypto');
|
||||
cy.get('#root_0_currency').select('SNT');
|
||||
cy.get('#root_0_unit_price').type('1750');
|
||||
cy.get('#root_item_0_sub_category').select('freelancers');
|
||||
cy.get('#root_item_0_item_name').clear().type('Freelancers to do the Python development and front end react app development');
|
||||
cy.get('#root_item_0_qty').clear().type('4');
|
||||
cy.get('#root_item_0_currency_type').select('Crypto');
|
||||
cy.get('#root_item_0_currency').select('SNT');
|
||||
cy.get('#root_item_0_unit_price').type('1750');
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.get('#root_item > div:nth-child(3) > p > button').click();
|
||||
|
||||
//item 1
|
||||
cy.get('#root_1_sub_category').select('consultants');
|
||||
cy.get('#root_1_item').clear().type('A consultant (from Latin: consultare "to deliberate") is a professional');
|
||||
cy.get('#root_1_qty').clear().type('1');
|
||||
cy.get('#root_1_currency_type').select('Fiat');
|
||||
cy.get('#root_1_currency').select('CAD');
|
||||
cy.get('#root_1_unit_price').type('1355');
|
||||
cy.get('#root_item_1_sub_category').select('consultants');
|
||||
cy.get('#root_item_1_item_name').clear().type('A consultant (from Latin: consultare "to deliberate") is a professional');
|
||||
cy.get('#root_item_1_qty').clear().type('1');
|
||||
cy.get('#root_item_1_currency_type').select('Fiat');
|
||||
cy.get('#root_item_1_currency').select('CAD');
|
||||
cy.get('#root_item_1_unit_price').type('1355');
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.get('#root_item > div:nth-child(3) > p > button').click();
|
||||
|
||||
//item 2
|
||||
cy.get('#root_2_sub_category').select('freelancers');
|
||||
cy.get('#root_2_item').clear().type('Find & hire top freelancers, web developers & designers inexpensively. ');
|
||||
cy.get('#root_2_qty').clear().type('6');
|
||||
cy.get('#root_2_currency_type').select('Crypto');
|
||||
cy.get('#root_2_currency').select('SNT');
|
||||
cy.get('#root_2_unit_price').type('2300');
|
||||
cy.get('#root_item_2_sub_category').select('freelancers');
|
||||
cy.get('#root_item_2_item_name').clear().type('Find & hire top freelancers, web developers & designers inexpensively. ');
|
||||
cy.get('#root_item_2_qty').clear().type('6');
|
||||
cy.get('#root_item_2_currency_type').select('Crypto');
|
||||
cy.get('#root_item_2_currency').select('SNT');
|
||||
cy.get('#root_item_2_unit_price').type('2300');
|
||||
|
||||
|
||||
|
||||
|
@ -422,8 +433,9 @@ describe('Consulting Fees Path - Without Files', () => {
|
|||
.contains(/^Submit$/)
|
||||
.click();
|
||||
|
||||
cy.contains('Tasks for my open instances', { timeout: 60000 });
|
||||
cy.contains('Started by me', { timeout: 60000 });
|
||||
cy.logout();
|
||||
cy.wait(1000);
|
||||
|
||||
let budgetOwnerUsername = Cypress.env('budgetowner_username');
|
||||
let budgetOwnerPassword = Cypress.env('budgetowner_password');
|
||||
|
@ -452,7 +464,7 @@ describe('Consulting Fees Path - Without Files', () => {
|
|||
budgetOwnerUsername,
|
||||
budgetOwnerPassword,
|
||||
processInstanceId,
|
||||
'Task: Reminder: Request Additional Budget',
|
||||
'Task: Reminder: Check Existing Budget',
|
||||
"approve"
|
||||
);
|
||||
|
||||
|
@ -466,7 +478,7 @@ describe('Consulting Fees Path - Without Files', () => {
|
|||
describe('Consulting Fees Path - With Files', () => {
|
||||
Cypress._.times(1, () => {
|
||||
//Budget owner approves the request
|
||||
it('Budget owner approves', () => {
|
||||
it.only('Budget owner approves', () => {
|
||||
let username = Cypress.env('requestor_username');
|
||||
let password = Cypress.env('requestor_password');
|
||||
cy.log('=====username : ' + username);
|
||||
|
@ -476,24 +488,25 @@ describe('Consulting Fees Path - With Files', () => {
|
|||
cy.visit('/');
|
||||
|
||||
cy.contains('Start New +').click();
|
||||
cy.contains('Raise New Demand Request');
|
||||
cy.contains('Request Goods/Services');
|
||||
|
||||
cy.runPrimaryBpmnFile(true);
|
||||
|
||||
cy.contains('Please select the type of request to start the process.');
|
||||
// wait a second to ensure we can click the radio button
|
||||
|
||||
cy.wait(2000);
|
||||
cy.get('input#root-procurement').click();
|
||||
cy.wait(2000);
|
||||
|
||||
|
||||
cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
/* cy.contains('Please select the type of request to start the process.');
|
||||
// wait a second to ensure we can click the radio button
|
||||
|
||||
cy.wait(2000);
|
||||
cy.get('input#root-procurement').click();
|
||||
cy.wait(2000);
|
||||
|
||||
|
||||
cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
*/
|
||||
|
||||
cy.contains(
|
||||
'Submit a new demand request for the procurement of needed items',
|
||||
'Request Goods/Services',
|
||||
{ timeout: 60000 }
|
||||
);
|
||||
|
||||
|
@ -503,46 +516,48 @@ describe('Consulting Fees Path - With Files', () => {
|
|||
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
||||
cy.log('==###############===processInstanceId : ', processInstanceId);
|
||||
let projectId = Cypress.env('project_id');
|
||||
cy.wait(2000);
|
||||
cy.get('#root_project').select(projectId);
|
||||
cy.get('#root_category').select('consult_fees');
|
||||
cy.get('#root_purpose').clear().type('Consulting ==== Management consulting includes a broad range of activities, and the many firms and their members often define these practices quite differently. One way to categorize the activities is in terms of the professional’s area of expertise.');
|
||||
cy.get('#root_criticality').select('High');
|
||||
cy.get('#root_period').clear().type('2025-12-25');
|
||||
cy.get('#root_period').clear().type('05-12-2025');
|
||||
cy.get('body').click();
|
||||
cy.get('#root_vendor').clear().type('Embassar');
|
||||
cy.get('#root_payment_method').select('Bank Transfer');
|
||||
cy.get('button')
|
||||
/*cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
|
||||
cy.contains('Task: Enter NDR Items', { timeout: 60000 });
|
||||
cy.contains('Task: Enter NDR Items', { timeout: 60000 });*/
|
||||
|
||||
//item 0
|
||||
cy.get('#root_0_sub_category').select('ambassadors');
|
||||
cy.get('#root_0_item').clear().type('An ambassador is an official envoy, especially a high-ranking diplomat who represents a state.');
|
||||
cy.get('#root_0_qty').clear().type('4');
|
||||
cy.get('#root_0_currency_type').select('Crypto');
|
||||
cy.get('#root_0_currency').select('ETH');
|
||||
cy.get('#root_0_unit_price').type('1.15');
|
||||
cy.get('#root_item_0_sub_category').select('ambassadors');
|
||||
cy.get('#root_item_0_item_name').clear().type('An ambassador is an official envoy, especially a high-ranking diplomat who represents a state.');
|
||||
cy.get('#root_item_0_qty').clear().type('4');
|
||||
cy.get('#root_item_0_currency_type').select('Crypto');
|
||||
cy.get('#root_item_0_currency').select('ETH');
|
||||
cy.get('#root_item_0_unit_price').type('1.15');
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.get('#root_item > div:nth-child(3) > p > button').click();
|
||||
|
||||
//item 1
|
||||
cy.get('#root_1_sub_category').select('consultants');
|
||||
cy.get('#root_1_item').clear().type('A consultant (from Latin: consultare "to deliberate") is a professional');
|
||||
cy.get('#root_1_qty').clear().type('1');
|
||||
cy.get('#root_1_currency_type').select('Fiat');
|
||||
cy.get('#root_1_currency').select('CAD');
|
||||
cy.get('#root_1_unit_price').type('1355');
|
||||
cy.get('#root_item_1_sub_category').select('consultants');
|
||||
cy.get('#root_item_1_item_name').clear().type('A consultant (from Latin: consultare "to deliberate") is a professional');
|
||||
cy.get('#root_item_1_qty').clear().type('1');
|
||||
cy.get('#root_item_1_currency_type').select('Fiat');
|
||||
cy.get('#root_item_1_currency').select('CAD');
|
||||
cy.get('#root_item_1_unit_price').type('1355');
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.get('#root_item > div:nth-child(3) > p > button').click();
|
||||
|
||||
//item 2
|
||||
cy.get('#root_2_sub_category').select('freelancers');
|
||||
cy.get('#root_2_item').clear().type('Find & hire top freelancers, web developers & designers inexpensively. ');
|
||||
cy.get('#root_2_qty').clear().type('6');
|
||||
cy.get('#root_2_currency_type').select('Crypto');
|
||||
cy.get('#root_2_currency').select('SNT');
|
||||
cy.get('#root_2_unit_price').type('2300');
|
||||
cy.get('#root_item_2_sub_category').select('freelancers');
|
||||
cy.get('#root_item_2_item_name').clear().type('Find & hire top freelancers, web developers & designers inexpensively. ');
|
||||
cy.get('#root_item_2_qty').clear().type('6');
|
||||
cy.get('#root_item_2_currency_type').select('Crypto');
|
||||
cy.get('#root_item_2_currency').select('SNT');
|
||||
cy.get('#root_item_2_unit_price').type('2300');
|
||||
|
||||
|
||||
cy.get('button')
|
||||
|
@ -556,8 +571,47 @@ describe('Consulting Fees Path - With Files', () => {
|
|||
|
||||
cy.get('.cds--text-area__wrapper').find('#root').type('For professionals working in the professional services, ‘consultant’ and advisor’ are often used and fall under common terminology. Consultancy.uk zooms in on this field to get a closer look. \n https://www.consultancy.uk/career/what-is-consulting');
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
|
||||
cy.get("input[type=file]")
|
||||
.attachFile(['lorem-ipsum.pdf', 'png-5mb-1.png', 'Free_Test_Data_1MB_PDF.pdf', 'sampletext.txt']);
|
||||
.attachFile(['lorem-ipsum.pdf']);
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(2) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
cy.get("input[type=file]")
|
||||
.attachFile(['png-5mb-1.png']);
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(3) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(2) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get("input[type=file]")
|
||||
.attachFile(['Free_Test_Data_1MB_PDF.pdf']);
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(4) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(3) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(2) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get("input[type=file]")
|
||||
.attachFile(['sampletext.txt']);
|
||||
|
||||
cy.wait(2000);
|
||||
|
||||
cy.contains('Submit the Request').click();
|
||||
|
||||
|
@ -569,8 +623,9 @@ describe('Consulting Fees Path - With Files', () => {
|
|||
.click();
|
||||
|
||||
|
||||
cy.contains('Tasks for my open instances', { timeout: 60000 });
|
||||
cy.contains('Started by me', { timeout: 60000 });
|
||||
cy.logout();
|
||||
cy.wait(1000);
|
||||
|
||||
let budgetOwnerUsername = Cypress.env('budgetowner_username');
|
||||
let budgetOwnerPassword = Cypress.env('budgetowner_password');
|
||||
|
@ -581,7 +636,7 @@ describe('Consulting Fees Path - With Files', () => {
|
|||
budgetOwnerUsername,
|
||||
budgetOwnerPassword,
|
||||
processInstanceId,
|
||||
'Task: Reminder: Request Additional Budget',
|
||||
'Task: Reminder: Check Existing Budget',
|
||||
"approve"
|
||||
);
|
||||
|
||||
|
@ -599,24 +654,25 @@ describe('Consulting Fees Path - With Files', () => {
|
|||
cy.visit('/');
|
||||
|
||||
cy.contains('Start New +').click();
|
||||
cy.contains('Raise New Demand Request');
|
||||
cy.contains('Request Goods/Services');
|
||||
|
||||
cy.runPrimaryBpmnFile(true);
|
||||
|
||||
cy.contains('Please select the type of request to start the process.');
|
||||
// wait a second to ensure we can click the radio button
|
||||
|
||||
cy.wait(2000);
|
||||
cy.get('input#root-procurement').click();
|
||||
cy.wait(2000);
|
||||
|
||||
|
||||
cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
/* cy.contains('Please select the type of request to start the process.');
|
||||
// wait a second to ensure we can click the radio button
|
||||
|
||||
cy.wait(2000);
|
||||
cy.get('input#root-procurement').click();
|
||||
cy.wait(2000);
|
||||
|
||||
|
||||
cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
*/
|
||||
|
||||
cy.contains(
|
||||
'Submit a new demand request for the procurement of needed items',
|
||||
'Request Goods/Services',
|
||||
{ timeout: 60000 }
|
||||
);
|
||||
|
||||
|
@ -626,46 +682,48 @@ describe('Consulting Fees Path - With Files', () => {
|
|||
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
||||
cy.log('==###############===processInstanceId : ', processInstanceId);
|
||||
let projectId = Cypress.env('project_id');
|
||||
cy.wait(2000);
|
||||
cy.get('#root_project').select(projectId);
|
||||
cy.get('#root_category').select('consult_fees');
|
||||
cy.get('#root_purpose').clear().type('Consulting is defined as the practise of providing a third party with expertise on a matter in exchange for a fee. The service may involve either advisory or implementation services.');
|
||||
cy.get('#root_criticality').select('Medium');
|
||||
cy.get('#root_period').clear().type('2024-10-02');
|
||||
cy.get('#root_period').clear().type('14-10-2029');
|
||||
cy.get('body').click();
|
||||
cy.get('#root_vendor').clear().type('Consultancy.uk');
|
||||
cy.get('#root_payment_method').select('Crypto Transfer');
|
||||
cy.get('button')
|
||||
/*cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
|
||||
cy.contains('Task: Enter NDR Items', { timeout: 60000 });
|
||||
cy.contains('Task: Enter NDR Items', { timeout: 60000 });*/
|
||||
|
||||
//item 0
|
||||
cy.get('#root_0_sub_category').select('consultants');
|
||||
cy.get('#root_0_item').clear().type('Software development consultants with Python background');
|
||||
cy.get('#root_0_qty').clear().type('5');
|
||||
cy.get('#root_0_currency_type').select('Crypto');
|
||||
cy.get('#root_0_currency').select('DAI');
|
||||
cy.get('#root_0_unit_price').type('1500');
|
||||
cy.get('#root_item_0_sub_category').select('consultants');
|
||||
cy.get('#root_item_0_item_name').clear().type('Software development consultants with Python background');
|
||||
cy.get('#root_item_0_qty').clear().type('5');
|
||||
cy.get('#root_item_0_currency_type').select('Crypto');
|
||||
cy.get('#root_item_0_currency').select('DAI');
|
||||
cy.get('#root_item_0_unit_price').type('1500');
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.get('#root_item > div:nth-child(3) > p > button').click();
|
||||
|
||||
//item 1
|
||||
cy.get('#root_1_sub_category').select('consultants');
|
||||
cy.get('#root_1_item').clear().type('A consultant (from Latin: consultare "to deliberate") is a professional');
|
||||
cy.get('#root_1_qty').clear().type('1');
|
||||
cy.get('#root_1_currency_type').select('Fiat');
|
||||
cy.get('#root_1_currency').select('CAD');
|
||||
cy.get('#root_1_unit_price').type('1355');
|
||||
cy.get('#root_item_1_sub_category').select('consultants');
|
||||
cy.get('#root_item_1_item_name').clear().type('A consultant (from Latin: consultare "to deliberate") is a professional');
|
||||
cy.get('#root_item_1_qty').clear().type('1');
|
||||
cy.get('#root_item_1_currency_type').select('Fiat');
|
||||
cy.get('#root_item_1_currency').select('CAD');
|
||||
cy.get('#root_item_1_unit_price').type('1355');
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.get('#root_item > div:nth-child(3) > p > button').click();
|
||||
|
||||
//item 2
|
||||
cy.get('#root_2_sub_category').select('freelancers');
|
||||
cy.get('#root_2_item').clear().type('Find & hire top freelancers, web developers & designers inexpensively. ');
|
||||
cy.get('#root_2_qty').clear().type('6');
|
||||
cy.get('#root_2_currency_type').select('Crypto');
|
||||
cy.get('#root_2_currency').select('SNT');
|
||||
cy.get('#root_2_unit_price').type('2300');
|
||||
cy.get('#root_item_2_sub_category').select('freelancers');
|
||||
cy.get('#root_item_2_item_name').clear().type('Find & hire top freelancers, web developers & designers inexpensively. ');
|
||||
cy.get('#root_item_2_qty').clear().type('6');
|
||||
cy.get('#root_item_2_currency_type').select('Crypto');
|
||||
cy.get('#root_item_2_currency').select('SNT');
|
||||
cy.get('#root_item_2_unit_price').type('2300');
|
||||
|
||||
|
||||
cy.get('button')
|
||||
|
@ -679,8 +737,47 @@ describe('Consulting Fees Path - With Files', () => {
|
|||
|
||||
cy.get('.cds--text-area__wrapper').find('#root').type('For professionals working in the professional services, ‘consultant’ and advisor’ are often used and fall under common terminology. Consultancy.uk zooms in on this field to get a closer look. \n https://www.consultancy.uk/career/what-is-consulting');
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
|
||||
cy.get("input[type=file]")
|
||||
.attachFile(['lorem-ipsum.pdf', 'png-5mb-1.png', 'Free_Test_Data_1MB_PDF.pdf', 'sampletext.txt']);
|
||||
.attachFile(['lorem-ipsum.pdf']);
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(2) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
cy.get("input[type=file]")
|
||||
.attachFile(['png-5mb-1.png']);
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(3) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(2) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get("input[type=file]")
|
||||
.attachFile(['Free_Test_Data_1MB_PDF.pdf']);
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(4) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(3) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(2) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get("input[type=file]")
|
||||
.attachFile(['sampletext.txt']);
|
||||
|
||||
cy.wait(2000);
|
||||
|
||||
cy.contains('Submit the Request').click();
|
||||
|
||||
|
@ -691,8 +788,9 @@ describe('Consulting Fees Path - With Files', () => {
|
|||
.contains(/^Submit$/)
|
||||
.click();
|
||||
|
||||
cy.contains('Tasks for my open instances', { timeout: 60000 });
|
||||
cy.contains('Started by me', { timeout: 60000 });
|
||||
cy.logout();
|
||||
cy.wait(1000);
|
||||
|
||||
let budgetOwnerUsername = Cypress.env('budgetowner_username');
|
||||
let budgetOwnerPassword = Cypress.env('budgetowner_password');
|
||||
|
@ -721,24 +819,25 @@ describe('Consulting Fees Path - With Files', () => {
|
|||
cy.visit('/');
|
||||
|
||||
cy.contains('Start New +').click();
|
||||
cy.contains('Raise New Demand Request');
|
||||
cy.contains('Request Goods/Services');
|
||||
|
||||
cy.runPrimaryBpmnFile(true);
|
||||
|
||||
cy.contains('Please select the type of request to start the process.');
|
||||
// wait a second to ensure we can click the radio button
|
||||
|
||||
cy.wait(2000);
|
||||
cy.get('input#root-procurement').click();
|
||||
cy.wait(2000);
|
||||
|
||||
|
||||
cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
/* cy.contains('Please select the type of request to start the process.');
|
||||
// wait a second to ensure we can click the radio button
|
||||
|
||||
cy.wait(2000);
|
||||
cy.get('input#root-procurement').click();
|
||||
cy.wait(2000);
|
||||
|
||||
|
||||
cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
*/
|
||||
|
||||
cy.contains(
|
||||
'Submit a new demand request for the procurement of needed items',
|
||||
'Request Goods/Services',
|
||||
{ timeout: 60000 }
|
||||
);
|
||||
|
||||
|
@ -748,45 +847,47 @@ describe('Consulting Fees Path - With Files', () => {
|
|||
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
||||
cy.log('==###############===processInstanceId : ', processInstanceId);
|
||||
let projectId = Cypress.env('project_id');
|
||||
cy.wait(2000);
|
||||
cy.get('#root_project').select(projectId);
|
||||
cy.get('#root_category').select('consult_fees');
|
||||
cy.get('#root_purpose').clear().type('Freelancing - Freelancing is doing specific work for clients without committing to full-time employment. Freelancers often take on multiple projects with different clients simultaneously. IRS considers freelancers to be self-employed individuals.');
|
||||
cy.get('#root_criticality').select('Low');
|
||||
cy.get('#root_period').clear().type('2025-04-15');
|
||||
cy.get('#root_period').clear().type('05-04-2024');
|
||||
cy.get('body').click();
|
||||
cy.get('#root_vendor').clear().type('Upwork');
|
||||
cy.get('#root_payment_method').select('Debit Card');
|
||||
cy.get('button')
|
||||
/*cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
|
||||
cy.contains('Task: Enter NDR Items', { timeout: 60000 });
|
||||
cy.contains('Task: Enter NDR Items', { timeout: 60000 });*/
|
||||
//item 0
|
||||
cy.get('#root_0_sub_category').select('freelancers');
|
||||
cy.get('#root_0_item').clear().type('Freelancers to do the Python development and front end react app development');
|
||||
cy.get('#root_0_qty').clear().type('4');
|
||||
cy.get('#root_0_currency_type').select('Crypto');
|
||||
cy.get('#root_0_currency').select('SNT');
|
||||
cy.get('#root_0_unit_price').type('1750');
|
||||
cy.get('#root_item_0_sub_category').select('freelancers');
|
||||
cy.get('#root_item_0_item_name').clear().type('Freelancers to do the Python development and front end react app development');
|
||||
cy.get('#root_item_0_qty').clear().type('4');
|
||||
cy.get('#root_item_0_currency_type').select('Crypto');
|
||||
cy.get('#root_item_0_currency').select('SNT');
|
||||
cy.get('#root_item_0_unit_price').type('1750');
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.get('#root_item > div:nth-child(3) > p > button').click();
|
||||
|
||||
//item 1
|
||||
cy.get('#root_1_sub_category').select('consultants');
|
||||
cy.get('#root_1_item').clear().type('A consultant (from Latin: consultare "to deliberate") is a professional');
|
||||
cy.get('#root_1_qty').clear().type('1');
|
||||
cy.get('#root_1_currency_type').select('Fiat');
|
||||
cy.get('#root_1_currency').select('CAD');
|
||||
cy.get('#root_1_unit_price').type('1355');
|
||||
cy.get('#root_item_1_sub_category').select('consultants');
|
||||
cy.get('#root_item_1_item_name').clear().type('A consultant (from Latin: consultare "to deliberate") is a professional');
|
||||
cy.get('#root_item_1_qty').clear().type('1');
|
||||
cy.get('#root_item_1_currency_type').select('Fiat');
|
||||
cy.get('#root_item_1_currency').select('CAD');
|
||||
cy.get('#root_item_1_unit_price').type('1355');
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.get('#root_item > div:nth-child(3) > p > button').click();
|
||||
|
||||
//item 2
|
||||
cy.get('#root_2_sub_category').select('freelancers');
|
||||
cy.get('#root_2_item').clear().type('Find & hire top freelancers, web developers & designers inexpensively. ');
|
||||
cy.get('#root_2_qty').clear().type('6');
|
||||
cy.get('#root_2_currency_type').select('Crypto');
|
||||
cy.get('#root_2_currency').select('SNT');
|
||||
cy.get('#root_2_unit_price').type('2300');
|
||||
cy.get('#root_item_2_sub_category').select('freelancers');
|
||||
cy.get('#root_item_2_item_name').clear().type('Find & hire top freelancers, web developers & designers inexpensively. ');
|
||||
cy.get('#root_item_2_qty').clear().type('6');
|
||||
cy.get('#root_item_2_currency_type').select('Crypto');
|
||||
cy.get('#root_item_2_currency').select('SNT');
|
||||
cy.get('#root_item_2_unit_price').type('2300');
|
||||
|
||||
|
||||
cy.get('button')
|
||||
|
@ -800,8 +901,47 @@ describe('Consulting Fees Path - With Files', () => {
|
|||
|
||||
cy.get('.cds--text-area__wrapper').find('#root').type('It\’s free and easy to post a job. Simply fill in a title, description and budget and competitive bids come within minutes. No job is too big or too small. We\'ve got freelancers for jobs of any size or budget across 1800 skills. No job is too complex.');
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
|
||||
cy.get("input[type=file]")
|
||||
.attachFile(['lorem-ipsum.pdf', 'png-5mb-1.png', 'Free_Test_Data_1MB_PDF.pdf', 'sampletext.txt']);
|
||||
.attachFile(['lorem-ipsum.pdf']);
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(2) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
cy.get("input[type=file]")
|
||||
.attachFile(['png-5mb-1.png']);
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(3) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(2) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get("input[type=file]")
|
||||
.attachFile(['Free_Test_Data_1MB_PDF.pdf']);
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(4) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(3) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(2) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get("input[type=file]")
|
||||
.attachFile(['sampletext.txt']);
|
||||
|
||||
cy.wait(2000);
|
||||
|
||||
cy.contains('Submit the Request').click();
|
||||
|
||||
|
@ -812,8 +952,9 @@ describe('Consulting Fees Path - With Files', () => {
|
|||
.contains(/^Submit$/)
|
||||
.click();
|
||||
|
||||
cy.contains('Tasks for my open instances', { timeout: 60000 });
|
||||
cy.contains('Started by me', { timeout: 60000 });
|
||||
cy.logout();
|
||||
cy.wait(1000);
|
||||
|
||||
let budgetOwnerUsername = Cypress.env('budgetowner_username');
|
||||
let budgetOwnerPassword = Cypress.env('budgetowner_password');
|
||||
|
@ -842,7 +983,7 @@ describe('Consulting Fees Path - With Files', () => {
|
|||
budgetOwnerUsername,
|
||||
budgetOwnerPassword,
|
||||
processInstanceId,
|
||||
'Task: Reminder: Request Additional Budget',
|
||||
'Task: Reminder: Check Existing Budget',
|
||||
"approve"
|
||||
);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -84,7 +84,7 @@ describe('Other Fees Path - Without Files', () => {
|
|||
|
||||
Cypress._.times(1, () => {
|
||||
//Budget owner approves the request
|
||||
it('Budget owner approves', () => {
|
||||
it.only('Budget owner approves', () => {
|
||||
let username = Cypress.env('requestor_username');
|
||||
let password = Cypress.env('requestor_password');
|
||||
cy.log('=====username : ' + username);
|
||||
|
@ -94,24 +94,25 @@ describe('Other Fees Path - Without Files', () => {
|
|||
cy.visit('/');
|
||||
|
||||
cy.contains('Start New +').click();
|
||||
cy.contains('Raise New Demand Request');
|
||||
cy.contains('Request Goods/Services');
|
||||
|
||||
cy.runPrimaryBpmnFile(true);
|
||||
|
||||
cy.contains('Please select the type of request to start the process.');
|
||||
// wait a second to ensure we can click the radio button
|
||||
|
||||
cy.wait(2000);
|
||||
cy.get('input#root-procurement').click();
|
||||
cy.wait(2000);
|
||||
|
||||
|
||||
cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
/* cy.contains('Please select the type of request to start the process.');
|
||||
// wait a second to ensure we can click the radio button
|
||||
|
||||
cy.wait(2000);
|
||||
cy.get('input#root-procurement').click();
|
||||
cy.wait(2000);
|
||||
|
||||
|
||||
cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
*/
|
||||
|
||||
cy.contains(
|
||||
'Submit a new demand request for the procurement of needed items',
|
||||
'Request Goods/Services',
|
||||
{ timeout: 60000 }
|
||||
);
|
||||
|
||||
|
@ -121,36 +122,39 @@ describe('Other Fees Path - Without Files', () => {
|
|||
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
||||
cy.log('==###############===processInstanceId : ', processInstanceId);
|
||||
let projectId = Cypress.env('project_id');
|
||||
cy.wait(2000);
|
||||
cy.get('#root_project').select(projectId);
|
||||
cy.get('#root_category').select('other_fees');
|
||||
cy.get('#root_purpose').clear().type('Other Fees and Expenses means, collectively, all fees and expenses payable to Lenders under the Loan Documents, other than principal, interest and default interest/penalty amounts.');
|
||||
cy.get('#root_criticality').select('High');
|
||||
cy.get('#root_period').clear().type('2025-11-25');
|
||||
cy.get('#root_period').clear().type('25-11-2025');
|
||||
cy.get('body').click();
|
||||
cy.get('#root_vendor').clear().type('ABC CO');
|
||||
cy.get('#root_payment_method').select('Reimbursement');
|
||||
cy.get('button')
|
||||
/*cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
|
||||
cy.contains('Task: Enter NDR Items', { timeout: 60000 });
|
||||
*/
|
||||
//item 0
|
||||
cy.get('#root_0_sub_category').select('bounties');
|
||||
cy.get('#root_0_item').clear().type('A bounty is a payment or reward of money to locate');
|
||||
cy.get('#root_0_qty').clear().type('2');
|
||||
cy.get('#root_0_currency_type').select('Fiat');
|
||||
cy.get('#root_0_currency').select('AUD');
|
||||
cy.get('#root_0_unit_price').type('2416');
|
||||
cy.get('#root_item_0_sub_category').select('bounties');
|
||||
cy.get('#root_item_0_item_name').clear().type('A bounty is a payment or reward of money to locate');
|
||||
cy.get('#root_item_0_qty').clear().type('2');
|
||||
cy.get('#root_item_0_currency_type').select('Fiat');
|
||||
cy.get('#root_item_0_currency').select('AUD');
|
||||
cy.get('#root_item_0_unit_price').type('2416');
|
||||
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.get('#root_item > div:nth-child(3) > p > button').click();
|
||||
|
||||
//item 1
|
||||
cy.get('#root_1_sub_category').select('coworking');
|
||||
cy.get('#root_1_item').clear().type('A consultant (from Latin: consultare "to deliberate") is a professional');
|
||||
cy.get('#root_1_qty').clear().type('1');
|
||||
cy.get('#root_1_currency_type').select('Crypto');
|
||||
cy.get('#root_1_currency').select('SNT');
|
||||
cy.get('#root_1_unit_price').type('1355');
|
||||
cy.get('#root_item_1_sub_category').select('coworking');
|
||||
cy.get('#root_item_1_item_name').clear().type('A consultant (from Latin: consultare "to deliberate") is a professional');
|
||||
cy.get('#root_item_1_qty').clear().type('1');
|
||||
cy.get('#root_item_1_currency_type').select('Crypto');
|
||||
cy.get('#root_item_1_currency').select('SNT');
|
||||
cy.get('#root_item_1_unit_price').type('1355');
|
||||
|
||||
|
||||
cy.get('button')
|
||||
|
@ -174,8 +178,9 @@ describe('Other Fees Path - Without Files', () => {
|
|||
.click();
|
||||
|
||||
|
||||
cy.contains('Tasks for my open instances', { timeout: 60000 });
|
||||
cy.contains('Started by me', { timeout: 60000 });
|
||||
cy.logout();
|
||||
cy.wait(1000);
|
||||
|
||||
let budgetOwnerUsername = Cypress.env('budgetowner_username');
|
||||
let budgetOwnerPassword = Cypress.env('budgetowner_password');
|
||||
|
@ -186,7 +191,7 @@ describe('Other Fees Path - Without Files', () => {
|
|||
budgetOwnerUsername,
|
||||
budgetOwnerPassword,
|
||||
processInstanceId,
|
||||
'Task: Reminder: Request Additional Budget',
|
||||
'Task: Reminder: Check Existing Budget',
|
||||
"approve"
|
||||
);
|
||||
|
||||
|
@ -204,24 +209,25 @@ describe('Other Fees Path - Without Files', () => {
|
|||
cy.visit('/');
|
||||
|
||||
cy.contains('Start New +').click();
|
||||
cy.contains('Raise New Demand Request');
|
||||
cy.contains('Request Goods/Services');
|
||||
|
||||
cy.runPrimaryBpmnFile(true);
|
||||
|
||||
cy.contains('Please select the type of request to start the process.');
|
||||
// wait a second to ensure we can click the radio button
|
||||
|
||||
cy.wait(2000);
|
||||
cy.get('input#root-procurement').click();
|
||||
cy.wait(2000);
|
||||
|
||||
|
||||
cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
/* cy.contains('Please select the type of request to start the process.');
|
||||
// wait a second to ensure we can click the radio button
|
||||
|
||||
cy.wait(2000);
|
||||
cy.get('input#root-procurement').click();
|
||||
cy.wait(2000);
|
||||
|
||||
|
||||
cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
*/
|
||||
|
||||
cy.contains(
|
||||
'Submit a new demand request for the procurement of needed items',
|
||||
'Request Goods/Services',
|
||||
{ timeout: 60000 }
|
||||
);
|
||||
|
||||
|
@ -231,24 +237,27 @@ describe('Other Fees Path - Without Files', () => {
|
|||
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
||||
cy.log('==###############===processInstanceId : ', processInstanceId);
|
||||
let projectId = Cypress.env('project_id');
|
||||
cy.wait(2000);
|
||||
cy.get('#root_project').select(projectId);
|
||||
cy.get('#root_category').select('other_fees');
|
||||
cy.get('#root_purpose').clear().type('Other Fees and Expenses means, collectively, all fees and expenses payable to Lenders under the Loan Documents, other than principal, interest and default interest/penalty amounts.');
|
||||
cy.get('#root_criticality').select('Medium');
|
||||
cy.get('#root_period').clear().type('2024-02-06');
|
||||
cy.get('#root_period').clear().type('24-02-2036');
|
||||
cy.get('body').click();
|
||||
cy.get('#root_vendor').clear().type('CO-WORK ENG');
|
||||
cy.get('#root_payment_method').select('Bank Transfer');
|
||||
cy.get('button')
|
||||
/*cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
|
||||
cy.contains('Task: Enter NDR Items', { timeout: 60000 });
|
||||
cy.get('#root_0_sub_category').select('coworking');
|
||||
cy.get('#root_0_item').clear().type('Coworking is an arrangement in which workers for different companies share an office space');
|
||||
cy.get('#root_0_qty').clear().type('5');
|
||||
cy.get('#root_0_currency_type').select('Fiat');
|
||||
cy.get('#root_0_currency').select('EUR');
|
||||
cy.get('#root_0_unit_price').type('250');
|
||||
*/
|
||||
cy.get('#root_item_0_sub_category').select('coworking');
|
||||
cy.get('#root_item_0_item_name').clear().type('Coworking is an arrangement in which workers for different companies share an office space');
|
||||
cy.get('#root_item_0_qty').clear().type('5');
|
||||
cy.get('#root_item_0_currency_type').select('Fiat');
|
||||
cy.get('#root_item_0_currency').select('EUR');
|
||||
cy.get('#root_item_0_unit_price').type('250');
|
||||
|
||||
|
||||
cy.get('button')
|
||||
|
@ -271,8 +280,9 @@ describe('Other Fees Path - Without Files', () => {
|
|||
.contains(/^Submit$/)
|
||||
.click();
|
||||
|
||||
cy.contains('Tasks for my open instances', { timeout: 60000 });
|
||||
cy.contains('Started by me', { timeout: 60000 });
|
||||
cy.logout();
|
||||
cy.wait(1000);
|
||||
|
||||
let budgetOwnerUsername = Cypress.env('budgetowner_username');
|
||||
let budgetOwnerPassword = Cypress.env('budgetowner_password');
|
||||
|
@ -301,24 +311,25 @@ describe('Other Fees Path - Without Files', () => {
|
|||
cy.visit('/');
|
||||
|
||||
cy.contains('Start New +').click();
|
||||
cy.contains('Raise New Demand Request');
|
||||
cy.contains('Request Goods/Services');
|
||||
|
||||
cy.runPrimaryBpmnFile(true);
|
||||
|
||||
cy.contains('Please select the type of request to start the process.');
|
||||
// wait a second to ensure we can click the radio button
|
||||
|
||||
cy.wait(2000);
|
||||
cy.get('input#root-procurement').click();
|
||||
cy.wait(2000);
|
||||
|
||||
|
||||
cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
/* cy.contains('Please select the type of request to start the process.');
|
||||
// wait a second to ensure we can click the radio button
|
||||
|
||||
cy.wait(2000);
|
||||
cy.get('input#root-procurement').click();
|
||||
cy.wait(2000);
|
||||
|
||||
|
||||
cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
*/
|
||||
|
||||
cy.contains(
|
||||
'Submit a new demand request for the procurement of needed items',
|
||||
'Request Goods/Services',
|
||||
{ timeout: 60000 }
|
||||
);
|
||||
|
||||
|
@ -328,24 +339,27 @@ describe('Other Fees Path - Without Files', () => {
|
|||
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
||||
cy.log('==###############===processInstanceId : ', processInstanceId);
|
||||
let projectId = Cypress.env('project_id');
|
||||
cy.wait(2000);
|
||||
cy.get('#root_project').select(projectId);
|
||||
cy.get('#root_category').select('other_fees');
|
||||
cy.get('#root_purpose').clear().type(' It allows cost savings and convenience through the use of common infrastructures, such as equipment, utilities and receptionist and custodial services, and in some cases refreshments and parcel services.\nhttps://en.wikipedia.org/wiki/Coworking');
|
||||
cy.get('#root_criticality').select('Low');
|
||||
cy.get('#root_period').clear().type('2025-02-25');
|
||||
cy.get('#root_period').clear().type('05-02-2025');
|
||||
cy.get('body').click();
|
||||
cy.get('#root_vendor').clear().type('Bounty Co');
|
||||
cy.get('#root_payment_method').select('Crypto Transfer');
|
||||
cy.get('button')
|
||||
/*cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
|
||||
cy.contains('Task: Enter NDR Items', { timeout: 60000 });
|
||||
cy.get('#root_0_sub_category').select('bounties');
|
||||
cy.get('#root_0_item').clear().type('Coworking is not only about providing a physical place, but also about establishing a community.');
|
||||
cy.get('#root_0_qty').clear().type('4');
|
||||
cy.get('#root_0_currency_type').select('Crypto');
|
||||
cy.get('#root_0_currency').select('SNT');
|
||||
cy.get('#root_0_unit_price').type('450');
|
||||
*/
|
||||
cy.get('#root_item_0_sub_category').select('bounties');
|
||||
cy.get('#root_item_0_item_name').clear().type('Coworking is not only about providing a physical place, but also about establishing a community.');
|
||||
cy.get('#root_item_0_qty').clear().type('4');
|
||||
cy.get('#root_item_0_currency_type').select('Crypto');
|
||||
cy.get('#root_item_0_currency').select('SNT');
|
||||
cy.get('#root_item_0_unit_price').type('450');
|
||||
|
||||
|
||||
cy.get('button')
|
||||
|
@ -368,8 +382,9 @@ describe('Other Fees Path - Without Files', () => {
|
|||
.contains(/^Submit$/)
|
||||
.click();
|
||||
|
||||
cy.contains('Tasks for my open instances', { timeout: 60000 });
|
||||
cy.contains('Started by me', { timeout: 60000 });
|
||||
cy.logout();
|
||||
cy.wait(1000);
|
||||
|
||||
let budgetOwnerUsername = Cypress.env('budgetowner_username');
|
||||
let budgetOwnerPassword = Cypress.env('budgetowner_password');
|
||||
|
@ -398,7 +413,7 @@ describe('Other Fees Path - Without Files', () => {
|
|||
budgetOwnerUsername,
|
||||
budgetOwnerPassword,
|
||||
processInstanceId,
|
||||
'Task: Reminder: Request Additional Budget',
|
||||
'Task: Reminder: Check Existing Budget',
|
||||
"approve"
|
||||
);
|
||||
|
||||
|
@ -412,7 +427,7 @@ describe('Other Fees Path - With Files', () => {
|
|||
|
||||
Cypress._.times(1, () => {
|
||||
//Budget owner approves the request
|
||||
it('Budget owner approves', () => {
|
||||
it.only('Budget owner approves', () => {
|
||||
let username = Cypress.env('requestor_username');
|
||||
let password = Cypress.env('requestor_password');
|
||||
cy.log('=====username : ' + username);
|
||||
|
@ -422,24 +437,25 @@ describe('Other Fees Path - With Files', () => {
|
|||
cy.visit('/');
|
||||
|
||||
cy.contains('Start New +').click();
|
||||
cy.contains('Raise New Demand Request');
|
||||
cy.contains('Request Goods/Services');
|
||||
|
||||
cy.runPrimaryBpmnFile(true);
|
||||
|
||||
cy.contains('Please select the type of request to start the process.');
|
||||
// wait a second to ensure we can click the radio button
|
||||
|
||||
cy.wait(2000);
|
||||
cy.get('input#root-procurement').click();
|
||||
cy.wait(2000);
|
||||
|
||||
|
||||
cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
/* cy.contains('Please select the type of request to start the process.');
|
||||
// wait a second to ensure we can click the radio button
|
||||
|
||||
cy.wait(2000);
|
||||
cy.get('input#root-procurement').click();
|
||||
cy.wait(2000);
|
||||
|
||||
|
||||
cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
*/
|
||||
|
||||
cy.contains(
|
||||
'Submit a new demand request for the procurement of needed items',
|
||||
'Request Goods/Services',
|
||||
{ timeout: 60000 }
|
||||
);
|
||||
|
||||
|
@ -449,35 +465,38 @@ describe('Other Fees Path - With Files', () => {
|
|||
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
||||
cy.log('==###############===processInstanceId : ', processInstanceId);
|
||||
let projectId = Cypress.env('project_id');
|
||||
cy.wait(2000);
|
||||
cy.get('#root_project').select(projectId);
|
||||
cy.get('#root_category').select('other_fees');
|
||||
cy.get('#root_purpose').clear().type('It allows cost savings and convenience through the use of common infrastructures, such as equipment, utilities and receptionist and custodial services, and in some cases refreshments and parcel acceptance services');
|
||||
cy.get('#root_criticality').select('High');
|
||||
cy.get('#root_period').clear().type('2025-11-25');
|
||||
cy.get('#root_period').clear().type('15-11-2025');
|
||||
cy.get('body').click();
|
||||
cy.get('#root_vendor').clear().type('Embassar');
|
||||
cy.get('#root_payment_method').select('Reimbursement');
|
||||
cy.get('button')
|
||||
/*cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
|
||||
cy.contains('Task: Enter NDR Items', { timeout: 60000 });
|
||||
*/
|
||||
//item 0
|
||||
cy.get('#root_0_sub_category').select('bounties');
|
||||
cy.get('#root_0_item').clear().type('A bounty is a payment or reward of money to locate');
|
||||
cy.get('#root_0_qty').clear().type('2');
|
||||
cy.get('#root_0_currency_type').select('Fiat');
|
||||
cy.get('#root_0_currency').select('AUD');
|
||||
cy.get('#root_0_unit_price').type('2416');
|
||||
cy.get('#root_item_0_sub_category').select('bounties');
|
||||
cy.get('#root_item_0_item_name').clear().type('A bounty is a payment or reward of money to locate');
|
||||
cy.get('#root_item_0_qty').clear().type('2');
|
||||
cy.get('#root_item_0_currency_type').select('Fiat');
|
||||
cy.get('#root_item_0_currency').select('AUD');
|
||||
cy.get('#root_item_0_unit_price').type('2416');
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.get('#root_item > div:nth-child(3) > p > button').click();
|
||||
|
||||
//item 1
|
||||
cy.get('#root_1_sub_category').select('coworking');
|
||||
cy.get('#root_1_item').clear().type('A consultant (from Latin: consultare "to deliberate") is a professional');
|
||||
cy.get('#root_1_qty').clear().type('1');
|
||||
cy.get('#root_1_currency_type').select('Crypto');
|
||||
cy.get('#root_1_currency').select('DAI');
|
||||
cy.get('#root_1_unit_price').type('4250');
|
||||
cy.get('#root_item_1_sub_category').select('coworking');
|
||||
cy.get('#root_item_1_item_name').clear().type('A consultant (from Latin: consultare "to deliberate") is a professional');
|
||||
cy.get('#root_item_1_qty').clear().type('1');
|
||||
cy.get('#root_item_1_currency_type').select('Crypto');
|
||||
cy.get('#root_item_1_currency').select('DAI');
|
||||
cy.get('#root_item_1_unit_price').type('4250');
|
||||
|
||||
cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
|
@ -490,8 +509,47 @@ describe('Other Fees Path - With Files', () => {
|
|||
|
||||
cy.get('.cds--text-area__wrapper').find('#root').type('For professionals working in the professional services, ‘consultant’ and advisor’ are often used and fall under common terminology. Consultancy.uk zooms in on this field to get a closer look. \n https://www.consultancy.uk/career/what-is-consulting');
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
|
||||
cy.get("input[type=file]")
|
||||
.attachFile(['lorem-ipsum.pdf', 'png-5mb-1.png', 'Free_Test_Data_1MB_PDF.pdf', 'sampletext.txt']);
|
||||
.attachFile(['lorem-ipsum.pdf']);
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(2) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
cy.get("input[type=file]")
|
||||
.attachFile(['png-5mb-1.png']);
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(3) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(2) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get("input[type=file]")
|
||||
.attachFile(['Free_Test_Data_1MB_PDF.pdf']);
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(4) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(3) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(2) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get("input[type=file]")
|
||||
.attachFile(['sampletext.txt']);
|
||||
|
||||
cy.wait(2000);
|
||||
|
||||
cy.contains('Submit the Request').click();
|
||||
|
||||
|
@ -503,8 +561,9 @@ describe('Other Fees Path - With Files', () => {
|
|||
.click();
|
||||
|
||||
|
||||
cy.contains('Tasks for my open instances', { timeout: 60000 });
|
||||
cy.contains('Started by me', { timeout: 60000 });
|
||||
cy.logout();
|
||||
cy.wait(1000);
|
||||
|
||||
let budgetOwnerUsername = Cypress.env('budgetowner_username');
|
||||
let budgetOwnerPassword = Cypress.env('budgetowner_password');
|
||||
|
@ -515,7 +574,7 @@ describe('Other Fees Path - With Files', () => {
|
|||
budgetOwnerUsername,
|
||||
budgetOwnerPassword,
|
||||
processInstanceId,
|
||||
'Task: Reminder: Request Additional Budget',
|
||||
'Task: Reminder: Check Existing Budget',
|
||||
"approve"
|
||||
);
|
||||
|
||||
|
@ -533,24 +592,25 @@ describe('Other Fees Path - With Files', () => {
|
|||
cy.visit('/');
|
||||
|
||||
cy.contains('Start New +').click();
|
||||
cy.contains('Raise New Demand Request');
|
||||
cy.contains('Request Goods/Services');
|
||||
|
||||
cy.runPrimaryBpmnFile(true);
|
||||
|
||||
cy.contains('Please select the type of request to start the process.');
|
||||
// wait a second to ensure we can click the radio button
|
||||
|
||||
cy.wait(2000);
|
||||
cy.get('input#root-procurement').click();
|
||||
cy.wait(2000);
|
||||
|
||||
|
||||
cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
/* cy.contains('Please select the type of request to start the process.');
|
||||
// wait a second to ensure we can click the radio button
|
||||
|
||||
cy.wait(2000);
|
||||
cy.get('input#root-procurement').click();
|
||||
cy.wait(2000);
|
||||
|
||||
|
||||
cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
*/
|
||||
|
||||
cy.contains(
|
||||
'Submit a new demand request for the procurement of needed items',
|
||||
'Request Goods/Services',
|
||||
{ timeout: 60000 }
|
||||
);
|
||||
|
||||
|
@ -560,24 +620,27 @@ describe('Other Fees Path - With Files', () => {
|
|||
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
||||
cy.log('==###############===processInstanceId : ', processInstanceId);
|
||||
let projectId = Cypress.env('project_id');
|
||||
cy.wait(2000);
|
||||
cy.get('#root_project').select(projectId);
|
||||
cy.get('#root_category').select('other_fees');
|
||||
cy.get('#root_purpose').clear().type('Other Fees and Expenses means, collectively, all fees and expenses payable to Lenders under the Loan Documents, other than principal, interest and default interest/penalty amounts.');
|
||||
cy.get('#root_criticality').select('Medium');
|
||||
cy.get('#root_period').clear().type('2024-02-06');
|
||||
cy.get('#root_period').clear().type('20-02-2026');
|
||||
cy.get('body').click();
|
||||
cy.get('#root_vendor').clear().type('CO-WORK ENG');
|
||||
cy.get('#root_payment_method').select('Bank Transfer');
|
||||
cy.get('button')
|
||||
/*cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
|
||||
cy.contains('Task: Enter NDR Items', { timeout: 60000 });
|
||||
cy.get('#root_0_sub_category').select('coworking');
|
||||
cy.get('#root_0_item').clear().type('Coworking is not only about providing a physical place, but also about establishing a community');
|
||||
cy.get('#root_0_qty').clear().type('5');
|
||||
cy.get('#root_0_currency_type').select('Fiat');
|
||||
cy.get('#root_0_currency').select('EUR');
|
||||
cy.get('#root_0_unit_price').type('250');
|
||||
*/
|
||||
cy.get('#root_item_0_sub_category').select('coworking');
|
||||
cy.get('#root_item_0_item_name').clear().type('Coworking is not only about providing a physical place, but also about establishing a community');
|
||||
cy.get('#root_item_0_qty').clear().type('5');
|
||||
cy.get('#root_item_0_currency_type').select('Fiat');
|
||||
cy.get('#root_item_0_currency').select('EUR');
|
||||
cy.get('#root_item_0_unit_price').type('250');
|
||||
|
||||
|
||||
cy.get('button')
|
||||
|
@ -591,8 +654,47 @@ describe('Other Fees Path - With Files', () => {
|
|||
|
||||
cy.get('.cds--text-area__wrapper').find('#root').type('For professionals working in the professional services, ‘consultant’ and advisor’ are often used and fall under common terminology. Consultancy.uk zooms in on this field to get a closer look. \n https://www.consultancy.uk/career/what-is-consulting');
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
|
||||
cy.get("input[type=file]")
|
||||
.attachFile(['lorem-ipsum.pdf', 'png-5mb-1.png', 'Free_Test_Data_1MB_PDF.pdf', 'sampletext.txt']);
|
||||
.attachFile(['lorem-ipsum.pdf']);
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(2) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
cy.get("input[type=file]")
|
||||
.attachFile(['png-5mb-1.png']);
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(3) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(2) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get("input[type=file]")
|
||||
.attachFile(['Free_Test_Data_1MB_PDF.pdf']);
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(4) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(3) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(2) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get("input[type=file]")
|
||||
.attachFile(['sampletext.txt']);
|
||||
|
||||
cy.wait(2000);
|
||||
|
||||
cy.contains('Submit the Request').click();
|
||||
|
||||
|
@ -603,8 +705,9 @@ describe('Other Fees Path - With Files', () => {
|
|||
.contains(/^Submit$/)
|
||||
.click();
|
||||
|
||||
cy.contains('Tasks for my open instances', { timeout: 60000 });
|
||||
cy.contains('Started by me', { timeout: 60000 });
|
||||
cy.logout();
|
||||
cy.wait(1000);
|
||||
|
||||
let budgetOwnerUsername = Cypress.env('budgetowner_username');
|
||||
let budgetOwnerPassword = Cypress.env('budgetowner_password');
|
||||
|
@ -633,24 +736,25 @@ describe('Other Fees Path - With Files', () => {
|
|||
cy.visit('/');
|
||||
|
||||
cy.contains('Start New +').click();
|
||||
cy.contains('Raise New Demand Request');
|
||||
cy.contains('Request Goods/Services');
|
||||
|
||||
cy.runPrimaryBpmnFile(true);
|
||||
|
||||
cy.contains('Please select the type of request to start the process.');
|
||||
// wait a second to ensure we can click the radio button
|
||||
|
||||
cy.wait(2000);
|
||||
cy.get('input#root-procurement').click();
|
||||
cy.wait(2000);
|
||||
|
||||
|
||||
cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
/* cy.contains('Please select the type of request to start the process.');
|
||||
// wait a second to ensure we can click the radio button
|
||||
|
||||
cy.wait(2000);
|
||||
cy.get('input#root-procurement').click();
|
||||
cy.wait(2000);
|
||||
|
||||
|
||||
cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
*/
|
||||
|
||||
cy.contains(
|
||||
'Submit a new demand request for the procurement of needed items',
|
||||
'Request Goods/Services',
|
||||
{ timeout: 60000 }
|
||||
);
|
||||
|
||||
|
@ -660,24 +764,27 @@ describe('Other Fees Path - With Files', () => {
|
|||
const processInstanceId = currentUrl.match(/(?<=\/tasks\/)\d+/)[0];
|
||||
cy.log('==###############===processInstanceId : ', processInstanceId);
|
||||
let projectId = Cypress.env('project_id');
|
||||
cy.wait(2000);
|
||||
cy.get('#root_project').select(projectId);
|
||||
cy.get('#root_category').select('other_fees');
|
||||
cy.get('#root_purpose').clear().type('It allows cost savings and convenience through the use of common infrastructures, such as equipment, utilities and receptionist and custodial services, and in some cases refreshments and parcel services.\nhttps://en.wikipedia.org/wiki/Coworking');
|
||||
cy.get('#root_criticality').select('Low');
|
||||
cy.get('#root_period').clear().type('2025-02-25');
|
||||
cy.get('#root_period').clear().type('12-02-2025');
|
||||
cy.get('body').click();
|
||||
cy.get('#root_vendor').clear().type('BOUNTY');
|
||||
cy.get('#root_payment_method').select('Crypto Transfer');
|
||||
cy.get('button')
|
||||
/*cy.get('button')
|
||||
.contains(/^Submit$/)
|
||||
.click();
|
||||
|
||||
cy.contains('Task: Enter NDR Items', { timeout: 60000 });
|
||||
cy.get('#root_0_sub_category').select('bounties');
|
||||
cy.get('#root_0_item').clear().type('Coworking is distinct from business accelerators, business incubators, and executive suites.');
|
||||
cy.get('#root_0_qty').clear().type('4');
|
||||
cy.get('#root_0_currency_type').select('Crypto');
|
||||
cy.get('#root_0_currency').select('SNT');
|
||||
cy.get('#root_0_unit_price').type('450');
|
||||
*/
|
||||
cy.get('#root_item_0_sub_category').select('bounties');
|
||||
cy.get('#root_item_0_item_name').clear().type('Coworking is distinct from business accelerators, business incubators, and executive suites.');
|
||||
cy.get('#root_item_0_qty').clear().type('4');
|
||||
cy.get('#root_item_0_currency_type').select('Crypto');
|
||||
cy.get('#root_item_0_currency').select('SNT');
|
||||
cy.get('#root_item_0_unit_price').type('450');
|
||||
|
||||
|
||||
cy.get('button')
|
||||
|
@ -691,8 +798,47 @@ describe('Other Fees Path - With Files', () => {
|
|||
|
||||
cy.get('.cds--text-area__wrapper').find('#root').type('It\’s free and easy to post a job. Simply fill in a title, description and budget and competitive bids come within minutes. No job is too big or too small. We\'ve got freelancers for jobs of any size or budget across 1800 skills. No job is too complex.');
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
|
||||
cy.get("input[type=file]")
|
||||
.attachFile(['lorem-ipsum.pdf', 'png-5mb-1.png', 'Free_Test_Data_1MB_PDF.pdf', 'sampletext.txt']);
|
||||
.attachFile(['lorem-ipsum.pdf']);
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(2) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
cy.get("input[type=file]")
|
||||
.attachFile(['png-5mb-1.png']);
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(3) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(2) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get("input[type=file]")
|
||||
.attachFile(['Free_Test_Data_1MB_PDF.pdf']);
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div:nth-child(3) > p > button').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(4) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(3) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
cy.get('#root > div.row.array-item-list > div:nth-child(2) > div > div.cds--sm\\:col-span-1.cds--md\\:col-span-1.cds--lg\\:col-span-1.cds--css-grid-column > div > div > button.btn.btn-default.array-item-move-up > svg').click();
|
||||
cy.wait(1000);
|
||||
|
||||
cy.get("input[type=file]")
|
||||
.attachFile(['sampletext.txt']);
|
||||
|
||||
cy.wait(2000);
|
||||
|
||||
cy.contains('Submit the Request').click();
|
||||
|
||||
|
@ -703,8 +849,9 @@ describe('Other Fees Path - With Files', () => {
|
|||
.contains(/^Submit$/)
|
||||
.click();
|
||||
|
||||
cy.contains('Tasks for my open instances', { timeout: 60000 });
|
||||
cy.contains('Started by me', { timeout: 60000 });
|
||||
cy.logout();
|
||||
cy.wait(1000);
|
||||
|
||||
let budgetOwnerUsername = Cypress.env('budgetowner_username');
|
||||
let budgetOwnerPassword = Cypress.env('budgetowner_password');
|
||||
|
@ -733,7 +880,7 @@ describe('Other Fees Path - With Files', () => {
|
|||
budgetOwnerUsername,
|
||||
budgetOwnerPassword,
|
||||
processInstanceId,
|
||||
'Task: Reminder: Request Additional Budget',
|
||||
'Task: Reminder: Check Existing Budget',
|
||||
"approve"
|
||||
);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -7,19 +7,18 @@
|
|||
"@babel/plugin-transform-react-jsx": "^7.18.6",
|
||||
"@babel/preset-react": "^7.18.6",
|
||||
"@carbon/icons-react": "^11.10.0",
|
||||
"@carbon/react": "^1.16.0",
|
||||
"@carbon/react": "^1.27.0",
|
||||
"@carbon/styles": "^1.16.0",
|
||||
"@casl/ability": "^6.3.2",
|
||||
"@casl/react": "^3.1.0",
|
||||
"@ginkgo-bioworks/react-json-schema-form-builder": "^2.9.0",
|
||||
"@microsoft/fetch-event-source": "^2.0.1",
|
||||
"@monaco-editor/react": "^4.4.5",
|
||||
"@mui/material": "^5.10.14",
|
||||
"@react-icons/all-files": "^4.1.0",
|
||||
"@rjsf/core": "*",
|
||||
"@rjsf/mui": "^5.0.0-beta.13",
|
||||
"@rjsf/utils": "^5.0.0-beta.13",
|
||||
"@rjsf/validator-ajv8": "^5.0.0-beta.16",
|
||||
"@rjsf/core": "5.0.0-beta.20",
|
||||
"@rjsf/mui": "5.0.0-beta.20",
|
||||
"@rjsf/utils": "5.0.0-beta.20",
|
||||
"@rjsf/validator-ajv8": "5.0.0-beta.20",
|
||||
"@tanstack/react-table": "^8.2.2",
|
||||
"@testing-library/jest-dom": "^5.16.4",
|
||||
"@testing-library/react": "^13.3.0",
|
||||
|
@ -55,24 +54,17 @@
|
|||
"react-icons": "^4.4.0",
|
||||
"react-jsonschema-form": "^1.8.1",
|
||||
"react-router": "^6.3.0",
|
||||
"react-router-dom": "^6.3.0",
|
||||
"react-router-dom": "6.3.0",
|
||||
"react-scripts": "^5.0.1",
|
||||
"serve": "^14.0.0",
|
||||
"timepicker": "^1.13.18",
|
||||
"typescript": "^4.7.4",
|
||||
"use-debounce": "^9.0.4",
|
||||
"web-vitals": "^3.0.2"
|
||||
},
|
||||
"overrides": {
|
||||
"postcss-preset-env": {
|
||||
"autoprefixer": "10.4.5"
|
||||
},
|
||||
"@ginkgo-bioworks/react-json-schema-form-builder": {
|
||||
"react": "^18.2.0",
|
||||
"bootstrap": "^5.2.0-beta1"
|
||||
},
|
||||
"@carbon/react": {
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
// @ts-ignore
|
||||
import { Filter } from '@carbon/icons-react';
|
||||
import {
|
||||
Button,
|
||||
Grid,
|
||||
Column,
|
||||
// @ts-ignore
|
||||
} from '@carbon/react';
|
||||
|
||||
type OwnProps = {
|
||||
showFilterOptions: boolean;
|
||||
setShowFilterOptions: Function;
|
||||
filterOptions: Function;
|
||||
filtersEnabled?: boolean;
|
||||
reportSearchComponent?: Function | null;
|
||||
};
|
||||
|
||||
export default function Filters({
|
||||
showFilterOptions,
|
||||
setShowFilterOptions,
|
||||
filterOptions,
|
||||
reportSearchComponent = null,
|
||||
filtersEnabled = true,
|
||||
}: OwnProps) {
|
||||
const toggleShowFilterOptions = () => {
|
||||
setShowFilterOptions(!showFilterOptions);
|
||||
};
|
||||
|
||||
if (filtersEnabled) {
|
||||
let reportSearchSection = null;
|
||||
if (reportSearchComponent) {
|
||||
reportSearchSection = (
|
||||
<Column sm={2} md={4} lg={7}>
|
||||
{reportSearchComponent()}
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<Grid fullWidth>
|
||||
{reportSearchSection}
|
||||
<Column
|
||||
className="filterIcon"
|
||||
sm={{ span: 1, offset: 3 }}
|
||||
md={{ span: 1, offset: 7 }}
|
||||
lg={{ span: 1, offset: 15 }}
|
||||
>
|
||||
<Button
|
||||
data-qa="filter-section-expand-toggle"
|
||||
renderIcon={Filter}
|
||||
iconDescription="Filter Options"
|
||||
hasIconOnly
|
||||
size="lg"
|
||||
onClick={toggleShowFilterOptions}
|
||||
/>
|
||||
</Column>
|
||||
</Grid>
|
||||
{filterOptions()}
|
||||
</>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
|
@ -2,7 +2,7 @@ import { useEffect, useMemo, useRef, useState } from 'react';
|
|||
import { useNavigate, useParams, useSearchParams } from 'react-router-dom';
|
||||
|
||||
// @ts-ignore
|
||||
import { Filter, Close, AddAlt } from '@carbon/icons-react';
|
||||
import { Close, AddAlt } from '@carbon/icons-react';
|
||||
import {
|
||||
Button,
|
||||
ButtonSet,
|
||||
|
@ -71,6 +71,7 @@ import { usePermissionFetcher } from '../hooks/PermissionService';
|
|||
import { Can } from '../contexts/Can';
|
||||
import TableCellWithTimeAgoInWords from './TableCellWithTimeAgoInWords';
|
||||
import UserService from '../services/UserService';
|
||||
import Filters from './Filters';
|
||||
|
||||
type OwnProps = {
|
||||
filtersEnabled?: boolean;
|
||||
|
@ -1396,12 +1397,22 @@ export default function ProcessInstanceListTable({
|
|||
);
|
||||
}
|
||||
if (column.accessor === 'waiting_for') {
|
||||
return <td>{getWaitingForTableCellComponent(row)}</td>;
|
||||
return (
|
||||
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
|
||||
<td
|
||||
onClick={navigateToProcessInstance}
|
||||
onKeyDown={navigateToProcessInstance}
|
||||
>
|
||||
{getWaitingForTableCellComponent(row)}
|
||||
</td>
|
||||
);
|
||||
}
|
||||
if (column.accessor === 'updated_at_in_seconds') {
|
||||
return (
|
||||
<TableCellWithTimeAgoInWords
|
||||
timeInSeconds={row.updated_at_in_seconds}
|
||||
onClick={navigateToProcessInstance}
|
||||
onKeyDown={navigateToProcessInstance}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -1409,7 +1420,7 @@ export default function ProcessInstanceListTable({
|
|||
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
|
||||
<td
|
||||
data-qa={`process-instance-show-link-${column.accessor}`}
|
||||
onKeyDown={navigateToProcessModel}
|
||||
onKeyDown={navigateToProcessInstance}
|
||||
onClick={navigateToProcessInstance}
|
||||
>
|
||||
{formatter(row, value)}
|
||||
|
@ -1495,10 +1506,6 @@ export default function ProcessInstanceListTable({
|
|||
);
|
||||
};
|
||||
|
||||
const toggleShowFilterOptions = () => {
|
||||
setShowFilterOptions(!showFilterOptions);
|
||||
};
|
||||
|
||||
const reportSearchComponent = () => {
|
||||
if (showReports) {
|
||||
const columns = [
|
||||
|
@ -1518,37 +1525,6 @@ export default function ProcessInstanceListTable({
|
|||
return null;
|
||||
};
|
||||
|
||||
const filterComponent = () => {
|
||||
if (!filtersEnabled) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<Grid fullWidth>
|
||||
<Column sm={2} md={4} lg={7}>
|
||||
{reportSearchComponent()}
|
||||
</Column>
|
||||
<Column
|
||||
className="filterIcon"
|
||||
sm={{ span: 1, offset: 3 }}
|
||||
md={{ span: 1, offset: 7 }}
|
||||
lg={{ span: 1, offset: 15 }}
|
||||
>
|
||||
<Button
|
||||
data-qa="filter-section-expand-toggle"
|
||||
renderIcon={Filter}
|
||||
iconDescription="Filter Options"
|
||||
hasIconOnly
|
||||
size="lg"
|
||||
onClick={toggleShowFilterOptions}
|
||||
/>
|
||||
</Column>
|
||||
</Grid>
|
||||
{filterOptions()}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
if (pagination && (!textToShowIfEmpty || pagination.total > 0)) {
|
||||
// eslint-disable-next-line prefer-const
|
||||
let { page, perPage } = getPageInfoFromSearchParams(
|
||||
|
@ -1588,7 +1564,13 @@ export default function ProcessInstanceListTable({
|
|||
<>
|
||||
{reportColumnForm()}
|
||||
{processInstanceReportSaveTag()}
|
||||
{filterComponent()}
|
||||
<Filters
|
||||
filterOptions={filterOptions}
|
||||
showFilterOptions={showFilterOptions}
|
||||
setShowFilterOptions={setShowFilterOptions}
|
||||
reportSearchComponent={reportSearchComponent}
|
||||
filtersEnabled={filtersEnabled}
|
||||
/>
|
||||
{resultsTable}
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -4,13 +4,22 @@ import { convertSecondsToFormattedDateTime } from '../helpers';
|
|||
|
||||
type OwnProps = {
|
||||
timeInSeconds: number;
|
||||
onClick?: any;
|
||||
onKeyDown?: any;
|
||||
};
|
||||
|
||||
export default function TableCellWithTimeAgoInWords({
|
||||
timeInSeconds,
|
||||
onClick = null,
|
||||
onKeyDown = null,
|
||||
}: OwnProps) {
|
||||
return (
|
||||
<td title={convertSecondsToFormattedDateTime(timeInSeconds) || '-'}>
|
||||
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
|
||||
<td
|
||||
title={convertSecondsToFormattedDateTime(timeInSeconds) || '-'}
|
||||
onClick={onClick}
|
||||
onKeyDown={onKeyDown}
|
||||
>
|
||||
{timeInSeconds ? TimeAgo.inWords(timeInSeconds) : '-'}
|
||||
</td>
|
||||
);
|
||||
|
|
|
@ -26,6 +26,17 @@ export const underscorizeString = (inputString: string) => {
|
|||
return slugifyString(inputString).replace(/-/g, '_');
|
||||
};
|
||||
|
||||
export const selectKeysFromSearchParams = (obj: any, keys: string[]) => {
|
||||
const newSearchParams: { [key: string]: string } = {};
|
||||
keys.forEach((key: string) => {
|
||||
const value = obj.get(key);
|
||||
if (value) {
|
||||
newSearchParams[key] = value;
|
||||
}
|
||||
});
|
||||
return newSearchParams;
|
||||
};
|
||||
|
||||
export const capitalizeFirstLetter = (string: any) => {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||
};
|
||||
|
|
|
@ -1,16 +1,35 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
// @ts-ignore
|
||||
import { Table, Tabs, TabList, Tab } from '@carbon/react';
|
||||
import { Link, useParams, useSearchParams } from 'react-router-dom';
|
||||
import {
|
||||
Table,
|
||||
Tabs,
|
||||
TabList,
|
||||
Tab,
|
||||
Grid,
|
||||
Column,
|
||||
ButtonSet,
|
||||
Button,
|
||||
TextInput,
|
||||
ComboBox,
|
||||
// @ts-ignore
|
||||
} from '@carbon/react';
|
||||
import {
|
||||
createSearchParams,
|
||||
Link,
|
||||
useParams,
|
||||
useSearchParams,
|
||||
} from 'react-router-dom';
|
||||
import { useDebouncedCallback } from 'use-debounce';
|
||||
import PaginationForTable from '../components/PaginationForTable';
|
||||
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
||||
import {
|
||||
getPageInfoFromSearchParams,
|
||||
convertSecondsToFormattedDateTime,
|
||||
selectKeysFromSearchParams,
|
||||
} from '../helpers';
|
||||
import HttpService from '../services/HttpService';
|
||||
import { useUriListForPermissions } from '../hooks/UriListForPermissions';
|
||||
import { ProcessInstanceLogEntry } from '../interfaces';
|
||||
import Filters from '../components/Filters';
|
||||
|
||||
type OwnProps = {
|
||||
variant: string;
|
||||
|
@ -21,14 +40,42 @@ export default function ProcessInstanceLogList({ variant }: OwnProps) {
|
|||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const [processInstanceLogs, setProcessInstanceLogs] = useState([]);
|
||||
const [pagination, setPagination] = useState(null);
|
||||
|
||||
const [taskName, setTaskName] = useState<string>('');
|
||||
const [taskIdentifier, setTaskIdentifier] = useState<string>('');
|
||||
|
||||
const [taskTypes, setTaskTypes] = useState<string[]>([]);
|
||||
const [eventTypes, setEventTypes] = useState<string[]>([]);
|
||||
|
||||
const { targetUris } = useUriListForPermissions();
|
||||
const isDetailedView = searchParams.get('detailed') === 'true';
|
||||
|
||||
const taskNameHeader = isDetailedView ? 'Task Name' : 'Milestone';
|
||||
|
||||
const [showFilterOptions, setShowFilterOptions] = useState<boolean>(false);
|
||||
|
||||
let processInstanceShowPageBaseUrl = `/admin/process-instances/for-me/${params.process_model_id}`;
|
||||
if (variant === 'all') {
|
||||
processInstanceShowPageBaseUrl = `/admin/process-instances/${params.process_model_id}`;
|
||||
}
|
||||
|
||||
const updateSearchParams = (value: string, key: string) => {
|
||||
if (value) {
|
||||
searchParams.set(key, value);
|
||||
} else {
|
||||
searchParams.delete(key);
|
||||
}
|
||||
setSearchParams(searchParams);
|
||||
};
|
||||
|
||||
const addDebouncedSearchParams = useDebouncedCallback(
|
||||
(value: string, key: string) => {
|
||||
updateSearchParams(value, key);
|
||||
},
|
||||
// delay in ms
|
||||
1000
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
// Clear out any previous results to avoid a "flicker" effect where columns
|
||||
// are updated above the incorrect data.
|
||||
|
@ -39,11 +86,41 @@ export default function ProcessInstanceLogList({ variant }: OwnProps) {
|
|||
setProcessInstanceLogs(result.results);
|
||||
setPagination(result.pagination);
|
||||
};
|
||||
const { page, perPage } = getPageInfoFromSearchParams(searchParams);
|
||||
|
||||
const searchParamsToInclude = [
|
||||
'detailed',
|
||||
'page',
|
||||
'per_page',
|
||||
'bpmn_name',
|
||||
'bpmn_identifier',
|
||||
'task_type',
|
||||
'event_type',
|
||||
];
|
||||
const pickedSearchParams = selectKeysFromSearchParams(
|
||||
searchParams,
|
||||
searchParamsToInclude
|
||||
);
|
||||
|
||||
if ('bpmn_name' in pickedSearchParams) {
|
||||
setTaskName(pickedSearchParams.bpmn_name);
|
||||
}
|
||||
if ('bpmn_identifier' in pickedSearchParams) {
|
||||
setTaskIdentifier(pickedSearchParams.bpmn_identifier);
|
||||
}
|
||||
|
||||
HttpService.makeCallToBackend({
|
||||
path: `${targetUris.processInstanceLogListPath}?per_page=${perPage}&page=${page}&detailed=${isDetailedView}`,
|
||||
path: `${targetUris.processInstanceLogListPath}?${createSearchParams(
|
||||
pickedSearchParams
|
||||
)}`,
|
||||
successCallback: setProcessInstanceLogListFromResult,
|
||||
});
|
||||
HttpService.makeCallToBackend({
|
||||
path: `/v1.0/logs/types`,
|
||||
successCallback: (result: any) => {
|
||||
setTaskTypes(result.task_types);
|
||||
setEventTypes(result.event_types);
|
||||
},
|
||||
});
|
||||
}, [
|
||||
searchParams,
|
||||
params,
|
||||
|
@ -85,6 +162,7 @@ export default function ProcessInstanceLogList({ variant }: OwnProps) {
|
|||
if (isDetailedView) {
|
||||
tableRow.push(
|
||||
<>
|
||||
<td>{logEntry.task_definition_identifier}</td>
|
||||
<td>{logEntry.bpmn_task_type}</td>
|
||||
<td>{logEntry.event_type}</td>
|
||||
<td>
|
||||
|
@ -130,13 +208,13 @@ export default function ProcessInstanceLogList({ variant }: OwnProps) {
|
|||
<>
|
||||
<th>Id</th>
|
||||
<th>Bpmn Process</th>
|
||||
<th>Task Name</th>
|
||||
<th>{taskNameHeader}</th>
|
||||
</>
|
||||
);
|
||||
} else {
|
||||
tableHeaders.push(
|
||||
<>
|
||||
<th>Event</th>
|
||||
<th>{taskNameHeader}</th>
|
||||
<th>Bpmn Process</th>
|
||||
</>
|
||||
);
|
||||
|
@ -144,8 +222,9 @@ export default function ProcessInstanceLogList({ variant }: OwnProps) {
|
|||
if (isDetailedView) {
|
||||
tableHeaders.push(
|
||||
<>
|
||||
<th>Task Identifier</th>
|
||||
<th>Task Type</th>
|
||||
<th>Event</th>
|
||||
<th>Event Type</th>
|
||||
<th>User</th>
|
||||
</>
|
||||
);
|
||||
|
@ -160,60 +239,185 @@ export default function ProcessInstanceLogList({ variant }: OwnProps) {
|
|||
</Table>
|
||||
);
|
||||
};
|
||||
const selectedTabIndex = isDetailedView ? 1 : 0;
|
||||
|
||||
if (pagination) {
|
||||
const { page, perPage } = getPageInfoFromSearchParams(searchParams);
|
||||
const resetFilters = () => {
|
||||
setTaskIdentifier('');
|
||||
setTaskName('');
|
||||
|
||||
['bpmn_name', 'bpmn_identifier', 'task_type', 'event_type'].forEach(
|
||||
(value: string) => searchParams.delete(value)
|
||||
);
|
||||
|
||||
setSearchParams(searchParams);
|
||||
};
|
||||
|
||||
const shouldFilterStringItem = (options: any) => {
|
||||
const stringItem = options.item;
|
||||
let { inputValue } = options;
|
||||
if (!inputValue) {
|
||||
inputValue = '';
|
||||
}
|
||||
return stringItem.toLowerCase().includes(inputValue.toLowerCase());
|
||||
};
|
||||
|
||||
const filterOptions = () => {
|
||||
if (!showFilterOptions) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const filterElements = [];
|
||||
filterElements.push(
|
||||
<Column md={4}>
|
||||
<TextInput
|
||||
id="task-name-filter"
|
||||
labelText={taskNameHeader}
|
||||
value={taskName}
|
||||
onChange={(event: any) => {
|
||||
const newValue = event.target.value;
|
||||
setTaskName(newValue);
|
||||
addDebouncedSearchParams(newValue, 'bpmn_name');
|
||||
}}
|
||||
/>
|
||||
</Column>
|
||||
);
|
||||
|
||||
if (isDetailedView) {
|
||||
filterElements.push(
|
||||
<>
|
||||
<Column md={4}>
|
||||
<TextInput
|
||||
id="task-identifier-filter"
|
||||
labelText="Task Identifier"
|
||||
value={taskIdentifier}
|
||||
onChange={(event: any) => {
|
||||
const newValue = event.target.value;
|
||||
setTaskIdentifier(newValue);
|
||||
addDebouncedSearchParams(newValue, 'bpmn_identifier');
|
||||
}}
|
||||
/>
|
||||
</Column>
|
||||
<Column md={4}>
|
||||
<ComboBox
|
||||
onChange={(value: any) => {
|
||||
updateSearchParams(value.selectedItem, 'task_type');
|
||||
}}
|
||||
id="task-type-select"
|
||||
data-qa="task-type-select"
|
||||
items={taskTypes}
|
||||
itemToString={(value: string) => {
|
||||
return value;
|
||||
}}
|
||||
shouldFilterItem={shouldFilterStringItem}
|
||||
placeholder="Choose a process model"
|
||||
titleText="Task Type"
|
||||
selectedItem={searchParams.get('task_type')}
|
||||
/>
|
||||
</Column>
|
||||
<Column md={4}>
|
||||
<ComboBox
|
||||
onChange={(value: any) => {
|
||||
updateSearchParams(value.selectedItem, 'event_type');
|
||||
}}
|
||||
id="event-type-select"
|
||||
data-qa="event-type-select"
|
||||
items={eventTypes}
|
||||
itemToString={(value: string) => {
|
||||
return value;
|
||||
}}
|
||||
shouldFilterItem={shouldFilterStringItem}
|
||||
placeholder="Choose a process model"
|
||||
titleText="Event Type"
|
||||
selectedItem={searchParams.get('event_type')}
|
||||
/>
|
||||
</Column>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<ProcessBreadcrumb
|
||||
hotCrumbs={[
|
||||
['Process Groups', '/admin'],
|
||||
{
|
||||
entityToExplode: params.process_model_id || '',
|
||||
entityType: 'process-model-id',
|
||||
linkLastItem: true,
|
||||
},
|
||||
[
|
||||
`Process Instance: ${params.process_instance_id}`,
|
||||
`${processInstanceShowPageBaseUrl}/${params.process_instance_id}`,
|
||||
],
|
||||
['Logs'],
|
||||
]}
|
||||
/>
|
||||
<Tabs selectedIndex={selectedTabIndex}>
|
||||
<TabList aria-label="List of tabs">
|
||||
<Tab
|
||||
title="Only show a subset of the logs, and show fewer columns"
|
||||
data-qa="process-instance-log-simple"
|
||||
onClick={() => {
|
||||
searchParams.set('detailed', 'false');
|
||||
setSearchParams(searchParams);
|
||||
}}
|
||||
>
|
||||
Milestones
|
||||
</Tab>
|
||||
<Tab
|
||||
title="Show all logs for this process instance, and show extra columns that may be useful for debugging"
|
||||
data-qa="process-instance-log-detailed"
|
||||
onClick={() => {
|
||||
searchParams.set('detailed', 'true');
|
||||
setSearchParams(searchParams);
|
||||
}}
|
||||
>
|
||||
Events
|
||||
</Tab>
|
||||
</TabList>
|
||||
</Tabs>
|
||||
<br />
|
||||
<PaginationForTable
|
||||
page={page}
|
||||
perPage={perPage}
|
||||
pagination={pagination}
|
||||
tableToDisplay={buildTable()}
|
||||
/>
|
||||
<Grid fullWidth className="with-bottom-margin">
|
||||
{filterElements}
|
||||
</Grid>
|
||||
<Grid fullWidth className="with-bottom-margin">
|
||||
<Column sm={4} md={4} lg={8}>
|
||||
<ButtonSet>
|
||||
<Button
|
||||
kind=""
|
||||
className="button-white-background narrow-button"
|
||||
onClick={resetFilters}
|
||||
>
|
||||
Reset
|
||||
</Button>
|
||||
</ButtonSet>
|
||||
</Column>
|
||||
</Grid>
|
||||
</>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const tabs = () => {
|
||||
const selectedTabIndex = isDetailedView ? 1 : 0;
|
||||
return (
|
||||
<Tabs selectedIndex={selectedTabIndex}>
|
||||
<TabList aria-label="List of tabs">
|
||||
<Tab
|
||||
title="Only show a subset of the logs, and show fewer columns"
|
||||
data-qa="process-instance-log-simple"
|
||||
onClick={() => {
|
||||
searchParams.set('detailed', 'false');
|
||||
setSearchParams(searchParams);
|
||||
}}
|
||||
>
|
||||
Milestones
|
||||
</Tab>
|
||||
<Tab
|
||||
title="Show all logs for this process instance, and show extra columns that may be useful for debugging"
|
||||
data-qa="process-instance-log-detailed"
|
||||
onClick={() => {
|
||||
searchParams.set('detailed', 'true');
|
||||
setSearchParams(searchParams);
|
||||
}}
|
||||
>
|
||||
Events
|
||||
</Tab>
|
||||
</TabList>
|
||||
</Tabs>
|
||||
);
|
||||
};
|
||||
|
||||
const { page, perPage } = getPageInfoFromSearchParams(searchParams);
|
||||
return (
|
||||
<>
|
||||
<ProcessBreadcrumb
|
||||
hotCrumbs={[
|
||||
['Process Groups', '/admin'],
|
||||
{
|
||||
entityToExplode: params.process_model_id || '',
|
||||
entityType: 'process-model-id',
|
||||
linkLastItem: true,
|
||||
},
|
||||
[
|
||||
`Process Instance: ${params.process_instance_id}`,
|
||||
`${processInstanceShowPageBaseUrl}/${params.process_instance_id}`,
|
||||
],
|
||||
['Logs'],
|
||||
]}
|
||||
/>
|
||||
{tabs()}
|
||||
<Filters
|
||||
filterOptions={filterOptions}
|
||||
showFilterOptions={showFilterOptions}
|
||||
setShowFilterOptions={setShowFilterOptions}
|
||||
filtersEnabled
|
||||
/>
|
||||
<br />
|
||||
<PaginationForTable
|
||||
page={page}
|
||||
perPage={perPage}
|
||||
pagination={pagination}
|
||||
tableToDisplay={buildTable()}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ import {
|
|||
ComboBox,
|
||||
Button,
|
||||
ButtonSet,
|
||||
// @ts-ignore
|
||||
} from '@carbon/react';
|
||||
|
||||
import MDEditor from '@uiw/react-md-editor';
|
||||
|
|
|
@ -54,13 +54,6 @@ export default function BaseInputTemplate<
|
|||
...getInputProps<T, S, F>(schema, type, options),
|
||||
};
|
||||
|
||||
let inputValue;
|
||||
if (inputProps.type === 'number' || inputProps.type === 'integer') {
|
||||
inputValue = value || value === 0 ? value : '';
|
||||
} else {
|
||||
inputValue = value == null ? '' : value;
|
||||
}
|
||||
|
||||
const _onChange = useCallback(
|
||||
({ target: { value } }: React.ChangeEvent<HTMLInputElement>) =>
|
||||
onChange(value === '' ? options.emptyValue : value),
|
||||
|
@ -143,7 +136,6 @@ export default function BaseInputTemplate<
|
|||
<>
|
||||
<TextInput
|
||||
id={id}
|
||||
name={id}
|
||||
className="text-input"
|
||||
helperText={helperText}
|
||||
invalid={invalid}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
// @ts-ignore
|
||||
import { Select, SelectItem } from '@carbon/react';
|
||||
import { WidgetProps, processSelectValue } from '@rjsf/utils';
|
||||
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
// carbon/react is not very typescript safe so ignore it
|
||||
declare module '@carbon/react';
|
Loading…
Reference in New Issue