mirror of
https://github.com/sartography/spiff-arena.git
synced 2025-01-12 18:44:14 +00:00
Merge remote-tracking branch 'origin/main' into feature/store_boundary_events_properly
This commit is contained in:
commit
2c1433544f
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,5 +1,6 @@
|
|||||||
pyrightconfig.json
|
pyrightconfig.json
|
||||||
.idea/
|
.idea/
|
||||||
t
|
t
|
||||||
|
*~
|
||||||
.dccache
|
.dccache
|
||||||
*~
|
*~
|
@ -2089,6 +2089,37 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
$ref: "#/components/schemas/Secret"
|
$ref: "#/components/schemas/Secret"
|
||||||
|
|
||||||
|
/connector-proxy/type-ahead/{category}:
|
||||||
|
parameters:
|
||||||
|
- name: category
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
description: The category for the type-ahead search
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: prefix
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
description: The prefix to search for
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: limit
|
||||||
|
in: query
|
||||||
|
required: true
|
||||||
|
description: The maximum number of search results
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
get:
|
||||||
|
operationId: spiffworkflow_backend.routes.connector_proxy_controller.type_ahead
|
||||||
|
summary: Return type ahead search results
|
||||||
|
tags:
|
||||||
|
- Type Ahead
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: We return type ahead search results
|
||||||
|
#content:
|
||||||
|
# - application/json
|
||||||
|
|
||||||
components:
|
components:
|
||||||
securitySchemes:
|
securitySchemes:
|
||||||
jwt:
|
jwt:
|
||||||
|
@ -41,6 +41,10 @@ SPIFFWORKFLOW_BACKEND_URL = environ.get("SPIFFWORKFLOW_BACKEND_URL", default="ht
|
|||||||
SPIFFWORKFLOW_BACKEND_CONNECTOR_PROXY_URL = environ.get(
|
SPIFFWORKFLOW_BACKEND_CONNECTOR_PROXY_URL = environ.get(
|
||||||
"SPIFFWORKFLOW_BACKEND_CONNECTOR_PROXY_URL", default="http://localhost:7004"
|
"SPIFFWORKFLOW_BACKEND_CONNECTOR_PROXY_URL", default="http://localhost:7004"
|
||||||
)
|
)
|
||||||
|
SPIFFWORKFLOW_BACKEND_CONNECTOR_PROXY_TYPE_AHEAD_URL = environ.get(
|
||||||
|
"SPIFFWORKFLOW_BACKEND_CONNECTOR_PROXY_TYPE_AHEAD_URL",
|
||||||
|
default="https://emehvlxpwodjawtgi7ctkbvpse0vmaow.lambda-url.us-east-1.on.aws",
|
||||||
|
)
|
||||||
|
|
||||||
# Open ID server
|
# Open ID server
|
||||||
# use "http://localhost:7000/openid" for running with simple openid
|
# use "http://localhost:7000/openid" for running with simple openid
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import flask.wrappers
|
||||||
|
import requests
|
||||||
|
from flask import current_app
|
||||||
|
from flask.wrappers import Response
|
||||||
|
|
||||||
|
|
||||||
|
def connector_proxy_type_ahead_url() -> Any:
|
||||||
|
"""Returns the connector proxy type ahead url."""
|
||||||
|
return current_app.config["SPIFFWORKFLOW_BACKEND_CONNECTOR_PROXY_TYPE_AHEAD_URL"]
|
||||||
|
|
||||||
|
|
||||||
|
def type_ahead(category: str, prefix: str, limit: int) -> flask.wrappers.Response:
|
||||||
|
url = f"{connector_proxy_type_ahead_url()}/v1/type-ahead/{category}?prefix={prefix}&limit={limit}"
|
||||||
|
|
||||||
|
proxy_response = requests.get(url)
|
||||||
|
status = proxy_response.status_code
|
||||||
|
if status // 100 == 2:
|
||||||
|
response = proxy_response.text
|
||||||
|
else:
|
||||||
|
# supress pop up errors on the client
|
||||||
|
status = 200
|
||||||
|
response = "[]"
|
||||||
|
return Response(response, status=status, mimetype="application/json")
|
@ -59,6 +59,12 @@ def message_instance_list(
|
|||||||
# payload: dict,
|
# payload: dict,
|
||||||
# process_instance_id: Optional[int],
|
# process_instance_id: Optional[int],
|
||||||
# }
|
# }
|
||||||
|
#
|
||||||
|
# For example:
|
||||||
|
# curl 'http://localhost:7000/v1.0/messages/gogo' \
|
||||||
|
# -H 'authorization: Bearer [FIXME]' \
|
||||||
|
# -H 'content-type: application/json' \
|
||||||
|
# --data-raw '{"payload":{"sure": "yes", "food": "spicy"}}'
|
||||||
def message_send(
|
def message_send(
|
||||||
message_name: str,
|
message_name: str,
|
||||||
body: Dict[str, Any],
|
body: Dict[str, Any],
|
||||||
|
4
spiffworkflow-frontend/package-lock.json
generated
4
spiffworkflow-frontend/package-lock.json
generated
@ -8065,7 +8065,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/bpmn-js-spiffworkflow": {
|
"node_modules/bpmn-js-spiffworkflow": {
|
||||||
"version": "0.0.8",
|
"version": "0.0.8",
|
||||||
"resolved": "git+ssh://git@github.com/sartography/bpmn-js-spiffworkflow.git#1fa1f8741605ae1e1cd6d645d07e03953943c8cc",
|
"resolved": "git+ssh://git@github.com/sartography/bpmn-js-spiffworkflow.git#6391337a86a6342fcfcfcd3e57d39cb61c7af668",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"inherits": "^2.0.4",
|
"inherits": "^2.0.4",
|
||||||
@ -38214,7 +38214,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bpmn-js-spiffworkflow": {
|
"bpmn-js-spiffworkflow": {
|
||||||
"version": "git+ssh://git@github.com/sartography/bpmn-js-spiffworkflow.git#1fa1f8741605ae1e1cd6d645d07e03953943c8cc",
|
"version": "git+ssh://git@github.com/sartography/bpmn-js-spiffworkflow.git#6391337a86a6342fcfcfcd3e57d39cb61c7af668",
|
||||||
"from": "bpmn-js-spiffworkflow@sartography/bpmn-js-spiffworkflow#main",
|
"from": "bpmn-js-spiffworkflow@sartography/bpmn-js-spiffworkflow#main",
|
||||||
"requires": {
|
"requires": {
|
||||||
"inherits": "^2.0.4",
|
"inherits": "^2.0.4",
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
import { useNavigate, useParams } from 'react-router-dom';
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
import validator from '@rjsf/validator-ajv8';
|
import validator from '@rjsf/validator-ajv8';
|
||||||
|
|
||||||
@ -8,6 +8,7 @@ import {
|
|||||||
Tabs,
|
Tabs,
|
||||||
Grid,
|
Grid,
|
||||||
Column,
|
Column,
|
||||||
|
ComboBox,
|
||||||
Button,
|
Button,
|
||||||
ButtonSet,
|
ButtonSet,
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@ -22,6 +23,73 @@ import { modifyProcessIdentifierForPathParam } from '../helpers';
|
|||||||
import { ProcessInstanceTask } from '../interfaces';
|
import { ProcessInstanceTask } from '../interfaces';
|
||||||
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
||||||
|
|
||||||
|
// TODO: move this somewhere else
|
||||||
|
function TypeAheadWidget({
|
||||||
|
id,
|
||||||
|
onChange,
|
||||||
|
options: { category, itemFormat },
|
||||||
|
}: {
|
||||||
|
id: string;
|
||||||
|
onChange: any;
|
||||||
|
options: any;
|
||||||
|
}) {
|
||||||
|
const pathForCategory = (inputText: string) => {
|
||||||
|
return `/connector-proxy/type-ahead/${category}?prefix=${inputText}&limit=100`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const lastSearchTerm = useRef('');
|
||||||
|
const [items, setItems] = useState<any[]>([]);
|
||||||
|
const [selectedItem, setSelectedItem] = useState<any>(null);
|
||||||
|
const itemFormatRegex = /[^{}]+(?=})/g;
|
||||||
|
const itemFormatSubstitutions = itemFormat.match(itemFormatRegex);
|
||||||
|
|
||||||
|
const itemToString = (item: any) => {
|
||||||
|
if (!item) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let str = itemFormat;
|
||||||
|
itemFormatSubstitutions.forEach((key: string) => {
|
||||||
|
str = str.replace(`{${key}}`, item[key]);
|
||||||
|
});
|
||||||
|
return str;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleTypeAheadResult = (result: any, inputText: string) => {
|
||||||
|
if (lastSearchTerm.current === inputText) {
|
||||||
|
setItems(result);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const typeAheadSearch = (inputText: string) => {
|
||||||
|
if (inputText) {
|
||||||
|
lastSearchTerm.current = inputText;
|
||||||
|
// TODO: check cache of prefixes -> results
|
||||||
|
HttpService.makeCallToBackend({
|
||||||
|
path: pathForCategory(inputText),
|
||||||
|
successCallback: (result: any) =>
|
||||||
|
handleTypeAheadResult(result, inputText),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ComboBox
|
||||||
|
onInputChange={typeAheadSearch}
|
||||||
|
onChange={(event: any) => {
|
||||||
|
setSelectedItem(event.selectedItem);
|
||||||
|
onChange(itemToString(event.selectedItem));
|
||||||
|
}}
|
||||||
|
id={id}
|
||||||
|
items={items}
|
||||||
|
itemToString={itemToString}
|
||||||
|
placeholder={`Start typing to search for ${category}...`}
|
||||||
|
titleText={`Type ahead search for ${category}`}
|
||||||
|
selectedItem={selectedItem}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
class UnexpectedHumanTaskType extends Error {
|
class UnexpectedHumanTaskType extends Error {
|
||||||
constructor(message: string) {
|
constructor(message: string) {
|
||||||
super(message);
|
super(message);
|
||||||
@ -294,6 +362,8 @@ export default function TaskShow() {
|
|||||||
return getFieldsWithDateValidations(jsonSchema, formData, errors);
|
return getFieldsWithDateValidations(jsonSchema, formData, errors);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const widgets = { typeAhead: TypeAheadWidget };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid fullWidth condensed>
|
<Grid fullWidth condensed>
|
||||||
<Column sm={4} md={5} lg={8}>
|
<Column sm={4} md={5} lg={8}>
|
||||||
@ -303,6 +373,7 @@ export default function TaskShow() {
|
|||||||
onSubmit={handleFormSubmit}
|
onSubmit={handleFormSubmit}
|
||||||
schema={jsonSchema}
|
schema={jsonSchema}
|
||||||
uiSchema={formUiSchema}
|
uiSchema={formUiSchema}
|
||||||
|
widgets={widgets}
|
||||||
validator={validator}
|
validator={validator}
|
||||||
onChange={updateFormData}
|
onChange={updateFormData}
|
||||||
customValidate={customValidate}
|
customValidate={customValidate}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user