Merge pull request #22 from sartography/feature/carbon_ui
Feature/carbon UI
This commit is contained in:
commit
2db70303c2
|
@ -153,7 +153,6 @@ paths:
|
|||
description: The number of groups to show per page. Defaults to page 10.
|
||||
schema:
|
||||
type: integer
|
||||
# process_groups_list
|
||||
get:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_groups_list
|
||||
summary: get list
|
||||
|
@ -168,7 +167,6 @@ paths:
|
|||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/ProcessModelCategory"
|
||||
# process_group_add
|
||||
post:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_group_add
|
||||
summary: Add process group
|
||||
|
@ -429,7 +427,7 @@ paths:
|
|||
description: For filtering - beginning of start window - in seconds since epoch
|
||||
schema:
|
||||
type: integer
|
||||
- name: start_till
|
||||
- name: start_to
|
||||
in: query
|
||||
required: false
|
||||
description: For filtering - end of start window - in seconds since epoch
|
||||
|
@ -441,7 +439,7 @@ paths:
|
|||
description: For filtering - beginning of end window - in seconds since epoch
|
||||
schema:
|
||||
type: integer
|
||||
- name: end_till
|
||||
- name: end_to
|
||||
in: query
|
||||
required: false
|
||||
description: For filtering - end of end window - in seconds since epoch
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""Process_group."""
|
||||
from __future__ import annotations
|
||||
|
||||
import dataclasses
|
||||
from dataclasses import dataclass
|
||||
from dataclasses import field
|
||||
from typing import Any
|
||||
|
@ -20,6 +21,7 @@ class ProcessGroup:
|
|||
|
||||
id: str # A unique string name, lower case, under scores (ie, 'my_group')
|
||||
display_name: str
|
||||
description: str | None = None
|
||||
display_order: int | None = 0
|
||||
admin: bool | None = False
|
||||
process_models: list[ProcessModelInfo] = field(
|
||||
|
@ -38,6 +40,12 @@ class ProcessGroup:
|
|||
return True
|
||||
return False
|
||||
|
||||
@property
|
||||
def serialized(self) -> dict:
|
||||
"""Serialized."""
|
||||
original_dict = dataclasses.asdict(self)
|
||||
return {x: original_dict[x] for x in original_dict if x not in ["sort_index"]}
|
||||
|
||||
|
||||
class ProcessGroupSchema(Schema):
|
||||
"""ProcessGroupSchema."""
|
||||
|
|
|
@ -30,7 +30,6 @@ class ProcessModelInfo:
|
|||
display_name: str
|
||||
description: str
|
||||
process_group_id: str = ""
|
||||
process_group: Any | None = None
|
||||
primary_file_name: str | None = None
|
||||
primary_process_id: str | None = None
|
||||
display_order: int | None = 0
|
||||
|
|
|
@ -43,6 +43,7 @@ from spiffworkflow_backend.models.message_triggerable_process_model import (
|
|||
MessageTriggerableProcessModel,
|
||||
)
|
||||
from spiffworkflow_backend.models.principal import PrincipalModel
|
||||
from spiffworkflow_backend.models.process_group import ProcessGroup
|
||||
from spiffworkflow_backend.models.process_group import ProcessGroupSchema
|
||||
from spiffworkflow_backend.models.process_instance import ProcessInstanceApiSchema
|
||||
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
|
||||
|
@ -135,18 +136,12 @@ def permissions_check(body: Dict[str, Dict[str, list[str]]]) -> flask.wrappers.R
|
|||
return make_response(jsonify({"results": response_dict}), 200)
|
||||
|
||||
|
||||
def process_group_add(
|
||||
body: Dict[str, Union[str, bool, int]]
|
||||
) -> flask.wrappers.Response:
|
||||
def process_group_add(body: dict) -> flask.wrappers.Response:
|
||||
"""Add_process_group."""
|
||||
process_model_service = ProcessModelService()
|
||||
process_group = ProcessGroupSchema().load(body)
|
||||
process_group = ProcessGroup(**body)
|
||||
process_model_service.add_process_group(process_group)
|
||||
return Response(
|
||||
json.dumps(ProcessGroupSchema().dump(process_group)),
|
||||
status=201,
|
||||
mimetype="application/json",
|
||||
)
|
||||
return make_response(jsonify(process_group), 201)
|
||||
|
||||
|
||||
def process_group_delete(process_group_id: str) -> flask.wrappers.Response:
|
||||
|
@ -155,13 +150,18 @@ def process_group_delete(process_group_id: str) -> flask.wrappers.Response:
|
|||
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def process_group_update(
|
||||
process_group_id: str, body: Dict[str, Union[str, bool, int]]
|
||||
) -> Dict[str, Union[str, bool, int]]:
|
||||
def process_group_update(process_group_id: str, body: dict) -> flask.wrappers.Response:
|
||||
"""Process Group Update."""
|
||||
process_group = ProcessGroupSchema().load(body)
|
||||
body_include_list = ["display_name", "description"]
|
||||
body_filtered = {
|
||||
include_item: body[include_item]
|
||||
for include_item in body_include_list
|
||||
if include_item in body
|
||||
}
|
||||
|
||||
process_group = ProcessGroup(id=process_group_id, **body_filtered)
|
||||
ProcessModelService().update_process_group(process_group)
|
||||
return ProcessGroupSchema().dump(process_group) # type: ignore
|
||||
return make_response(jsonify(process_group), 200)
|
||||
|
||||
|
||||
def process_groups_list(page: int = 1, per_page: int = 100) -> flask.wrappers.Response:
|
||||
|
@ -174,6 +174,7 @@ def process_groups_list(page: int = 1, per_page: int = 100) -> flask.wrappers.Re
|
|||
remainder = len(process_groups) % per_page
|
||||
if remainder > 0:
|
||||
pages += 1
|
||||
|
||||
response_json = {
|
||||
"results": ProcessGroupSchema(many=True).dump(batch),
|
||||
"pagination": {
|
||||
|
@ -199,7 +200,7 @@ def process_group_show(
|
|||
status_code=400,
|
||||
)
|
||||
) from exception
|
||||
return ProcessGroupSchema().dump(process_group)
|
||||
return make_response(jsonify(process_group), 200)
|
||||
|
||||
|
||||
def process_model_add(
|
||||
|
@ -225,7 +226,6 @@ def process_model_add(
|
|||
status_code=400,
|
||||
)
|
||||
|
||||
process_model_info.process_group = process_group
|
||||
process_model_service.add_spec(process_model_info)
|
||||
return Response(
|
||||
json.dumps(ProcessModelInfoSchema().dump(process_model_info)),
|
||||
|
@ -651,9 +651,9 @@ def process_instance_list(
|
|||
page: int = 1,
|
||||
per_page: int = 100,
|
||||
start_from: Optional[int] = None,
|
||||
start_till: Optional[int] = None,
|
||||
start_to: Optional[int] = None,
|
||||
end_from: Optional[int] = None,
|
||||
end_till: Optional[int] = None,
|
||||
end_to: Optional[int] = None,
|
||||
process_status: Optional[str] = None,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_list."""
|
||||
|
@ -684,17 +684,17 @@ def process_instance_list(
|
|||
process_instance_query = process_instance_query.filter(
|
||||
ProcessInstanceModel.start_in_seconds >= start_from
|
||||
)
|
||||
if start_till is not None:
|
||||
if start_to is not None:
|
||||
process_instance_query = process_instance_query.filter(
|
||||
ProcessInstanceModel.start_in_seconds <= start_till
|
||||
ProcessInstanceModel.start_in_seconds <= start_to
|
||||
)
|
||||
if end_from is not None:
|
||||
process_instance_query = process_instance_query.filter(
|
||||
ProcessInstanceModel.end_in_seconds >= end_from
|
||||
)
|
||||
if end_till is not None:
|
||||
if end_to is not None:
|
||||
process_instance_query = process_instance_query.filter(
|
||||
ProcessInstanceModel.end_in_seconds <= end_till
|
||||
ProcessInstanceModel.end_in_seconds <= end_to
|
||||
)
|
||||
if process_status is not None:
|
||||
process_status_array = process_status.split(",")
|
||||
|
|
|
@ -170,7 +170,7 @@ class ProcessModelService(FileSystemService):
|
|||
json_path = os.path.join(cat_path, self.CAT_JSON_FILE)
|
||||
with open(json_path, "w") as cat_json:
|
||||
json.dump(
|
||||
self.GROUP_SCHEMA.dump(process_group),
|
||||
process_group.serialized,
|
||||
cat_json,
|
||||
indent=4,
|
||||
sort_keys=True,
|
||||
|
@ -274,6 +274,5 @@ class ProcessModelService(FileSystemService):
|
|||
with open(spec_path, "w") as wf_json:
|
||||
json.dump(self.WF_SCHEMA.dump(spec), wf_json, indent=4)
|
||||
if process_group:
|
||||
spec.process_group = process_group
|
||||
spec.process_group_id = process_group.id
|
||||
return spec
|
||||
|
|
|
@ -17,7 +17,6 @@ from spiffworkflow_backend.exceptions.process_entity_not_found_error import (
|
|||
from spiffworkflow_backend.models.active_task import ActiveTaskModel
|
||||
from spiffworkflow_backend.models.group import GroupModel
|
||||
from spiffworkflow_backend.models.process_group import ProcessGroup
|
||||
from spiffworkflow_backend.models.process_group import ProcessGroupSchema
|
||||
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
|
||||
from spiffworkflow_backend.models.process_instance import ProcessInstanceStatus
|
||||
from spiffworkflow_backend.models.process_instance_report import (
|
||||
|
@ -388,25 +387,29 @@ class TestProcessApi(BaseTest):
|
|||
display_name="Another Test Category",
|
||||
display_order=0,
|
||||
admin=False,
|
||||
description="Test Description",
|
||||
)
|
||||
response = client.post(
|
||||
"/v1.0/process-groups",
|
||||
headers=self.logged_in_headers(with_super_admin_user),
|
||||
content_type="application/json",
|
||||
data=json.dumps(ProcessGroupSchema().dump(process_group)),
|
||||
data=json.dumps(process_group.serialized),
|
||||
)
|
||||
assert response.status_code == 201
|
||||
assert response.json
|
||||
|
||||
# Check what is returned
|
||||
result = ProcessGroupSchema().loads(response.get_data(as_text=True))
|
||||
result = ProcessGroup(**response.json)
|
||||
assert result is not None
|
||||
assert result.display_name == "Another Test Category"
|
||||
assert result.id == "test"
|
||||
assert result.description == "Test Description"
|
||||
|
||||
# Check what is persisted
|
||||
persisted = ProcessModelService().get_process_group("test")
|
||||
assert persisted.display_name == "Another Test Category"
|
||||
assert persisted.id == "test"
|
||||
assert persisted.description == "Test Description"
|
||||
|
||||
def test_process_group_delete(
|
||||
self,
|
||||
|
@ -461,7 +464,7 @@ class TestProcessApi(BaseTest):
|
|||
f"/v1.0/process-groups/{group_id}",
|
||||
headers=self.logged_in_headers(with_super_admin_user),
|
||||
content_type="application/json",
|
||||
data=json.dumps(ProcessGroupSchema().dump(process_group)),
|
||||
data=json.dumps(process_group.serialized),
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
|
@ -788,6 +791,7 @@ class TestProcessApi(BaseTest):
|
|||
f"/v1.0/process-groups/{test_process_group_id}",
|
||||
headers=self.logged_in_headers(with_super_admin_user),
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response.json is not None
|
||||
assert response.json["id"] == test_process_group_id
|
||||
|
@ -1299,7 +1303,7 @@ class TestProcessApi(BaseTest):
|
|||
|
||||
# start > 2000, end < 5000 - this should eliminate the first 2 and the last
|
||||
response = client.get(
|
||||
"/v1.0/process-instances?start_from=2001&end_till=5999",
|
||||
"/v1.0/process-instances?start_from=2001&end_to=5999",
|
||||
headers=self.logged_in_headers(with_super_admin_user),
|
||||
)
|
||||
assert response.json is not None
|
||||
|
@ -1310,7 +1314,7 @@ class TestProcessApi(BaseTest):
|
|||
|
||||
# start > 1000, start < 4000 - this should eliminate the first and the last 2
|
||||
response = client.get(
|
||||
"/v1.0/process-instances?start_from=1001&start_till=3999",
|
||||
"/v1.0/process-instances?start_from=1001&start_to=3999",
|
||||
headers=self.logged_in_headers(with_super_admin_user),
|
||||
)
|
||||
assert response.json is not None
|
||||
|
@ -1321,7 +1325,7 @@ class TestProcessApi(BaseTest):
|
|||
|
||||
# end > 2000, end < 6000 - this should eliminate the first and the last
|
||||
response = client.get(
|
||||
"/v1.0/process-instances?end_from=2001&end_till=5999",
|
||||
"/v1.0/process-instances?end_from=2001&end_to=5999",
|
||||
headers=self.logged_in_headers(with_super_admin_user),
|
||||
)
|
||||
assert response.json is not None
|
||||
|
|
|
@ -10,4 +10,9 @@ module.exports = defineConfig({
|
|||
// implement node event listeners here
|
||||
},
|
||||
},
|
||||
|
||||
// this scrolls away from the elements for some reason with carbon when set to top
|
||||
// https://github.com/cypress-io/cypress/issues/2353
|
||||
// https://docs.cypress.io/guides/core-concepts/interacting-with-elements#Scrolling
|
||||
scrollBehavior: "center",
|
||||
});
|
||||
|
|
|
@ -32,7 +32,7 @@ describe('process-groups', () => {
|
|||
|
||||
cy.contains('Delete').click();
|
||||
cy.contains('Are you sure');
|
||||
cy.contains('OK').click();
|
||||
cy.getBySel('modal-confirmation-dialog').find('.cds--btn--danger').click();
|
||||
cy.url().should('include', `process-groups`);
|
||||
cy.contains(groupId).should('not.exist');
|
||||
});
|
||||
|
|
|
@ -43,12 +43,19 @@ const updateBpmnPythonScriptWithMonaco = (
|
|||
cy.contains('Launch Editor').click();
|
||||
// sometimes, Loading... appears for more than 4 seconds. not sure why.
|
||||
cy.contains('Loading...').should('not.exist');
|
||||
|
||||
// the delay 30 is because, at some point, monaco started automatically
|
||||
// adding a second double quote when we type a double quote. when it does
|
||||
// that, there is a race condition where it sometimes gets in more text
|
||||
// before the second double quote appears because the robot is typing faster
|
||||
// than a human being could, so we artificially slow it down to make it more
|
||||
// human.
|
||||
cy.get('.monaco-editor textarea:first')
|
||||
.click()
|
||||
.focused() // change subject to currently focused element
|
||||
// .type('{ctrl}a') // had been doing it this way, but it turns out to be flaky relative to clear()
|
||||
.clear()
|
||||
.type(pythonScript);
|
||||
.type(pythonScript, { delay: 30 });
|
||||
|
||||
cy.contains('Close').click();
|
||||
// wait for a little bit for the xml to get set before saving
|
||||
|
@ -111,8 +118,10 @@ describe('process-instances', () => {
|
|||
});
|
||||
|
||||
it('can create a new instance and can modify with monaco text editor', () => {
|
||||
const originalPythonScript = 'person = "Kevin"';
|
||||
const newPythonScript = 'person = "Mike"';
|
||||
// leave off the ending double quote since manco adds it
|
||||
const originalPythonScript = 'person = "Kevin';
|
||||
const newPythonScript = 'person = "Mike';
|
||||
|
||||
const bpmnFile = 'process_model_one.bpmn';
|
||||
|
||||
// Change bpmn
|
||||
|
|
|
@ -99,7 +99,7 @@ describe('process-models', () => {
|
|||
cy.contains(/^Process Model File$/);
|
||||
// Some reason, cypress evals json strings so we have to escape it it with '{{}'
|
||||
cy.get('.view-line').type('{{} "test_key": "test_value" }');
|
||||
cy.contains('Save').click();
|
||||
cy.getBySel('file-save-button').click();
|
||||
cy.get('input[name=file_name]').type(jsonFileName);
|
||||
cy.contains('Save Changes').click();
|
||||
cy.contains(`Process Model File: ${jsonFileName}`);
|
||||
|
@ -168,12 +168,8 @@ describe('process-models', () => {
|
|||
});
|
||||
|
||||
it('can allow searching for model', () => {
|
||||
cy.get('[name=process-model-selection]').click();
|
||||
cy.get('[name=process-model-selection]').type('model-3');
|
||||
cy.get(
|
||||
`[aria-label="acceptance-tests-group-one/acceptance-tests-model-3"]`
|
||||
).click();
|
||||
|
||||
cy.contains('Process Instances').click();
|
||||
cy.getBySel('process-model-selection').click().type('model-3');
|
||||
cy.contains('acceptance-tests-group-one/acceptance-tests-model-3').click();
|
||||
cy.contains('List').click();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -21,6 +21,7 @@ describe('tasks', () => {
|
|||
cy.logout();
|
||||
});
|
||||
|
||||
// TODO: need to fix the next_task thing to make this pass
|
||||
it('can complete and navigate a form', () => {
|
||||
const groupDisplayName = 'Acceptance Tests Group One';
|
||||
const modelId = `acceptance-tests-model-2`;
|
||||
|
|
|
@ -31,11 +31,13 @@ Cypress.Commands.add('getBySel', (selector, ...args) => {
|
|||
});
|
||||
|
||||
Cypress.Commands.add('navigateToHome', () => {
|
||||
cy.getBySel('nav-home').click();
|
||||
cy.get('button[aria-label="Open menu"]').click();
|
||||
cy.getBySel('side-nav-items').contains('Home').click();
|
||||
// cy.getBySel('nav-home').click();
|
||||
});
|
||||
|
||||
Cypress.Commands.add('navigateToAdmin', () => {
|
||||
cy.getBySel('spiffworkflow-logo').click();
|
||||
cy.visit('/admin');
|
||||
});
|
||||
|
||||
Cypress.Commands.add('login', (selector, ...args) => {
|
||||
|
@ -101,18 +103,15 @@ Cypress.Commands.add(
|
|||
);
|
||||
|
||||
Cypress.Commands.add('basicPaginationTest', () => {
|
||||
cy.get('#pagination-page-dropdown')
|
||||
.type('typing_to_open_dropdown_box....FIXME')
|
||||
.find('.dropdown-item')
|
||||
.contains(/^2$/)
|
||||
.click();
|
||||
cy.getBySel('pagination-options').scrollIntoView();
|
||||
cy.get('.cds--select__item-count').find('.cds--select-input').select('2');
|
||||
|
||||
cy.contains(/^1-2 of \d+$/);
|
||||
cy.getBySel('pagination-previous-button-inactive');
|
||||
cy.getBySel('pagination-next-button').click();
|
||||
cy.contains(/^3-4 of \d+$/);
|
||||
cy.getBySel('pagination-previous-button').click();
|
||||
cy.contains(/^1-2 of \d+$/);
|
||||
// NOTE: this is a em dash instead of en dash
|
||||
cy.contains(/\b1–2 of \d+/);
|
||||
cy.get('.cds--pagination__button--forward').click();
|
||||
cy.contains(/\b3–4 of \d+/);
|
||||
cy.get('.cds--pagination__button--backward').click();
|
||||
cy.contains(/\b1–2 of \d+/);
|
||||
});
|
||||
|
||||
Cypress.Commands.add('assertAtLeastOneItemInPaginatedResults', () => {
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
"@babel/core": "^7.18.10",
|
||||
"@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/styles": "^1.16.0",
|
||||
"@ginkgo-bioworks/react-json-schema-form-builder": "^2.9.0",
|
||||
"@monaco-editor/react": "^4.4.5",
|
||||
"@rjsf/core": "^4.2.0",
|
||||
|
@ -2140,6 +2143,138 @@
|
|||
"resolved": "https://registry.npmjs.org/@camunda/zeebe-element-templates-json-schema/-/zeebe-element-templates-json-schema-0.6.0.tgz",
|
||||
"integrity": "sha512-qawIFM52lp1hW2vWrHaX8ywguZsp2olE0DRTHUY+KWH5GwszZwGWECP3tji1KVih2TasQyf28kcQVh8TeQ6dAg=="
|
||||
},
|
||||
"node_modules/@carbon/colors": {
|
||||
"version": "11.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@carbon/colors/-/colors-11.7.0.tgz",
|
||||
"integrity": "sha512-2B57vtirYTpxGg7p9yIO+s4cwL5QB8ogGQB5Pz+zdaHoVxrLsGlxAg28CQgk7yxw7doqST79bRVYS6FaJq+qJw=="
|
||||
},
|
||||
"node_modules/@carbon/feature-flags": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@carbon/feature-flags/-/feature-flags-0.9.0.tgz",
|
||||
"integrity": "sha512-uNCRkxsNwLdJVNwQ5S5vrLAm4yawWzhFBwyP9EgXVmRzJH85Aim+miC+QNjRXntJDYhZYDuLABTeb3VD692ypA=="
|
||||
},
|
||||
"node_modules/@carbon/grid": {
|
||||
"version": "11.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@carbon/grid/-/grid-11.7.0.tgz",
|
||||
"integrity": "sha512-OCDXQNSPVOoBQN08Qn5wo2WpKRGRm/kEBo6ZTl2NoDCl21mcYJZ0IDbKPTukixJB1sUNDUlnrpwMoaznPj48dw==",
|
||||
"dependencies": {
|
||||
"@carbon/layout": "^11.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@carbon/icon-helpers": {
|
||||
"version": "10.34.0",
|
||||
"resolved": "https://registry.npmjs.org/@carbon/icon-helpers/-/icon-helpers-10.34.0.tgz",
|
||||
"integrity": "sha512-Ov9EBc1tR/DDrMI0pN1drj2jb27ISmYFBLdDji+aivVJkLPy8R/jikJOsOBgIq2kUjQJYNN199k2acHKjZdYIg=="
|
||||
},
|
||||
"node_modules/@carbon/icons-react": {
|
||||
"version": "11.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@carbon/icons-react/-/icons-react-11.10.0.tgz",
|
||||
"integrity": "sha512-807RWTfbvVzmsDg2DJ4FjwYNbJSgkrEd1Ui8I07YheJVb3sbYGGZMG7aCS0qXVlrQOhB2hggtxSW1w9NksUXNA==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@carbon/icon-helpers": "^10.34.0",
|
||||
"@carbon/telemetry": "0.1.0",
|
||||
"prop-types": "^15.7.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/@carbon/layout": {
|
||||
"version": "11.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@carbon/layout/-/layout-11.7.0.tgz",
|
||||
"integrity": "sha512-p4YQvW8U5Go0Tz1PZZgllGSPmoq8xBB5PHByuHiAjzwGclxPsBmY6Ea7tftINFW8VlcjDcampyT8VfZXhP2lFg=="
|
||||
},
|
||||
"node_modules/@carbon/motion": {
|
||||
"version": "11.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@carbon/motion/-/motion-11.5.0.tgz",
|
||||
"integrity": "sha512-5QEALh+xZzICdgVLanSpiDfBTErzVgEze/xUKs7ZdSbd6p1FaDKDGvCmj9RCsaz/CMVHIWo65MshIglSWX5Xvw=="
|
||||
},
|
||||
"node_modules/@carbon/react": {
|
||||
"version": "1.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@carbon/react/-/react-1.16.0.tgz",
|
||||
"integrity": "sha512-kVeL/iyVqN2tfcoE1xliIm4w2ex9L4m/b8KuGo7ZuqBmRzANQdfSYGfj11KU0TXT1CbOVFrqsT/aBxApsP5IDg==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.18.3",
|
||||
"@carbon/feature-flags": "^0.9.0",
|
||||
"@carbon/icons-react": "^11.10.0",
|
||||
"@carbon/layout": "^11.7.0",
|
||||
"@carbon/styles": "^1.16.0",
|
||||
"@carbon/telemetry": "0.1.0",
|
||||
"classnames": "2.3.2",
|
||||
"copy-to-clipboard": "^3.3.1",
|
||||
"downshift": "5.2.1",
|
||||
"flatpickr": "4.6.9",
|
||||
"invariant": "^2.2.3",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"lodash.findlast": "^4.5.0",
|
||||
"lodash.isequal": "^4.5.0",
|
||||
"lodash.omit": "^4.5.0",
|
||||
"lodash.throttle": "^4.1.1",
|
||||
"prop-types": "^15.7.2",
|
||||
"react-is": "^17.0.2",
|
||||
"use-resize-observer": "^6.0.0",
|
||||
"wicg-inert": "^3.1.1",
|
||||
"window-or-global": "^1.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.6 || ^17.0.1",
|
||||
"react-dom": "^16.8.6 || ^17.0.1",
|
||||
"sass": "^1.33.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@carbon/react/node_modules/react-is": {
|
||||
"version": "17.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
|
||||
},
|
||||
"node_modules/@carbon/styles": {
|
||||
"version": "1.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@carbon/styles/-/styles-1.16.0.tgz",
|
||||
"integrity": "sha512-LSjRw2Ws8rWI1a96KYUuX10jG+rpSn68dHlZhhDq+RJWsMGpjFhKUxPoTiJli2hHXyxey6rXV0hfr7oBJ0ud7w==",
|
||||
"dependencies": {
|
||||
"@carbon/colors": "^11.7.0",
|
||||
"@carbon/feature-flags": "^0.9.0",
|
||||
"@carbon/grid": "^11.7.0",
|
||||
"@carbon/layout": "^11.7.0",
|
||||
"@carbon/motion": "^11.5.0",
|
||||
"@carbon/themes": "^11.11.0",
|
||||
"@carbon/type": "^11.11.0",
|
||||
"@ibm/plex": "6.0.0-next.6"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"sass": "^1.33.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@carbon/telemetry": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@carbon/telemetry/-/telemetry-0.1.0.tgz",
|
||||
"integrity": "sha512-kNWt0bkgPwGW0i5h7HFuljbKRXPvIhsKbB+1tEURAYLXoJg9iJLF1eGvWN5iVoFCS2zje4GR3OGOsvvKVe7Hlg==",
|
||||
"bin": {
|
||||
"carbon-telemetry": "bin/carbon-telemetry.js"
|
||||
}
|
||||
},
|
||||
"node_modules/@carbon/themes": {
|
||||
"version": "11.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@carbon/themes/-/themes-11.11.0.tgz",
|
||||
"integrity": "sha512-EhLizr2oMqJXNubI2zWw09qcSPLZdWoBOQ6uNcjHzpXgoGNMwbVJE/qGMy/ivr+EOs6Fe0z5T0u97v+ZhSmRhg==",
|
||||
"dependencies": {
|
||||
"@carbon/colors": "^11.7.0",
|
||||
"@carbon/layout": "^11.7.0",
|
||||
"@carbon/type": "^11.11.0",
|
||||
"color": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@carbon/type": {
|
||||
"version": "11.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@carbon/type/-/type-11.11.0.tgz",
|
||||
"integrity": "sha512-eX6z8BibP1En1xBm2wUd01Nzk0Tm1jftR2QSD4JBn4xhnkGR824gpcbLTAIMGx9/Mr3R65Enbam3uFO0OOaH8g==",
|
||||
"dependencies": {
|
||||
"@carbon/grid": "^11.7.0",
|
||||
"@carbon/layout": "^11.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/autocomplete": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.3.0.tgz",
|
||||
|
@ -2899,6 +3034,14 @@
|
|||
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
|
||||
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA=="
|
||||
},
|
||||
"node_modules/@ibm/plex": {
|
||||
"version": "6.0.0-next.6",
|
||||
"resolved": "https://registry.npmjs.org/@ibm/plex/-/plex-6.0.0-next.6.tgz",
|
||||
"integrity": "sha512-B3uGruTn2rS5gweynLmfSe7yCawSRsJguJJQHVQiqf4rh2RNgJFu8YLE2Zd/JHV0ZXoVMOslcXP2k3hMkxKEyA==",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@istanbuljs/load-nyc-config": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
|
||||
|
@ -8009,9 +8152,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/classnames": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
|
||||
"integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz",
|
||||
"integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
|
||||
},
|
||||
"node_modules/clean-css": {
|
||||
"version": "5.3.1",
|
||||
|
@ -8207,6 +8350,18 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/color": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
|
||||
"integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1",
|
||||
"color-string": "^1.9.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
|
@ -8220,6 +8375,31 @@
|
|||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
|
||||
},
|
||||
"node_modules/color-string": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
|
||||
"integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
|
||||
"dependencies": {
|
||||
"color-name": "^1.0.0",
|
||||
"simple-swizzle": "^0.2.2"
|
||||
}
|
||||
},
|
||||
"node_modules/color/node_modules/color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dependencies": {
|
||||
"color-name": "~1.1.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/color/node_modules/color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"node_modules/colord": {
|
||||
"version": "2.9.3",
|
||||
"resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz",
|
||||
|
@ -8484,6 +8664,14 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/copy-to-clipboard": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.2.tgz",
|
||||
"integrity": "sha512-Vme1Z6RUDzrb6xAI7EZlVZ5uvOk2F//GaxKUxajDqm9LhOVM1inxNAD2vy+UZDYsd0uyA9s7b3/FVZPSxqrCfg==",
|
||||
"dependencies": {
|
||||
"toggle-selection": "^1.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/core_d": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/core_d/-/core_d-5.0.1.tgz",
|
||||
|
@ -9005,9 +9193,9 @@
|
|||
"integrity": "sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A=="
|
||||
},
|
||||
"node_modules/cypress": {
|
||||
"version": "10.8.0",
|
||||
"resolved": "https://registry.npmjs.org/cypress/-/cypress-10.8.0.tgz",
|
||||
"integrity": "sha512-QVse0dnLm018hgti2enKMVZR9qbIO488YGX06nH5j3Dg1isL38DwrBtyrax02CANU6y8F4EJUuyW6HJKw1jsFA==",
|
||||
"version": "10.11.0",
|
||||
"resolved": "https://registry.npmjs.org/cypress/-/cypress-10.11.0.tgz",
|
||||
"integrity": "sha512-lsaE7dprw5DoXM00skni6W5ElVVLGAdRUUdZjX2dYsGjbY/QnpzWZ95Zom1mkGg0hAaO/QVTZoFVS7Jgr/GUPA==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
|
@ -9872,6 +10060,25 @@
|
|||
"resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz",
|
||||
"integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA=="
|
||||
},
|
||||
"node_modules/downshift": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/downshift/-/downshift-5.2.1.tgz",
|
||||
"integrity": "sha512-uHX2OLbWthLR8QbR8NCI8OmjvvJxq8+PrA95KblFd9JyB1zVZh1HnszzsWMMCnMuH6IvsUtVfF5HY7XfijJ2dw==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.9.1",
|
||||
"compute-scroll-into-view": "^1.0.13",
|
||||
"prop-types": "^15.7.2",
|
||||
"react-is": "^16.13.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=0.14.9"
|
||||
}
|
||||
},
|
||||
"node_modules/downshift/node_modules/react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||
},
|
||||
"node_modules/duplexer": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
|
||||
|
@ -11596,6 +11803,11 @@
|
|||
"node": "^10.12.0 || >=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/flatpickr": {
|
||||
"version": "4.6.9",
|
||||
"resolved": "https://registry.npmjs.org/flatpickr/-/flatpickr-4.6.9.tgz",
|
||||
"integrity": "sha512-F0azNNi8foVWKSF+8X+ZJzz8r9sE1G4hl06RyceIaLvyltKvDl6vqk9Lm/6AUUCi5HWaIjiUbk7UpeE/fOXOpw=="
|
||||
},
|
||||
"node_modules/flatted": {
|
||||
"version": "3.2.7",
|
||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
|
||||
|
@ -12794,6 +13006,12 @@
|
|||
"url": "https://opencollective.com/immer"
|
||||
}
|
||||
},
|
||||
"node_modules/immutable": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz",
|
||||
"integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/import-fresh": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
||||
|
@ -18240,6 +18458,16 @@
|
|||
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
|
||||
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
|
||||
},
|
||||
"node_modules/lodash.findlast": {
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.findlast/-/lodash.findlast-4.6.0.tgz",
|
||||
"integrity": "sha512-+OGwb1FVKjhc2aIEQ9vKqNDW1a0/HaCLr0iCIK10jfVif3dBE0nhQD0jOZNZLh7zOlmFUTrk+vt85eXoH4vKuA=="
|
||||
},
|
||||
"node_modules/lodash.isequal": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
||||
"integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="
|
||||
},
|
||||
"node_modules/lodash.memoize": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
|
||||
|
@ -18250,6 +18478,11 @@
|
|||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
|
||||
},
|
||||
"node_modules/lodash.omit": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz",
|
||||
"integrity": "sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg=="
|
||||
},
|
||||
"node_modules/lodash.once": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
|
||||
|
@ -18261,6 +18494,11 @@
|
|||
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
|
||||
"integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA=="
|
||||
},
|
||||
"node_modules/lodash.throttle": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
|
||||
"integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ=="
|
||||
},
|
||||
"node_modules/lodash.truncate": {
|
||||
"version": "4.4.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
|
||||
|
@ -23919,6 +24157,11 @@
|
|||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
|
||||
},
|
||||
"node_modules/resize-observer-polyfill": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
|
||||
"integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
|
||||
},
|
||||
"node_modules/resolve": {
|
||||
"version": "1.22.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
|
||||
|
@ -24247,6 +24490,23 @@
|
|||
"resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-13.0.0.tgz",
|
||||
"integrity": "sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA=="
|
||||
},
|
||||
"node_modules/sass": {
|
||||
"version": "1.55.0",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.55.0.tgz",
|
||||
"integrity": "sha512-Pk+PMy7OGLs9WaxZGJMn7S96dvlyVBwwtToX895WmCpAOr5YiJYEUJfiJidMuKb613z2xNWcXCHEuOvjZbqC6A==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"chokidar": ">=3.0.0 <4.0.0",
|
||||
"immutable": "^4.0.0",
|
||||
"source-map-js": ">=0.6.2 <2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"sass": "sass.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/sax": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
|
||||
|
@ -24717,6 +24977,19 @@
|
|||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
|
||||
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
|
||||
},
|
||||
"node_modules/simple-swizzle": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
|
||||
"integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
|
||||
"dependencies": {
|
||||
"is-arrayish": "^0.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/simple-swizzle/node_modules/is-arrayish": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
|
||||
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
|
||||
},
|
||||
"node_modules/sisteransi": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
|
||||
|
@ -26202,6 +26475,11 @@
|
|||
"ret": "~0.1.10"
|
||||
}
|
||||
},
|
||||
"node_modules/toggle-selection": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
|
||||
"integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ=="
|
||||
},
|
||||
"node_modules/toidentifier": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||
|
@ -27747,6 +28025,18 @@
|
|||
"react": "^16.8.0 || ^17.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/use-resize-observer": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/use-resize-observer/-/use-resize-observer-6.1.0.tgz",
|
||||
"integrity": "sha512-SiPcWHiIQ1CnHmb6PxbYtygqiZXR0U9dNkkbpX9VYnlstUwF8+QqpUTrzh13pjPwcjMVGR+QIC+nvF5ujfFNng==",
|
||||
"dependencies": {
|
||||
"resize-observer-polyfill": "^1.5.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/util": {
|
||||
"version": "0.11.1",
|
||||
"resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",
|
||||
|
@ -28868,6 +29158,11 @@
|
|||
"integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/wicg-inert": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/wicg-inert/-/wicg-inert-3.1.2.tgz",
|
||||
"integrity": "sha512-Ba9tGNYxXwaqKEi9sJJvPMKuo063umUPsHN0JJsjrs2j8KDSzkWLMZGZ+MH1Jf1Fq4OWZ5HsESJID6nRza2ang=="
|
||||
},
|
||||
"node_modules/widest-line": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz",
|
||||
|
@ -28923,6 +29218,11 @@
|
|||
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/window-or-global": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/window-or-global/-/window-or-global-1.0.1.tgz",
|
||||
"integrity": "sha512-tE12J/NenOv4xdVobD+AD3fT06T4KNqnzRhkv5nBIu7K+pvOH2oLCEgYP+i+5mF2jtI6FEADheOdZkA8YWET9w=="
|
||||
},
|
||||
"node_modules/word-wrap": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
|
||||
|
@ -30836,6 +31136,124 @@
|
|||
"resolved": "https://registry.npmjs.org/@camunda/zeebe-element-templates-json-schema/-/zeebe-element-templates-json-schema-0.6.0.tgz",
|
||||
"integrity": "sha512-qawIFM52lp1hW2vWrHaX8ywguZsp2olE0DRTHUY+KWH5GwszZwGWECP3tji1KVih2TasQyf28kcQVh8TeQ6dAg=="
|
||||
},
|
||||
"@carbon/colors": {
|
||||
"version": "11.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@carbon/colors/-/colors-11.7.0.tgz",
|
||||
"integrity": "sha512-2B57vtirYTpxGg7p9yIO+s4cwL5QB8ogGQB5Pz+zdaHoVxrLsGlxAg28CQgk7yxw7doqST79bRVYS6FaJq+qJw=="
|
||||
},
|
||||
"@carbon/feature-flags": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@carbon/feature-flags/-/feature-flags-0.9.0.tgz",
|
||||
"integrity": "sha512-uNCRkxsNwLdJVNwQ5S5vrLAm4yawWzhFBwyP9EgXVmRzJH85Aim+miC+QNjRXntJDYhZYDuLABTeb3VD692ypA=="
|
||||
},
|
||||
"@carbon/grid": {
|
||||
"version": "11.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@carbon/grid/-/grid-11.7.0.tgz",
|
||||
"integrity": "sha512-OCDXQNSPVOoBQN08Qn5wo2WpKRGRm/kEBo6ZTl2NoDCl21mcYJZ0IDbKPTukixJB1sUNDUlnrpwMoaznPj48dw==",
|
||||
"requires": {
|
||||
"@carbon/layout": "^11.7.0"
|
||||
}
|
||||
},
|
||||
"@carbon/icon-helpers": {
|
||||
"version": "10.34.0",
|
||||
"resolved": "https://registry.npmjs.org/@carbon/icon-helpers/-/icon-helpers-10.34.0.tgz",
|
||||
"integrity": "sha512-Ov9EBc1tR/DDrMI0pN1drj2jb27ISmYFBLdDji+aivVJkLPy8R/jikJOsOBgIq2kUjQJYNN199k2acHKjZdYIg=="
|
||||
},
|
||||
"@carbon/icons-react": {
|
||||
"version": "11.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@carbon/icons-react/-/icons-react-11.10.0.tgz",
|
||||
"integrity": "sha512-807RWTfbvVzmsDg2DJ4FjwYNbJSgkrEd1Ui8I07YheJVb3sbYGGZMG7aCS0qXVlrQOhB2hggtxSW1w9NksUXNA==",
|
||||
"requires": {
|
||||
"@carbon/icon-helpers": "^10.34.0",
|
||||
"@carbon/telemetry": "0.1.0",
|
||||
"prop-types": "^15.7.2"
|
||||
}
|
||||
},
|
||||
"@carbon/layout": {
|
||||
"version": "11.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@carbon/layout/-/layout-11.7.0.tgz",
|
||||
"integrity": "sha512-p4YQvW8U5Go0Tz1PZZgllGSPmoq8xBB5PHByuHiAjzwGclxPsBmY6Ea7tftINFW8VlcjDcampyT8VfZXhP2lFg=="
|
||||
},
|
||||
"@carbon/motion": {
|
||||
"version": "11.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@carbon/motion/-/motion-11.5.0.tgz",
|
||||
"integrity": "sha512-5QEALh+xZzICdgVLanSpiDfBTErzVgEze/xUKs7ZdSbd6p1FaDKDGvCmj9RCsaz/CMVHIWo65MshIglSWX5Xvw=="
|
||||
},
|
||||
"@carbon/react": {
|
||||
"version": "1.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@carbon/react/-/react-1.16.0.tgz",
|
||||
"integrity": "sha512-kVeL/iyVqN2tfcoE1xliIm4w2ex9L4m/b8KuGo7ZuqBmRzANQdfSYGfj11KU0TXT1CbOVFrqsT/aBxApsP5IDg==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.18.3",
|
||||
"@carbon/feature-flags": "^0.9.0",
|
||||
"@carbon/icons-react": "^11.10.0",
|
||||
"@carbon/layout": "^11.7.0",
|
||||
"@carbon/styles": "^1.16.0",
|
||||
"@carbon/telemetry": "0.1.0",
|
||||
"classnames": "2.3.2",
|
||||
"copy-to-clipboard": "^3.3.1",
|
||||
"downshift": "5.2.1",
|
||||
"flatpickr": "4.6.9",
|
||||
"invariant": "^2.2.3",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"lodash.findlast": "^4.5.0",
|
||||
"lodash.isequal": "^4.5.0",
|
||||
"lodash.omit": "^4.5.0",
|
||||
"lodash.throttle": "^4.1.1",
|
||||
"prop-types": "^15.7.2",
|
||||
"react-is": "^17.0.2",
|
||||
"use-resize-observer": "^6.0.0",
|
||||
"wicg-inert": "^3.1.1",
|
||||
"window-or-global": "^1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"react-is": {
|
||||
"version": "17.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@carbon/styles": {
|
||||
"version": "1.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@carbon/styles/-/styles-1.16.0.tgz",
|
||||
"integrity": "sha512-LSjRw2Ws8rWI1a96KYUuX10jG+rpSn68dHlZhhDq+RJWsMGpjFhKUxPoTiJli2hHXyxey6rXV0hfr7oBJ0ud7w==",
|
||||
"requires": {
|
||||
"@carbon/colors": "^11.7.0",
|
||||
"@carbon/feature-flags": "^0.9.0",
|
||||
"@carbon/grid": "^11.7.0",
|
||||
"@carbon/layout": "^11.7.0",
|
||||
"@carbon/motion": "^11.5.0",
|
||||
"@carbon/themes": "^11.11.0",
|
||||
"@carbon/type": "^11.11.0",
|
||||
"@ibm/plex": "6.0.0-next.6"
|
||||
}
|
||||
},
|
||||
"@carbon/telemetry": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@carbon/telemetry/-/telemetry-0.1.0.tgz",
|
||||
"integrity": "sha512-kNWt0bkgPwGW0i5h7HFuljbKRXPvIhsKbB+1tEURAYLXoJg9iJLF1eGvWN5iVoFCS2zje4GR3OGOsvvKVe7Hlg=="
|
||||
},
|
||||
"@carbon/themes": {
|
||||
"version": "11.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@carbon/themes/-/themes-11.11.0.tgz",
|
||||
"integrity": "sha512-EhLizr2oMqJXNubI2zWw09qcSPLZdWoBOQ6uNcjHzpXgoGNMwbVJE/qGMy/ivr+EOs6Fe0z5T0u97v+ZhSmRhg==",
|
||||
"requires": {
|
||||
"@carbon/colors": "^11.7.0",
|
||||
"@carbon/layout": "^11.7.0",
|
||||
"@carbon/type": "^11.11.0",
|
||||
"color": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"@carbon/type": {
|
||||
"version": "11.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@carbon/type/-/type-11.11.0.tgz",
|
||||
"integrity": "sha512-eX6z8BibP1En1xBm2wUd01Nzk0Tm1jftR2QSD4JBn4xhnkGR824gpcbLTAIMGx9/Mr3R65Enbam3uFO0OOaH8g==",
|
||||
"requires": {
|
||||
"@carbon/grid": "^11.7.0",
|
||||
"@carbon/layout": "^11.7.0"
|
||||
}
|
||||
},
|
||||
"@codemirror/autocomplete": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.3.0.tgz",
|
||||
|
@ -31364,6 +31782,11 @@
|
|||
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
|
||||
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA=="
|
||||
},
|
||||
"@ibm/plex": {
|
||||
"version": "6.0.0-next.6",
|
||||
"resolved": "https://registry.npmjs.org/@ibm/plex/-/plex-6.0.0-next.6.tgz",
|
||||
"integrity": "sha512-B3uGruTn2rS5gweynLmfSe7yCawSRsJguJJQHVQiqf4rh2RNgJFu8YLE2Zd/JHV0ZXoVMOslcXP2k3hMkxKEyA=="
|
||||
},
|
||||
"@istanbuljs/load-nyc-config": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
|
||||
|
@ -35236,9 +35659,9 @@
|
|||
}
|
||||
},
|
||||
"classnames": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz",
|
||||
"integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA=="
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz",
|
||||
"integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
|
||||
},
|
||||
"clean-css": {
|
||||
"version": "5.3.1",
|
||||
|
@ -35376,6 +35799,30 @@
|
|||
"object-visit": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"color": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
|
||||
"integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
|
||||
"requires": {
|
||||
"color-convert": "^2.0.1",
|
||||
"color-string": "^1.9.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
|
@ -35389,6 +35836,15 @@
|
|||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
|
||||
},
|
||||
"color-string": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
|
||||
"integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
|
||||
"requires": {
|
||||
"color-name": "^1.0.0",
|
||||
"simple-swizzle": "^0.2.2"
|
||||
}
|
||||
},
|
||||
"colord": {
|
||||
"version": "2.9.3",
|
||||
"resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz",
|
||||
|
@ -35614,6 +36070,14 @@
|
|||
"resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
|
||||
"integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw=="
|
||||
},
|
||||
"copy-to-clipboard": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.2.tgz",
|
||||
"integrity": "sha512-Vme1Z6RUDzrb6xAI7EZlVZ5uvOk2F//GaxKUxajDqm9LhOVM1inxNAD2vy+UZDYsd0uyA9s7b3/FVZPSxqrCfg==",
|
||||
"requires": {
|
||||
"toggle-selection": "^1.0.6"
|
||||
}
|
||||
},
|
||||
"core_d": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/core_d/-/core_d-5.0.1.tgz",
|
||||
|
@ -36020,9 +36484,9 @@
|
|||
"integrity": "sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A=="
|
||||
},
|
||||
"cypress": {
|
||||
"version": "10.8.0",
|
||||
"resolved": "https://registry.npmjs.org/cypress/-/cypress-10.8.0.tgz",
|
||||
"integrity": "sha512-QVse0dnLm018hgti2enKMVZR9qbIO488YGX06nH5j3Dg1isL38DwrBtyrax02CANU6y8F4EJUuyW6HJKw1jsFA==",
|
||||
"version": "10.11.0",
|
||||
"resolved": "https://registry.npmjs.org/cypress/-/cypress-10.11.0.tgz",
|
||||
"integrity": "sha512-lsaE7dprw5DoXM00skni6W5ElVVLGAdRUUdZjX2dYsGjbY/QnpzWZ95Zom1mkGg0hAaO/QVTZoFVS7Jgr/GUPA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@cypress/request": "^2.88.10",
|
||||
|
@ -36715,6 +37179,24 @@
|
|||
"resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz",
|
||||
"integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA=="
|
||||
},
|
||||
"downshift": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/downshift/-/downshift-5.2.1.tgz",
|
||||
"integrity": "sha512-uHX2OLbWthLR8QbR8NCI8OmjvvJxq8+PrA95KblFd9JyB1zVZh1HnszzsWMMCnMuH6IvsUtVfF5HY7XfijJ2dw==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.9.1",
|
||||
"compute-scroll-into-view": "^1.0.13",
|
||||
"prop-types": "^15.7.2",
|
||||
"react-is": "^16.13.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"duplexer": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
|
||||
|
@ -38020,6 +38502,11 @@
|
|||
"rimraf": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"flatpickr": {
|
||||
"version": "4.6.9",
|
||||
"resolved": "https://registry.npmjs.org/flatpickr/-/flatpickr-4.6.9.tgz",
|
||||
"integrity": "sha512-F0azNNi8foVWKSF+8X+ZJzz8r9sE1G4hl06RyceIaLvyltKvDl6vqk9Lm/6AUUCi5HWaIjiUbk7UpeE/fOXOpw=="
|
||||
},
|
||||
"flatted": {
|
||||
"version": "3.2.7",
|
||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
|
||||
|
@ -38876,6 +39363,12 @@
|
|||
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.15.tgz",
|
||||
"integrity": "sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ=="
|
||||
},
|
||||
"immutable": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz",
|
||||
"integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==",
|
||||
"peer": true
|
||||
},
|
||||
"import-fresh": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
||||
|
@ -43000,6 +43493,16 @@
|
|||
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
|
||||
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
|
||||
},
|
||||
"lodash.findlast": {
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.findlast/-/lodash.findlast-4.6.0.tgz",
|
||||
"integrity": "sha512-+OGwb1FVKjhc2aIEQ9vKqNDW1a0/HaCLr0iCIK10jfVif3dBE0nhQD0jOZNZLh7zOlmFUTrk+vt85eXoH4vKuA=="
|
||||
},
|
||||
"lodash.isequal": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
||||
"integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="
|
||||
},
|
||||
"lodash.memoize": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
|
||||
|
@ -43010,6 +43513,11 @@
|
|||
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
|
||||
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
|
||||
},
|
||||
"lodash.omit": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz",
|
||||
"integrity": "sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg=="
|
||||
},
|
||||
"lodash.once": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
|
||||
|
@ -43021,6 +43529,11 @@
|
|||
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
|
||||
"integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA=="
|
||||
},
|
||||
"lodash.throttle": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
|
||||
"integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ=="
|
||||
},
|
||||
"lodash.truncate": {
|
||||
"version": "4.4.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
|
||||
|
@ -46934,6 +47447,11 @@
|
|||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
|
||||
},
|
||||
"resize-observer-polyfill": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
|
||||
"integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.22.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
|
||||
|
@ -47167,6 +47685,17 @@
|
|||
"resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-13.0.0.tgz",
|
||||
"integrity": "sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA=="
|
||||
},
|
||||
"sass": {
|
||||
"version": "1.55.0",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.55.0.tgz",
|
||||
"integrity": "sha512-Pk+PMy7OGLs9WaxZGJMn7S96dvlyVBwwtToX895WmCpAOr5YiJYEUJfiJidMuKb613z2xNWcXCHEuOvjZbqC6A==",
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"chokidar": ">=3.0.0 <4.0.0",
|
||||
"immutable": "^4.0.0",
|
||||
"source-map-js": ">=0.6.2 <2.0.0"
|
||||
}
|
||||
},
|
||||
"sax": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
|
||||
|
@ -47565,6 +48094,21 @@
|
|||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
|
||||
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
|
||||
},
|
||||
"simple-swizzle": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
|
||||
"integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
|
||||
"requires": {
|
||||
"is-arrayish": "^0.3.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"is-arrayish": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
|
||||
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"sisteransi": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
|
||||
|
@ -48736,6 +49280,11 @@
|
|||
"is-number": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"toggle-selection": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
|
||||
"integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ=="
|
||||
},
|
||||
"toidentifier": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||
|
@ -49905,6 +50454,14 @@
|
|||
"integrity": "sha512-u2qFKtxLsia/r8qG0ZKkbytbztzRb317XCkT7yP8wxL0tZ/CzK2G+WWie5vWvpyeP7+YoPIwbJoIHJ4Ba4k0oQ==",
|
||||
"requires": {}
|
||||
},
|
||||
"use-resize-observer": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/use-resize-observer/-/use-resize-observer-6.1.0.tgz",
|
||||
"integrity": "sha512-SiPcWHiIQ1CnHmb6PxbYtygqiZXR0U9dNkkbpX9VYnlstUwF8+QqpUTrzh13pjPwcjMVGR+QIC+nvF5ujfFNng==",
|
||||
"requires": {
|
||||
"resize-observer-polyfill": "^1.5.1"
|
||||
}
|
||||
},
|
||||
"util": {
|
||||
"version": "0.11.1",
|
||||
"resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",
|
||||
|
@ -50782,6 +51339,11 @@
|
|||
"integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==",
|
||||
"dev": true
|
||||
},
|
||||
"wicg-inert": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/wicg-inert/-/wicg-inert-3.1.2.tgz",
|
||||
"integrity": "sha512-Ba9tGNYxXwaqKEi9sJJvPMKuo063umUPsHN0JJsjrs2j8KDSzkWLMZGZ+MH1Jf1Fq4OWZ5HsESJID6nRza2ang=="
|
||||
},
|
||||
"widest-line": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz",
|
||||
|
@ -50815,6 +51377,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"window-or-global": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/window-or-global/-/window-or-global-1.0.1.tgz",
|
||||
"integrity": "sha512-tE12J/NenOv4xdVobD+AD3fT06T4KNqnzRhkv5nBIu7K+pvOH2oLCEgYP+i+5mF2jtI6FEADheOdZkA8YWET9w=="
|
||||
},
|
||||
"word-wrap": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
"@babel/core": "^7.18.10",
|
||||
"@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/styles": "^1.16.0",
|
||||
"@ginkgo-bioworks/react-json-schema-form-builder": "^2.9.0",
|
||||
"@monaco-editor/react": "^4.4.5",
|
||||
"@rjsf/core": "^4.2.0",
|
||||
|
@ -55,6 +58,10 @@
|
|||
"@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": {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { useMemo, useState } from 'react';
|
||||
import { Container } from 'react-bootstrap';
|
||||
// @ts-ignore
|
||||
import { Content } from '@carbon/react';
|
||||
|
||||
import { BrowserRouter, Routes, Route } from 'react-router-dom';
|
||||
import ErrorContext from './contexts/ErrorContext';
|
||||
|
@ -9,7 +10,6 @@ import HomePage from './routes/HomePage';
|
|||
import TaskShow from './routes/TaskShow';
|
||||
import ErrorBoundary from './components/ErrorBoundary';
|
||||
import AdminRoutes from './routes/AdminRoutes';
|
||||
import SubNavigation from './components/SubNavigation';
|
||||
import { ErrorForDisplay } from './interfaces';
|
||||
|
||||
export default function App() {
|
||||
|
@ -47,30 +47,27 @@ export default function App() {
|
|||
|
||||
return (
|
||||
<ErrorContext.Provider value={errorContextValueArray}>
|
||||
<NavigationBar />
|
||||
<Container>
|
||||
{errorTag}
|
||||
<ErrorBoundary>
|
||||
<BrowserRouter>
|
||||
<SubNavigation />
|
||||
<main style={{ padding: '1rem 0' }}>
|
||||
<Routes>
|
||||
<Route path="/" element={<HomePage />} />
|
||||
<Route path="/tasks" element={<HomePage />} />
|
||||
<Route path="/admin/*" element={<AdminRoutes />} />
|
||||
<Route
|
||||
path="/tasks/:process_instance_id/:task_id"
|
||||
element={<TaskShow />}
|
||||
/>
|
||||
<Route
|
||||
path="/tasks/:process_instance_id/:task_id"
|
||||
element={<TaskShow />}
|
||||
/>
|
||||
</Routes>
|
||||
</main>
|
||||
</BrowserRouter>
|
||||
</ErrorBoundary>
|
||||
</Container>
|
||||
<BrowserRouter>
|
||||
<NavigationBar />
|
||||
<Content>
|
||||
{errorTag}
|
||||
<ErrorBoundary>
|
||||
<Routes>
|
||||
<Route path="/" element={<HomePage />} />
|
||||
<Route path="/tasks" element={<HomePage />} />
|
||||
<Route path="/admin/*" element={<AdminRoutes />} />
|
||||
<Route
|
||||
path="/tasks/:process_instance_id/:task_id"
|
||||
element={<TaskShow />}
|
||||
/>
|
||||
<Route
|
||||
path="/tasks/:process_instance_id/:task_id"
|
||||
element={<TaskShow />}
|
||||
/>
|
||||
</Routes>
|
||||
</ErrorBoundary>
|
||||
</Content>
|
||||
</BrowserRouter>
|
||||
</ErrorContext.Provider>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { useState } from 'react';
|
||||
import { Button, Modal } from 'react-bootstrap';
|
||||
// @ts-ignore
|
||||
import { Button, Modal } from '@carbon/react';
|
||||
|
||||
type OwnProps = {
|
||||
description?: string;
|
||||
|
@ -25,13 +26,6 @@ export default function ButtonWithConfirmation({
|
|||
setShowConfirmationPrompt(false);
|
||||
};
|
||||
|
||||
const modalBodyElement = () => {
|
||||
if (description) {
|
||||
return <Modal.Body>{description}</Modal.Body>;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const handleConfirmation = () => {
|
||||
onConfirmation();
|
||||
setShowConfirmationPrompt(false);
|
||||
|
@ -40,28 +34,22 @@ export default function ButtonWithConfirmation({
|
|||
const confirmationDialog = () => {
|
||||
return (
|
||||
<Modal
|
||||
show={showConfirmationPrompt}
|
||||
onHide={handleConfirmationPromptCancel}
|
||||
>
|
||||
<Modal.Header closeButton>
|
||||
<Modal.Title>{title}</Modal.Title>
|
||||
</Modal.Header>
|
||||
{modalBodyElement()}
|
||||
<Modal.Footer>
|
||||
<Button variant="secondary" onClick={handleConfirmationPromptCancel}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button variant="primary" onClick={handleConfirmation}>
|
||||
{confirmButtonLabel}
|
||||
</Button>
|
||||
</Modal.Footer>
|
||||
</Modal>
|
||||
open={showConfirmationPrompt}
|
||||
danger
|
||||
data-qa="modal-confirmation-dialog"
|
||||
modalHeading={description}
|
||||
modalLabel={title}
|
||||
primaryButtonText={confirmButtonLabel}
|
||||
secondaryButtonText="Cancel"
|
||||
onSecondarySubmit={handleConfirmationPromptCancel}
|
||||
onRequestSubmit={handleConfirmation}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button onClick={handleShowConfirmationPrompt} variant="danger">
|
||||
<Button onClick={handleShowConfirmationPrompt} kind="danger">
|
||||
{buttonLabel}
|
||||
</Button>
|
||||
{confirmationDialog()}
|
||||
|
|
|
@ -1,12 +1,28 @@
|
|||
import { Button, Navbar, Nav, Container } from 'react-bootstrap';
|
||||
import {
|
||||
Header,
|
||||
HeaderContainer,
|
||||
HeaderMenuButton,
|
||||
SkipToContent,
|
||||
SideNav,
|
||||
SideNavItems,
|
||||
HeaderSideNavItems,
|
||||
HeaderName,
|
||||
HeaderNavigation,
|
||||
HeaderMenuItem,
|
||||
HeaderGlobalAction,
|
||||
HeaderGlobalBar,
|
||||
// @ts-ignore
|
||||
} from '@carbon/react';
|
||||
// @ts-ignore
|
||||
import { Logout, Login } from '@carbon/icons-react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
// @ts-expect-error TS(2307) FIXME: Cannot find module '../logo.svg' or its correspond... Remove this comment to see the full error message
|
||||
import logo from '../logo.svg';
|
||||
import UserService from '../services/UserService';
|
||||
|
||||
// for ref: https://react-bootstrap.github.io/components/navbar/
|
||||
export default function NavigationBar() {
|
||||
const navElements = null;
|
||||
|
||||
const handleLogout = () => {
|
||||
UserService.doLogout();
|
||||
};
|
||||
|
@ -15,56 +31,116 @@ export default function NavigationBar() {
|
|||
UserService.doLogin();
|
||||
};
|
||||
|
||||
const loginLink = () => {
|
||||
if (!UserService.isLoggedIn()) {
|
||||
return (
|
||||
<Navbar.Collapse className="justify-content-end">
|
||||
<Navbar.Text>
|
||||
<Button variant="link" onClick={handleLogin}>
|
||||
Login
|
||||
</Button>
|
||||
</Navbar.Text>
|
||||
</Navbar.Collapse>
|
||||
);
|
||||
const location = useLocation();
|
||||
const [activeKey, setActiveKey] = useState<string>('');
|
||||
|
||||
useEffect(() => {
|
||||
let newActiveKey = '/admin/process-groups';
|
||||
if (location.pathname.match(/^\/admin\/messages\b/)) {
|
||||
newActiveKey = '/admin/messages';
|
||||
} else if (location.pathname.match(/^\/admin\/process-instances\b/)) {
|
||||
newActiveKey = '/admin/process-instances';
|
||||
} else if (location.pathname.match(/^\/admin\/secrets\b/)) {
|
||||
newActiveKey = '/admin/secrets';
|
||||
} else if (location.pathname.match(/^\/admin\/authentications\b/)) {
|
||||
newActiveKey = '/admin/authentications';
|
||||
} else if (location.pathname === '/') {
|
||||
newActiveKey = '/';
|
||||
} else if (location.pathname.match(/^\/tasks\b/)) {
|
||||
newActiveKey = '/';
|
||||
}
|
||||
return null;
|
||||
setActiveKey(newActiveKey);
|
||||
}, [location]);
|
||||
|
||||
const isActivePage = (menuItemPath: string) => {
|
||||
return activeKey === menuItemPath;
|
||||
};
|
||||
|
||||
const logoutLink = () => {
|
||||
const loginAndLogoutAction = () => {
|
||||
if (UserService.isLoggedIn()) {
|
||||
return (
|
||||
<Navbar.Collapse className="justify-content-end">
|
||||
<Navbar.Text>
|
||||
Signed in as: <strong>{UserService.getUsername()}</strong>
|
||||
</Navbar.Text>
|
||||
<Navbar.Text>
|
||||
<Button
|
||||
variant="link"
|
||||
onClick={handleLogout}
|
||||
data-qa="logout-button"
|
||||
>
|
||||
Logout
|
||||
</Button>
|
||||
</Navbar.Text>
|
||||
</Navbar.Collapse>
|
||||
<>
|
||||
<HeaderGlobalAction>{UserService.getUsername()}</HeaderGlobalAction>
|
||||
<HeaderGlobalAction
|
||||
aria-label="Logout"
|
||||
onClick={handleLogout}
|
||||
data-qa="logout-button"
|
||||
>
|
||||
<Logout />
|
||||
</HeaderGlobalAction>
|
||||
</>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
return (
|
||||
<HeaderGlobalAction
|
||||
data-qa="login-button"
|
||||
aria-label="Login"
|
||||
onClick={handleLogin}
|
||||
>
|
||||
<Login />
|
||||
</HeaderGlobalAction>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Navbar bg="dark" expand="lg" variant="dark">
|
||||
<Container>
|
||||
<Navbar.Brand data-qa="spiffworkflow-logo" href="/admin">
|
||||
<img src={logo} className="app-logo" alt="logo" />
|
||||
</Navbar.Brand>
|
||||
<Navbar.Toggle aria-controls="basic-navbar-nav" />
|
||||
<Navbar.Collapse id="basic-navbar-nav">
|
||||
<Nav className="me-auto">{navElements}</Nav>
|
||||
</Navbar.Collapse>
|
||||
{loginLink()}
|
||||
{logoutLink()}
|
||||
</Container>
|
||||
</Navbar>
|
||||
);
|
||||
const headerMenuItems = () => {
|
||||
return (
|
||||
<>
|
||||
<HeaderMenuItem href="/" isCurrentPage={isActivePage('/')}>
|
||||
Home
|
||||
</HeaderMenuItem>
|
||||
<HeaderMenuItem
|
||||
href="/admin/process-groups"
|
||||
isCurrentPage={isActivePage('/admin/process-groups')}
|
||||
data-qa="header-nav-processes"
|
||||
>
|
||||
Processes
|
||||
</HeaderMenuItem>
|
||||
<HeaderMenuItem
|
||||
href="/admin/process-instances"
|
||||
isCurrentPage={isActivePage('/admin/process-instances')}
|
||||
>
|
||||
Process Instances
|
||||
</HeaderMenuItem>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
if (activeKey) {
|
||||
// TODO: apply theme g100 to the header
|
||||
return (
|
||||
<HeaderContainer
|
||||
render={({ isSideNavExpanded, onClickSideNavExpand }: any) => (
|
||||
<Header aria-label="IBM Platform Name">
|
||||
<SkipToContent />
|
||||
<HeaderMenuButton
|
||||
aria-label="Open menu"
|
||||
onClick={onClickSideNavExpand}
|
||||
isActive={isSideNavExpanded}
|
||||
/>
|
||||
<HeaderName href="/" prefix="" data-qa="spiffworkflow-logo">
|
||||
<img src={logo} className="app-logo" alt="logo" />
|
||||
</HeaderName>
|
||||
<HeaderNavigation
|
||||
data-qa="main-nav-header"
|
||||
aria-label="Spiffworkflow"
|
||||
>
|
||||
{headerMenuItems()}
|
||||
</HeaderNavigation>
|
||||
<SideNav
|
||||
data-qa="side-nav-items"
|
||||
aria-label="Side navigation"
|
||||
expanded={isSideNavExpanded}
|
||||
isPersistent={false}
|
||||
>
|
||||
<SideNavItems>
|
||||
<HeaderSideNavItems>{headerMenuItems()}</HeaderSideNavItems>
|
||||
</SideNavItems>
|
||||
</SideNav>
|
||||
<HeaderGlobalBar>{loginAndLogoutAction()}</HeaderGlobalBar>
|
||||
</Header>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import { Dropdown, Stack } from 'react-bootstrap';
|
||||
// @ts-ignore
|
||||
import { Pagination } from '@carbon/react';
|
||||
import { PaginationObject } from '../interfaces';
|
||||
|
||||
export const DEFAULT_PER_PAGE = 50;
|
||||
export const DEFAULT_PAGE = 1;
|
||||
|
@ -10,9 +11,7 @@ type OwnProps = {
|
|||
page: number;
|
||||
perPage: number;
|
||||
perPageOptions?: number[];
|
||||
pagination: {
|
||||
[key: string]: number;
|
||||
};
|
||||
pagination: PaginationObject | null;
|
||||
tableToDisplay: any;
|
||||
queryParamString?: string;
|
||||
path: string;
|
||||
|
@ -28,140 +27,32 @@ export default function PaginationForTable({
|
|||
path,
|
||||
}: OwnProps) {
|
||||
const PER_PAGE_OPTIONS = [2, 10, 50, 100];
|
||||
const navigate = useNavigate();
|
||||
|
||||
const buildPerPageDropdown = () => {
|
||||
const perPageDropdownRows = (perPageOptions || PER_PAGE_OPTIONS).map(
|
||||
(perPageOption) => {
|
||||
if (perPageOption === perPage) {
|
||||
return (
|
||||
<Dropdown.Item
|
||||
key={perPageOption}
|
||||
href={`${path}?page=1&per_page=${perPageOption}`}
|
||||
active
|
||||
>
|
||||
{perPageOption}
|
||||
</Dropdown.Item>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Dropdown.Item
|
||||
key={perPageOption}
|
||||
href={`${path}?page=1&per_page=${perPageOption}`}
|
||||
>
|
||||
{perPageOption}
|
||||
</Dropdown.Item>
|
||||
);
|
||||
}
|
||||
);
|
||||
return (
|
||||
<Stack direction="horizontal" gap={3}>
|
||||
<Dropdown className="ms-auto" id="pagination-page-dropdown">
|
||||
<Dropdown.Toggle
|
||||
id="process-instances-per-page"
|
||||
variant="light border"
|
||||
>
|
||||
Number to show: {perPage}
|
||||
</Dropdown.Toggle>
|
||||
|
||||
<Dropdown.Menu variant="light">{perPageDropdownRows}</Dropdown.Menu>
|
||||
</Dropdown>
|
||||
</Stack>
|
||||
);
|
||||
const updateRows = (args: any) => {
|
||||
const newPage = args.page;
|
||||
const { pageSize } = args;
|
||||
navigate(`${path}?page=${newPage}&per_page=${pageSize}${queryParamString}`);
|
||||
};
|
||||
|
||||
const buildPaginationNav = () => {
|
||||
let previousPageTag = null;
|
||||
if (page === 1) {
|
||||
previousPageTag = (
|
||||
<li
|
||||
data-qa="pagination-previous-button-inactive"
|
||||
className="page-item disabled"
|
||||
key="previous"
|
||||
>
|
||||
<span style={{ fontSize: '1.5em' }} className="page-link">
|
||||
«
|
||||
</span>
|
||||
</li>
|
||||
);
|
||||
} else {
|
||||
previousPageTag = (
|
||||
<li className="page-item" key="previous">
|
||||
<Link
|
||||
data-qa="pagination-previous-button"
|
||||
className="page-link"
|
||||
style={{ fontSize: '1.5em' }}
|
||||
to={`${path}?page=${
|
||||
page - 1
|
||||
}&per_page=${perPage}${queryParamString}`}
|
||||
>
|
||||
«
|
||||
</Link>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
let nextPageTag = null;
|
||||
if (page >= pagination.pages) {
|
||||
nextPageTag = (
|
||||
<li
|
||||
data-qa="pagination-next-button-inactive"
|
||||
className="page-item disabled"
|
||||
key="next"
|
||||
>
|
||||
<span style={{ fontSize: '1.5em' }} className="page-link">
|
||||
»
|
||||
</span>
|
||||
</li>
|
||||
);
|
||||
} else {
|
||||
nextPageTag = (
|
||||
<li className="page-item" key="next">
|
||||
<Link
|
||||
data-qa="pagination-next-button"
|
||||
className="page-link"
|
||||
style={{ fontSize: '1.5em' }}
|
||||
to={`${path}?page=${
|
||||
page + 1
|
||||
}&per_page=${perPage}${queryParamString}`}
|
||||
>
|
||||
»
|
||||
</Link>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
let startingNumber = (page - 1) * perPage + 1;
|
||||
let endingNumber = page * perPage;
|
||||
if (endingNumber > pagination.total) {
|
||||
endingNumber = pagination.total;
|
||||
}
|
||||
if (startingNumber > pagination.total) {
|
||||
startingNumber = pagination.total;
|
||||
}
|
||||
|
||||
if (pagination) {
|
||||
return (
|
||||
<Stack direction="horizontal" gap={3}>
|
||||
<p className="ms-auto">
|
||||
{startingNumber}-{endingNumber} of{' '}
|
||||
<span data-qa="total-paginated-items">{pagination.total}</span>
|
||||
</p>
|
||||
<nav aria-label="Page navigation">
|
||||
<div>
|
||||
<ul className="pagination">
|
||||
{previousPageTag}
|
||||
{nextPageTag}
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
</Stack>
|
||||
<>
|
||||
{tableToDisplay}
|
||||
<Pagination
|
||||
data-qa="pagination-options"
|
||||
backwardText="Previous page"
|
||||
forwardText="Next page"
|
||||
itemsPerPageText="Items per page:"
|
||||
page={page}
|
||||
pageNumberText="Page Number"
|
||||
pageSize={perPage}
|
||||
pageSizes={perPageOptions || PER_PAGE_OPTIONS}
|
||||
totalItems={pagination.total}
|
||||
onChange={updateRows}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<main>
|
||||
{buildPaginationNav()}
|
||||
{tableToDisplay}
|
||||
{buildPerPageDropdown()}
|
||||
</main>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,181 @@
|
|||
import { useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
// @ts-ignore
|
||||
import { Button, ButtonSet, Form, Stack, TextInput } from '@carbon/react';
|
||||
import { slugifyString } from '../helpers';
|
||||
import HttpService from '../services/HttpService';
|
||||
import { ProcessGroup } from '../interfaces';
|
||||
import ButtonWithConfirmation from './ButtonWithConfirmation';
|
||||
|
||||
type OwnProps = {
|
||||
mode: string;
|
||||
processGroup: ProcessGroup;
|
||||
setProcessGroup: (..._args: any[]) => any;
|
||||
};
|
||||
|
||||
export default function ProcessGroupForm({
|
||||
mode,
|
||||
processGroup,
|
||||
setProcessGroup,
|
||||
}: OwnProps) {
|
||||
const [identifierInvalid, setIdentifierInvalid] = useState<boolean>(false);
|
||||
const [idHasBeenUpdatedByUser, setIdHasBeenUpdatedByUser] =
|
||||
useState<boolean>(false);
|
||||
const [displayNameInvalid, setDisplayNameInvalid] = useState<boolean>(false);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const navigateToProcessGroup = (_result: any) => {
|
||||
if (processGroup) {
|
||||
navigate(`/admin/process-groups/${processGroup.id}`);
|
||||
}
|
||||
};
|
||||
|
||||
const navigateToProcessGroups = (_result: any) => {
|
||||
navigate(`/admin/process-groups`);
|
||||
};
|
||||
|
||||
const hasValidIdentifier = (identifierToCheck: string) => {
|
||||
return identifierToCheck.match(/^[a-z0-9][0-9a-z-]+[a-z0-9]$/);
|
||||
};
|
||||
|
||||
const deleteProcessGroup = () => {
|
||||
HttpService.makeCallToBackend({
|
||||
path: `/process-groups/${processGroup.id}`,
|
||||
successCallback: navigateToProcessGroups,
|
||||
httpMethod: 'DELETE',
|
||||
});
|
||||
};
|
||||
|
||||
const handleFormSubmission = (event: any) => {
|
||||
event.preventDefault();
|
||||
let hasErrors = false;
|
||||
if (!hasValidIdentifier(processGroup.id)) {
|
||||
setIdentifierInvalid(true);
|
||||
hasErrors = true;
|
||||
}
|
||||
if (processGroup.display_name === '') {
|
||||
setDisplayNameInvalid(true);
|
||||
hasErrors = true;
|
||||
}
|
||||
if (hasErrors) {
|
||||
return;
|
||||
}
|
||||
let path = '/process-groups';
|
||||
if (mode === 'edit') {
|
||||
path = `/process-groups/${processGroup.id}`;
|
||||
}
|
||||
let httpMethod = 'POST';
|
||||
if (mode === 'edit') {
|
||||
httpMethod = 'PUT';
|
||||
}
|
||||
const postBody = {
|
||||
display_name: processGroup.display_name,
|
||||
description: processGroup.description,
|
||||
};
|
||||
if (mode === 'new') {
|
||||
Object.assign(postBody, { id: processGroup.id });
|
||||
}
|
||||
|
||||
HttpService.makeCallToBackend({
|
||||
path,
|
||||
successCallback: navigateToProcessGroup,
|
||||
httpMethod,
|
||||
postBody,
|
||||
});
|
||||
};
|
||||
|
||||
const updateProcessGroup = (newValues: any) => {
|
||||
const processGroupToCopy = {
|
||||
...processGroup,
|
||||
};
|
||||
Object.assign(processGroupToCopy, newValues);
|
||||
setProcessGroup(processGroupToCopy);
|
||||
};
|
||||
|
||||
const onDisplayNameChanged = (newDisplayName: any) => {
|
||||
setDisplayNameInvalid(false);
|
||||
const updateDict = { display_name: newDisplayName };
|
||||
if (!idHasBeenUpdatedByUser) {
|
||||
Object.assign(updateDict, { id: slugifyString(newDisplayName) });
|
||||
}
|
||||
updateProcessGroup(updateDict);
|
||||
};
|
||||
|
||||
const formElements = () => {
|
||||
const textInputs = [
|
||||
<TextInput
|
||||
id="process-group-display-name"
|
||||
name="display_name"
|
||||
invalidText="Display Name is required."
|
||||
invalid={displayNameInvalid}
|
||||
labelText="Display Name*"
|
||||
value={processGroup.display_name}
|
||||
onChange={(event: any) => onDisplayNameChanged(event.target.value)}
|
||||
onBlur={(event: any) => console.log('event', event)}
|
||||
/>,
|
||||
];
|
||||
|
||||
if (mode === 'new') {
|
||||
textInputs.push(
|
||||
<TextInput
|
||||
id="process-group-identifier"
|
||||
name="id"
|
||||
invalidText="Identifier is required and must be all lowercase characters and hyphens."
|
||||
invalid={identifierInvalid}
|
||||
labelText="Identifier*"
|
||||
value={processGroup.id}
|
||||
onChange={(event: any) => {
|
||||
updateProcessGroup({ id: event.target.value });
|
||||
// was invalid, and now valid
|
||||
if (identifierInvalid && hasValidIdentifier(event.target.value)) {
|
||||
setIdentifierInvalid(false);
|
||||
}
|
||||
setIdHasBeenUpdatedByUser(true);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
textInputs.push(
|
||||
<TextInput
|
||||
id="process-group-description"
|
||||
name="description"
|
||||
labelText="Description"
|
||||
value={processGroup.description}
|
||||
onChange={(event: any) =>
|
||||
updateProcessGroup({ description: event.target.value })
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
return textInputs;
|
||||
};
|
||||
|
||||
const formButtons = () => {
|
||||
const buttons = [
|
||||
<Button kind="secondary" type="submit">
|
||||
Submit
|
||||
</Button>,
|
||||
];
|
||||
if (mode === 'edit') {
|
||||
buttons.push(
|
||||
<ButtonWithConfirmation
|
||||
description={`Delete Process Group ${processGroup.id}?`}
|
||||
onConfirmation={deleteProcessGroup}
|
||||
buttonLabel="Delete"
|
||||
confirmButtonLabel="Delete"
|
||||
/>
|
||||
);
|
||||
}
|
||||
return <ButtonSet>{buttons}</ButtonSet>;
|
||||
};
|
||||
|
||||
return (
|
||||
<Form onSubmit={handleFormSubmission}>
|
||||
<Stack gap={5}>
|
||||
{formElements()}
|
||||
{formButtons()}
|
||||
</Stack>
|
||||
</Form>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
import {
|
||||
ComboBox,
|
||||
// @ts-ignore
|
||||
} from '@carbon/react';
|
||||
import { truncateString } from '../helpers';
|
||||
import { ProcessModel } from '../interfaces';
|
||||
|
||||
type OwnProps = {
|
||||
onChange: (..._args: any[]) => any;
|
||||
processModels: ProcessModel[];
|
||||
selectedItem?: ProcessModel | null;
|
||||
titleText?: string;
|
||||
};
|
||||
|
||||
export default function ProcessModelSearch({
|
||||
processModels,
|
||||
selectedItem,
|
||||
onChange,
|
||||
titleText = 'Process model',
|
||||
}: OwnProps) {
|
||||
const shouldFilterProcessModel = (options: any) => {
|
||||
const processModel: ProcessModel = options.item;
|
||||
const { inputValue } = options;
|
||||
return `${processModel.process_group_id}/${processModel.id} (${processModel.display_name})`.includes(
|
||||
inputValue
|
||||
);
|
||||
};
|
||||
return (
|
||||
<ComboBox
|
||||
onChange={onChange}
|
||||
id="process-model-select"
|
||||
data-qa="process-model-selection"
|
||||
items={processModels}
|
||||
itemToString={(processModel: ProcessModel) => {
|
||||
if (processModel) {
|
||||
return `${processModel.process_group_id}/${
|
||||
processModel.id
|
||||
} (${truncateString(processModel.display_name, 20)})`;
|
||||
}
|
||||
return null;
|
||||
}}
|
||||
shouldFilterItem={shouldFilterProcessModel}
|
||||
placeholder="Choose a process model"
|
||||
titleText={titleText}
|
||||
selectedItem={selectedItem}
|
||||
/>
|
||||
);
|
||||
}
|
|
@ -18,7 +18,8 @@ import {
|
|||
} from 'dmn-js-properties-panel';
|
||||
|
||||
import React, { useRef, useEffect, useState } from 'react';
|
||||
import Button from 'react-bootstrap/Button';
|
||||
// @ts-ignore
|
||||
import { Button } from '@carbon/react';
|
||||
|
||||
import 'bpmn-js/dist/assets/diagram-js.css';
|
||||
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css';
|
||||
|
|
|
@ -16,4 +16,6 @@ export const PROCESS_STATUSES = [
|
|||
'suspended',
|
||||
];
|
||||
|
||||
export const DATE_FORMAT = 'yyyy-MM-dd HH:mm:ss';
|
||||
// with time: yyyy-MM-dd HH:mm:ss
|
||||
export const DATE_FORMAT = 'yyyy-MM-dd';
|
||||
export const DATE_FORMAT_CARBON = 'Y-m-d';
|
||||
|
|
|
@ -20,7 +20,10 @@ export const capitalizeFirstLetter = (string: any) => {
|
|||
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||
};
|
||||
|
||||
export const convertDateToSeconds = (date: any, onChangeFunction: any) => {
|
||||
export const convertDateToSeconds = (
|
||||
date: any,
|
||||
onChangeFunction: any = null
|
||||
) => {
|
||||
let dateInSeconds = date;
|
||||
if (date !== null) {
|
||||
let dateInMilliseconds = date;
|
||||
|
@ -39,14 +42,26 @@ export const convertDateToSeconds = (date: any, onChangeFunction: any) => {
|
|||
return null;
|
||||
};
|
||||
|
||||
export const convertSecondsToFormattedDate = (seconds: number) => {
|
||||
if (seconds) {
|
||||
const startDate = new Date(seconds * 1000);
|
||||
return format(startDate, DATE_FORMAT);
|
||||
export const convertStringToDate = (dateString: string) => {
|
||||
if (dateString) {
|
||||
return new Date(dateString);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
export const convertSecondsToFormattedDate = (seconds: number) => {
|
||||
if (seconds) {
|
||||
const dateObject = new Date(seconds * 1000);
|
||||
return format(dateObject, DATE_FORMAT);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
export const convertDateStringToSeconds = (dateString: string) => {
|
||||
const dateObject = convertStringToDate(dateString);
|
||||
return convertDateToSeconds(dateObject);
|
||||
};
|
||||
|
||||
export const objectIsEmpty = (obj: object) => {
|
||||
return Object.keys(obj).length === 0;
|
||||
};
|
||||
|
@ -90,3 +105,11 @@ export const getProcessModelFullIdentifierFromSearchParams = (
|
|||
}
|
||||
return processModelFullIdentifier;
|
||||
};
|
||||
|
||||
// https://stackoverflow.com/a/71352046/6090676
|
||||
export const truncateString = (text: string, len: number) => {
|
||||
if (text.length > len && text.length > 0) {
|
||||
return `${text.split(' ').slice(0, len).join(' ')} ...`;
|
||||
}
|
||||
return text;
|
||||
};
|
||||
|
|
|
@ -20,12 +20,15 @@ span.bjs-crumb {
|
|||
}
|
||||
|
||||
.app-logo {
|
||||
height: 35%;
|
||||
width: 35%;
|
||||
height: 85%;
|
||||
width: 85%;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.spiffworkflow-header-container {
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
.active-task-highlight:not(.djs-connection) .djs-visual > :nth-child(1) {
|
||||
fill: yellow !important;
|
||||
|
@ -44,6 +47,17 @@ span.bjs-crumb {
|
|||
margin:auto;
|
||||
}
|
||||
|
||||
.cds--btn.button-white-background {
|
||||
color: #393939;
|
||||
background: #FFFFFF;
|
||||
background-blend-mode: multiply;
|
||||
border: 1px solid #393939;
|
||||
}
|
||||
|
||||
.with-bottom-margin {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.diagram-viewer-canvas {
|
||||
border:1px solid #000000;
|
||||
height:70vh;
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
// @use '@carbon/react/scss/themes';
|
||||
// @use '@carbon/react/scss/theme' with ($theme: themes.$g100);
|
||||
@use '@carbon/react';
|
||||
@use '@carbon/styles';
|
||||
// @include grid.flex-grid();
|
|
@ -4,6 +4,7 @@ import App from './App';
|
|||
|
||||
import 'bootstrap/dist/css/bootstrap.css';
|
||||
import './index.css';
|
||||
import './index.scss';
|
||||
|
||||
import reportWebVitals from './reportWebVitals';
|
||||
import UserService from './services/UserService';
|
||||
|
|
|
@ -14,6 +14,7 @@ export interface RecentProcessModel {
|
|||
export interface ProcessGroup {
|
||||
id: string;
|
||||
display_name: string;
|
||||
description?: string | null;
|
||||
}
|
||||
|
||||
export interface ProcessModel {
|
||||
|
@ -41,3 +42,13 @@ export interface AuthenticationItem {
|
|||
id: string;
|
||||
parameters: AuthenticationParam[];
|
||||
}
|
||||
|
||||
export interface PaginationObject {
|
||||
count: number;
|
||||
total: number;
|
||||
pages: number;
|
||||
}
|
||||
|
||||
export interface CarbonComboBoxSelection {
|
||||
selectedItem: ProcessModel;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { useContext, useEffect, useState } from 'react';
|
||||
import { Table } from 'react-bootstrap';
|
||||
// @ts-ignore
|
||||
import { Table } from '@carbon/react';
|
||||
import ErrorContext from '../contexts/ErrorContext';
|
||||
import { AuthenticationItem } from '../interfaces';
|
||||
import HttpService from '../services/HttpService';
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
import { Button, Table } from 'react-bootstrap';
|
||||
// @ts-ignore
|
||||
import { Button, Table } from '@carbon/react';
|
||||
import { Link, useSearchParams } from 'react-router-dom';
|
||||
import PaginationForTable from '../components/PaginationForTable';
|
||||
import { getPageInfoFromSearchParams } from '../helpers';
|
||||
import HttpService from '../services/HttpService';
|
||||
import { RecentProcessModel } from '../interfaces';
|
||||
import { PaginationObject, RecentProcessModel } from '../interfaces';
|
||||
|
||||
const PER_PAGE_FOR_TASKS_ON_HOME_PAGE = 5;
|
||||
|
||||
export default function HomePage() {
|
||||
const [searchParams] = useSearchParams();
|
||||
const [tasks, setTasks] = useState([]);
|
||||
const [pagination, setPagination] = useState(null);
|
||||
const [pagination, setPagination] = useState<PaginationObject | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const { page, perPage } = getPageInfoFromSearchParams(
|
||||
|
@ -53,7 +54,7 @@ export default function HomePage() {
|
|||
data-qa="process-instance-show-link"
|
||||
to={`/admin/process-models/${rowToUse.process_group_identifier}/${rowToUse.process_model_identifier}/process-instances/${rowToUse.process_instance_id}`}
|
||||
>
|
||||
View
|
||||
View {rowToUse.process_instance_id}
|
||||
</Link>
|
||||
</td>
|
||||
<td
|
||||
|
@ -125,10 +126,10 @@ export default function HomePage() {
|
|||
);
|
||||
};
|
||||
|
||||
const relevantProcessModelSection =
|
||||
recentProcessModels.length > 0 && buildRecentProcessModelSection();
|
||||
|
||||
if (pagination) {
|
||||
const tasksWaitingForMeComponent = () => {
|
||||
if (pagination && pagination.total < 1) {
|
||||
return null;
|
||||
}
|
||||
const { page, perPage } = getPageInfoFromSearchParams(
|
||||
searchParams,
|
||||
PER_PAGE_FOR_TASKS_ON_HOME_PAGE
|
||||
|
@ -144,6 +145,17 @@ export default function HomePage() {
|
|||
tableToDisplay={buildTable()}
|
||||
path="/tasks"
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const relevantProcessModelSection =
|
||||
recentProcessModels.length > 0 && buildRecentProcessModelSection();
|
||||
|
||||
if (pagination) {
|
||||
return (
|
||||
<>
|
||||
{tasksWaitingForMeComponent()}
|
||||
{relevantProcessModelSection}
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
import { Table } from 'react-bootstrap';
|
||||
// @ts-ignore
|
||||
import { Table } from '@carbon/react';
|
||||
import { Link, useParams, useSearchParams } from 'react-router-dom';
|
||||
import PaginationForTable from '../components/PaginationForTable';
|
||||
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
||||
|
|
|
@ -1,20 +1,18 @@
|
|||
import { useState, useEffect } from 'react';
|
||||
import { useParams, useNavigate } from 'react-router-dom';
|
||||
import { Button, Stack } from 'react-bootstrap';
|
||||
import { useParams } from 'react-router-dom';
|
||||
// @ts-ignore
|
||||
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
||||
import HttpService from '../services/HttpService';
|
||||
import ButtonWithConfirmation from '../components/ButtonWithConfirmation';
|
||||
import ProcessGroupForm from '../components/ProcessGroupForm';
|
||||
import { ProcessGroup } from '../interfaces';
|
||||
|
||||
export default function ProcessGroupEdit() {
|
||||
const [displayName, setDisplayName] = useState('');
|
||||
const params = useParams();
|
||||
const navigate = useNavigate();
|
||||
const [processGroup, setProcessGroup] = useState(null);
|
||||
const [processGroup, setProcessGroup] = useState<ProcessGroup | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const setProcessGroupsFromResult = (result: any) => {
|
||||
setProcessGroup(result);
|
||||
setDisplayName(result.display_name);
|
||||
};
|
||||
|
||||
HttpService.makeCallToBackend({
|
||||
|
@ -23,69 +21,16 @@ export default function ProcessGroupEdit() {
|
|||
});
|
||||
}, [params]);
|
||||
|
||||
const navigateToProcessGroup = (_result: any) => {
|
||||
navigate(`/admin/process-groups/${(processGroup as any).id}`);
|
||||
};
|
||||
|
||||
const navigateToProcessGroups = (_result: any) => {
|
||||
navigate(`/admin/process-groups`);
|
||||
};
|
||||
|
||||
const updateProcessGroup = (event: any) => {
|
||||
event.preventDefault();
|
||||
HttpService.makeCallToBackend({
|
||||
path: `/process-groups/${(processGroup as any).id}`,
|
||||
successCallback: navigateToProcessGroup,
|
||||
httpMethod: 'PUT',
|
||||
postBody: {
|
||||
display_name: displayName,
|
||||
id: (processGroup as any).id,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const deleteProcessGroup = () => {
|
||||
HttpService.makeCallToBackend({
|
||||
path: `/process-groups/${(processGroup as any).id}`,
|
||||
successCallback: navigateToProcessGroups,
|
||||
httpMethod: 'DELETE',
|
||||
});
|
||||
};
|
||||
|
||||
const onDisplayNameChanged = (newDisplayName: any) => {
|
||||
setDisplayName(newDisplayName);
|
||||
};
|
||||
|
||||
if (processGroup) {
|
||||
return (
|
||||
<>
|
||||
<ProcessBreadcrumb processGroupId={(processGroup as any).id} />
|
||||
<h2>Edit Process Group: {(processGroup as any).id}</h2>
|
||||
<form onSubmit={updateProcessGroup}>
|
||||
<label>Display Name:</label>
|
||||
<input
|
||||
name="display_name"
|
||||
type="text"
|
||||
value={displayName}
|
||||
onChange={(e) => onDisplayNameChanged(e.target.value)}
|
||||
/>
|
||||
<br />
|
||||
<br />
|
||||
<Stack direction="horizontal" gap={3}>
|
||||
<Button type="submit">Submit</Button>
|
||||
<Button
|
||||
variant="secondary"
|
||||
href={`/admin/process-groups/${(processGroup as any).id}`}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<ButtonWithConfirmation
|
||||
description={`Delete Process Group ${(processGroup as any).id}?`}
|
||||
onConfirmation={deleteProcessGroup}
|
||||
buttonLabel="Delete"
|
||||
/>
|
||||
</Stack>
|
||||
</form>
|
||||
<ProcessGroupForm
|
||||
mode="edit"
|
||||
processGroup={processGroup}
|
||||
setProcessGroup={setProcessGroup}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,13 +1,21 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
import { Link, useNavigate, useSearchParams } from 'react-router-dom';
|
||||
import { Button, Form, InputGroup, Table } from 'react-bootstrap';
|
||||
import { Typeahead } from 'react-bootstrap-typeahead';
|
||||
import { Option } from 'react-bootstrap-typeahead/types/types';
|
||||
import {
|
||||
Button,
|
||||
Table,
|
||||
// ExpandableTile,
|
||||
// TileAboveTheFoldContent,
|
||||
// TileBelowTheFoldContent,
|
||||
// TextInput,
|
||||
// ClickableTile,
|
||||
// @ts-ignore
|
||||
} from '@carbon/react';
|
||||
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
||||
import PaginationForTable from '../components/PaginationForTable';
|
||||
import HttpService from '../services/HttpService';
|
||||
import { getPageInfoFromSearchParams } from '../helpers';
|
||||
import { ProcessModel } from '../interfaces';
|
||||
import { CarbonComboBoxSelection, ProcessGroup } from '../interfaces';
|
||||
import ProcessModelSearch from '../components/ProcessModelSearch';
|
||||
|
||||
// Example process group json
|
||||
// {'process_group_id': 'sure', 'display_name': 'Test Workflows', 'id': 'test_process_group'}
|
||||
|
@ -17,8 +25,9 @@ export default function ProcessGroupList() {
|
|||
|
||||
const [processGroups, setProcessGroups] = useState([]);
|
||||
const [pagination, setPagination] = useState(null);
|
||||
const [processModeleSelectionOptions, setProcessModelSelectionOptions] =
|
||||
useState([]);
|
||||
const [processModelAvailableItems, setProcessModelAvailableItems] = useState(
|
||||
[]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const setProcessGroupsFromResult = (result: any) => {
|
||||
|
@ -31,7 +40,7 @@ export default function ProcessGroupList() {
|
|||
Object.assign(item, { label });
|
||||
return item;
|
||||
});
|
||||
setProcessModelSelectionOptions(selectionArray);
|
||||
setProcessModelAvailableItems(selectionArray);
|
||||
};
|
||||
|
||||
const { page, perPage } = getPageInfoFromSearchParams(searchParams);
|
||||
|
@ -48,7 +57,7 @@ export default function ProcessGroupList() {
|
|||
}, [searchParams]);
|
||||
|
||||
const buildTable = () => {
|
||||
const rows = processGroups.map((row) => {
|
||||
const rows = processGroups.map((row: ProcessGroup) => {
|
||||
return (
|
||||
<tr key={(row as any).id}>
|
||||
<td>
|
||||
|
@ -72,6 +81,17 @@ export default function ProcessGroupList() {
|
|||
<tbody>{rows}</tbody>
|
||||
</Table>
|
||||
);
|
||||
// const rows = processGroups.map((row: ProcessGroup) => {
|
||||
// return (
|
||||
// <span>
|
||||
// <ClickableTile href={`/admin/process-groups/${row.id}`}>
|
||||
// {row.display_name}
|
||||
// </ClickableTile>
|
||||
// </span>
|
||||
// );
|
||||
// });
|
||||
//
|
||||
// return <div style={{ width: '400px' }}>{rows}</div>;
|
||||
};
|
||||
|
||||
const processGroupsDisplayArea = () => {
|
||||
|
@ -97,35 +117,18 @@ export default function ProcessGroupList() {
|
|||
};
|
||||
|
||||
const processModelSearchArea = () => {
|
||||
const processModelSearchOnChange = (selected: Option[]) => {
|
||||
const processModel = selected[0] as ProcessModel;
|
||||
const processModelSearchOnChange = (selection: CarbonComboBoxSelection) => {
|
||||
const processModel = selection.selectedItem;
|
||||
navigate(
|
||||
`/admin/process-models/${processModel.process_group_id}/${processModel.id}`
|
||||
);
|
||||
};
|
||||
return (
|
||||
<form onSubmit={function hey() {}}>
|
||||
<h3>Search</h3>
|
||||
<Form.Group>
|
||||
<InputGroup>
|
||||
<InputGroup.Text className="text-nowrap">
|
||||
Process Model:{' '}
|
||||
</InputGroup.Text>
|
||||
<Typeahead
|
||||
style={{ width: 500 }}
|
||||
id="process-model-selection"
|
||||
labelKey="label"
|
||||
onChange={processModelSearchOnChange}
|
||||
// for cypress tests since data-qa does not work
|
||||
inputProps={{
|
||||
name: 'process-model-selection',
|
||||
}}
|
||||
options={processModeleSelectionOptions}
|
||||
placeholder="Choose a process model..."
|
||||
/>
|
||||
</InputGroup>
|
||||
</Form.Group>
|
||||
</form>
|
||||
<ProcessModelSearch
|
||||
onChange={processModelSearchOnChange}
|
||||
processModels={processModelAvailableItems}
|
||||
titleText="Process model search"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -133,7 +136,9 @@ export default function ProcessGroupList() {
|
|||
return (
|
||||
<>
|
||||
<ProcessBreadcrumb hotCrumbs={[['Process Groups']]} />
|
||||
<Button href="/admin/process-groups/new">Add a process group</Button>
|
||||
<Button kind="secondary" href="/admin/process-groups/new">
|
||||
Add a process group
|
||||
</Button>
|
||||
<br />
|
||||
<br />
|
||||
{processModelSearchArea()}
|
||||
|
|
|
@ -1,71 +1,24 @@
|
|||
import { useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import Button from 'react-bootstrap/Button';
|
||||
import Form from 'react-bootstrap/Form';
|
||||
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
||||
import { slugifyString } from '../helpers';
|
||||
import HttpService from '../services/HttpService';
|
||||
import ProcessGroupForm from '../components/ProcessGroupForm';
|
||||
import { ProcessGroup } from '../interfaces';
|
||||
|
||||
export default function ProcessGroupNew() {
|
||||
const [identifier, setIdentifier] = useState('');
|
||||
const [idHasBeenUpdatedByUser, setIdHasBeenUpdatedByUser] = useState(false);
|
||||
const [displayName, setDisplayName] = useState('');
|
||||
const navigate = useNavigate();
|
||||
|
||||
const navigateToProcessGroup = (_result: any) => {
|
||||
navigate(`/admin/process-groups/${identifier}`);
|
||||
};
|
||||
|
||||
const addProcessGroup = (event: any) => {
|
||||
event.preventDefault();
|
||||
HttpService.makeCallToBackend({
|
||||
path: `/process-groups`,
|
||||
successCallback: navigateToProcessGroup,
|
||||
httpMethod: 'POST',
|
||||
postBody: {
|
||||
id: identifier,
|
||||
display_name: displayName,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const onDisplayNameChanged = (newDisplayName: any) => {
|
||||
setDisplayName(newDisplayName);
|
||||
if (!idHasBeenUpdatedByUser) {
|
||||
setIdentifier(slugifyString(newDisplayName));
|
||||
}
|
||||
};
|
||||
const [processGroup, setProcessGroup] = useState<ProcessGroup>({
|
||||
id: '',
|
||||
display_name: '',
|
||||
description: '',
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<ProcessBreadcrumb />
|
||||
<h2>Add Process Group</h2>
|
||||
<Form onSubmit={addProcessGroup}>
|
||||
<Form.Group className="mb-3" controlId="display_name">
|
||||
<Form.Label>Display Name:</Form.Label>
|
||||
<Form.Control
|
||||
type="text"
|
||||
name="display_name"
|
||||
value={displayName}
|
||||
onChange={(e) => onDisplayNameChanged(e.target.value)}
|
||||
/>
|
||||
</Form.Group>
|
||||
<Form.Group className="mb-3" controlId="identifier">
|
||||
<Form.Label>ID:</Form.Label>
|
||||
<Form.Control
|
||||
type="text"
|
||||
name="id"
|
||||
value={identifier}
|
||||
onChange={(e) => {
|
||||
setIdentifier(e.target.value);
|
||||
setIdHasBeenUpdatedByUser(true);
|
||||
}}
|
||||
/>
|
||||
</Form.Group>
|
||||
<Button variant="primary" type="submit">
|
||||
Submit
|
||||
</Button>
|
||||
</Form>
|
||||
<ProcessGroupForm
|
||||
mode="new"
|
||||
processGroup={processGroup}
|
||||
setProcessGroup={setProcessGroup}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
import { Link, useSearchParams, useParams } from 'react-router-dom';
|
||||
import { Button, Table, Stack } from 'react-bootstrap';
|
||||
// @ts-ignore
|
||||
import { Button, Table, Stack } from '@carbon/react';
|
||||
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
||||
import PaginationForTable from '../components/PaginationForTable';
|
||||
import HttpService from '../services/HttpService';
|
||||
|
@ -81,7 +82,7 @@ export default function ProcessGroupShow() {
|
|||
]}
|
||||
/>
|
||||
<ul>
|
||||
<Stack direction="horizontal" gap={3}>
|
||||
<Stack orientation="horizontal" gap={3}>
|
||||
<Button
|
||||
href={`/admin/process-models/${(processGroup as any).id}/new`}
|
||||
>
|
||||
|
|
|
@ -6,14 +6,27 @@ import {
|
|||
useSearchParams,
|
||||
} from 'react-router-dom';
|
||||
|
||||
import { Button, Table, Stack, Form, InputGroup } from 'react-bootstrap';
|
||||
// @ts-expect-error TS(7016) FIXME: Could not find a declaration file for module 'reac... Remove this comment to see the full error message
|
||||
import DatePicker from 'react-datepicker';
|
||||
import { Typeahead } from 'react-bootstrap-typeahead';
|
||||
import { Option } from 'react-bootstrap-typeahead/types/types';
|
||||
import { PROCESS_STATUSES, DATE_FORMAT } from '../config';
|
||||
// @ts-ignore
|
||||
import { Filter } from '@carbon/icons-react';
|
||||
import {
|
||||
convertDateToSeconds,
|
||||
Button,
|
||||
ButtonSet,
|
||||
DatePicker,
|
||||
DatePickerInput,
|
||||
Table,
|
||||
Grid,
|
||||
Column,
|
||||
MultiSelect,
|
||||
// TableHeader,
|
||||
// TableHead,
|
||||
// TableRow,
|
||||
// TableBody,
|
||||
// TableCell,
|
||||
// @ts-ignore
|
||||
} from '@carbon/react';
|
||||
import { PROCESS_STATUSES, DATE_FORMAT, DATE_FORMAT_CARBON } from '../config';
|
||||
import {
|
||||
convertDateStringToSeconds,
|
||||
convertSecondsToFormattedDate,
|
||||
getPageInfoFromSearchParams,
|
||||
getProcessModelFullIdentifierFromSearchParams,
|
||||
|
@ -27,6 +40,8 @@ import HttpService from '../services/HttpService';
|
|||
|
||||
import 'react-bootstrap-typeahead/css/Typeahead.css';
|
||||
import 'react-bootstrap-typeahead/css/Typeahead.bs5.css';
|
||||
import { PaginationObject, ProcessModel } from '../interfaces';
|
||||
import ProcessModelSearch from '../components/ProcessModelSearch';
|
||||
|
||||
export default function ProcessInstanceList() {
|
||||
const params = useParams();
|
||||
|
@ -34,36 +49,38 @@ export default function ProcessInstanceList() {
|
|||
const navigate = useNavigate();
|
||||
|
||||
const [processInstances, setProcessInstances] = useState([]);
|
||||
const [pagination, setPagination] = useState(null);
|
||||
const [pagination, setPagination] = useState<PaginationObject | null>(null);
|
||||
|
||||
const oneHourInSeconds = 3600;
|
||||
const oneMonthInSeconds = oneHourInSeconds * 24 * 30;
|
||||
const [startFrom, setStartFrom] = useState(null);
|
||||
const [startTill, setStartTill] = useState(null);
|
||||
const [endFrom, setEndFrom] = useState(null);
|
||||
const [endTill, setEndTill] = useState(null);
|
||||
const [startFrom, setStartFrom] = useState<string>('');
|
||||
const [startTo, setStartTo] = useState<string>('');
|
||||
const [endFrom, setEndFrom] = useState<string>('');
|
||||
const [endTo, setEndTo] = useState<string>('');
|
||||
const [showFilterOptions, setShowFilterOptions] = useState<boolean>(false);
|
||||
|
||||
const setErrorMessage = (useContext as any)(ErrorContext)[1];
|
||||
|
||||
const [processStatuseSelectionOptions, setProcessStatusSelectionOptions] =
|
||||
useState<any[]>([]);
|
||||
const [processStatusSelection, setProcessStatusSelection] = useState<
|
||||
Option[]
|
||||
>([]);
|
||||
const [processModeleSelectionOptions, setProcessModelSelectionOptions] =
|
||||
useState([]);
|
||||
const [processModelSelection, setProcessModelSelection] = useState<Option[]>(
|
||||
const [processStatusAllOptions, setProcessStatusAllOptions] = useState<any[]>(
|
||||
[]
|
||||
);
|
||||
const [processStatusSelection, setProcessStatusSelection] = useState<
|
||||
string[]
|
||||
>([]);
|
||||
const [processModelAvailableItems, setProcessModelAvailableItems] = useState<
|
||||
ProcessModel[]
|
||||
>([]);
|
||||
const [processModelSelection, setProcessModelSelection] =
|
||||
useState<ProcessModel | null>(null);
|
||||
|
||||
const parametersToAlwaysFilterBy = useMemo(() => {
|
||||
return {
|
||||
start_from: setStartFrom,
|
||||
start_till: setStartTill,
|
||||
start_to: setStartTo,
|
||||
end_from: setEndFrom,
|
||||
end_till: setEndTill,
|
||||
end_to: setEndTo,
|
||||
};
|
||||
}, [setStartFrom, setStartTill, setEndFrom, setEndTill]);
|
||||
}, [setStartFrom, setStartTo, setEndFrom, setEndTo]);
|
||||
|
||||
const parametersToGetFromSearchParams = useMemo(() => {
|
||||
return {
|
||||
|
@ -90,7 +107,10 @@ export default function ProcessInstanceList() {
|
|||
const searchParamValue = searchParams.get(paramName);
|
||||
if (searchParamValue) {
|
||||
queryParamString += `&${paramName}=${searchParamValue}`;
|
||||
functionToCall(searchParamValue);
|
||||
const dateString = convertSecondsToFormattedDate(
|
||||
searchParamValue as any
|
||||
);
|
||||
functionToCall(dateString);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -118,24 +138,24 @@ export default function ProcessInstanceList() {
|
|||
const label = `${item.process_group_id}/${item.id}`;
|
||||
Object.assign(item, { label });
|
||||
if (label === processModelFullIdentifier) {
|
||||
setProcessModelSelection([item]);
|
||||
setProcessModelSelection(item);
|
||||
}
|
||||
return item;
|
||||
});
|
||||
setProcessModelSelectionOptions(selectionArray);
|
||||
setProcessModelAvailableItems(selectionArray);
|
||||
|
||||
const processStatusSelectedArray: Option[] = [];
|
||||
const processStatusSelectionArray = PROCESS_STATUSES.map(
|
||||
const processStatusSelectedArray: string[] = [];
|
||||
const processStatusAllOptionsArray = PROCESS_STATUSES.map(
|
||||
(processStatusOption: any) => {
|
||||
const regex = new RegExp(`\\b${processStatusOption}\\b`);
|
||||
if ((searchParams.get('process_status') || '').match(regex)) {
|
||||
processStatusSelectedArray.push({ label: processStatusOption });
|
||||
processStatusSelectedArray.push(processStatusOption);
|
||||
}
|
||||
return { label: processStatusOption };
|
||||
return processStatusOption;
|
||||
}
|
||||
);
|
||||
setProcessStatusSelection(processStatusSelectedArray);
|
||||
setProcessStatusSelectionOptions(processStatusSelectionArray);
|
||||
setProcessStatusAllOptions(processStatusAllOptionsArray);
|
||||
|
||||
getProcessInstances();
|
||||
}
|
||||
|
@ -170,51 +190,58 @@ export default function ProcessInstanceList() {
|
|||
}
|
||||
};
|
||||
|
||||
const handleFilter = (event: any) => {
|
||||
const applyFilter = (event: any) => {
|
||||
event.preventDefault();
|
||||
const { page, perPage } = getPageInfoFromSearchParams(searchParams);
|
||||
let queryParamString = `per_page=${perPage}&page=${page}`;
|
||||
|
||||
if (isTrueComparison(startFrom, '>', startTill)) {
|
||||
setErrorMessage({ message: 'startFrom cannot be after startTill' });
|
||||
const startFromSeconds = convertDateStringToSeconds(startFrom);
|
||||
const endFromSeconds = convertDateStringToSeconds(endFrom);
|
||||
const startToSeconds = convertDateStringToSeconds(startTo);
|
||||
const endToSeconds = convertDateStringToSeconds(endTo);
|
||||
if (isTrueComparison(startFromSeconds, '>', startToSeconds)) {
|
||||
setErrorMessage({
|
||||
message: '"Start date from" cannot be after "start date to"',
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (isTrueComparison(endFrom, '>', endTill)) {
|
||||
setErrorMessage({ message: 'endFrom cannot be after endTill' });
|
||||
if (isTrueComparison(endFromSeconds, '>', endToSeconds)) {
|
||||
setErrorMessage({
|
||||
message: '"End date from" cannot be after "end date to"',
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (isTrueComparison(startFrom, '>', endFrom)) {
|
||||
setErrorMessage({ message: 'startFrom cannot be after endFrom' });
|
||||
if (isTrueComparison(startFromSeconds, '>', endFromSeconds)) {
|
||||
setErrorMessage({
|
||||
message: '"Start date from" cannot be after "end date from"',
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (isTrueComparison(startTill, '>', endTill)) {
|
||||
setErrorMessage({ message: 'startTill cannot be after endTill' });
|
||||
if (isTrueComparison(startToSeconds, '>', endToSeconds)) {
|
||||
setErrorMessage({
|
||||
message: '"Start date to" cannot be after "end date to"',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (startFrom) {
|
||||
queryParamString += `&start_from=${startFrom}`;
|
||||
if (startFromSeconds) {
|
||||
queryParamString += `&start_from=${startFromSeconds}`;
|
||||
}
|
||||
if (startTill) {
|
||||
queryParamString += `&start_till=${startTill}`;
|
||||
if (startToSeconds) {
|
||||
queryParamString += `&start_to=${startToSeconds}`;
|
||||
}
|
||||
if (endFrom) {
|
||||
queryParamString += `&end_from=${endFrom}`;
|
||||
if (endFromSeconds) {
|
||||
queryParamString += `&end_from=${endFromSeconds}`;
|
||||
}
|
||||
if (endTill) {
|
||||
queryParamString += `&end_till=${endTill}`;
|
||||
if (endToSeconds) {
|
||||
queryParamString += `&end_to=${endToSeconds}`;
|
||||
}
|
||||
if (processStatusSelection.length > 0) {
|
||||
const processStatusSelectionString = processStatusSelection.map(
|
||||
(pss: any) => {
|
||||
return pss.label;
|
||||
}
|
||||
);
|
||||
queryParamString += `&process_status=${processStatusSelectionString}`;
|
||||
queryParamString += `&process_status=${processStatusSelection}`;
|
||||
}
|
||||
if (processModelSelection.length > 0) {
|
||||
const currentProcessModel: any = processModelSelection[0];
|
||||
queryParamString += `&process_group_identifier=${currentProcessModel.process_group_id}&process_model_identifier=${currentProcessModel.id}`;
|
||||
|
||||
if (processModelSelection) {
|
||||
queryParamString += `&process_group_identifier=${processModelSelection.process_group_id}&process_model_identifier=${processModelSelection.id}`;
|
||||
}
|
||||
|
||||
setErrorMessage(null);
|
||||
|
@ -227,30 +254,22 @@ export default function ProcessInstanceList() {
|
|||
initialDate: any,
|
||||
onChangeFunction: any
|
||||
) => {
|
||||
let selectedDate = null;
|
||||
if (initialDate) {
|
||||
selectedDate = new Date(initialDate * 1000);
|
||||
}
|
||||
return (
|
||||
<Form.Group>
|
||||
<InputGroup>
|
||||
<Stack className="ms-auto" direction="horizontal" gap={3}>
|
||||
<InputGroup.Text className="text-nowrap">
|
||||
{labelString}
|
||||
{'\u00A0'}
|
||||
</InputGroup.Text>
|
||||
<DatePicker
|
||||
id={`date-picker-${name}`}
|
||||
selected={selectedDate}
|
||||
onChange={(date: any) =>
|
||||
convertDateToSeconds(date, onChangeFunction)
|
||||
}
|
||||
showTimeSelect
|
||||
dateFormat={DATE_FORMAT}
|
||||
/>
|
||||
</Stack>
|
||||
</InputGroup>
|
||||
</Form.Group>
|
||||
<DatePicker dateFormat={DATE_FORMAT_CARBON} datePickerType="single">
|
||||
<DatePickerInput
|
||||
id={`date-picker-${name}`}
|
||||
placeholder={DATE_FORMAT}
|
||||
labelText={labelString}
|
||||
type="text"
|
||||
size="md"
|
||||
autocomplete="off"
|
||||
allowInput={false}
|
||||
onChange={(dateChangeEvent: any) => {
|
||||
onChangeFunction(dateChangeEvent.srcElement.value);
|
||||
}}
|
||||
value={initialDate}
|
||||
/>
|
||||
</DatePicker>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -273,96 +292,88 @@ export default function ProcessInstanceList() {
|
|||
return queryParamString;
|
||||
};
|
||||
|
||||
const processModelSearch = () => {
|
||||
const processStatusSearch = () => {
|
||||
return (
|
||||
<Form.Group>
|
||||
<InputGroup>
|
||||
<InputGroup.Text className="text-nowrap">
|
||||
Process Model:{' '}
|
||||
</InputGroup.Text>
|
||||
<Typeahead
|
||||
style={{ width: 500 }}
|
||||
id="process-model-selection"
|
||||
labelKey="label"
|
||||
onChange={setProcessModelSelection}
|
||||
options={processModeleSelectionOptions}
|
||||
placeholder="Choose a process model..."
|
||||
selected={processModelSelection}
|
||||
/>
|
||||
</InputGroup>
|
||||
</Form.Group>
|
||||
<MultiSelect
|
||||
label="Choose Status"
|
||||
id="process-instance-status-select"
|
||||
titleText="Status"
|
||||
items={processStatusAllOptions}
|
||||
onChange={(selection: any) => {
|
||||
setProcessStatusSelection(selection.selectedItems);
|
||||
}}
|
||||
itemToString={(item: any) => {
|
||||
return item || '';
|
||||
}}
|
||||
selectionFeedback="top-after-reopen"
|
||||
selectedItems={processStatusSelection}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const processStatusSearch = () => {
|
||||
return (
|
||||
<Form.Group>
|
||||
<InputGroup>
|
||||
<InputGroup.Text className="text-nowrap">
|
||||
Process Status:{' '}
|
||||
</InputGroup.Text>
|
||||
<Typeahead
|
||||
multiple
|
||||
style={{ width: 500 }}
|
||||
id="process-status-selection"
|
||||
// for cypress tests since data-qa does not work
|
||||
inputProps={{
|
||||
name: 'process-status-selection',
|
||||
}}
|
||||
labelKey="label"
|
||||
onChange={setProcessStatusSelection}
|
||||
options={processStatuseSelectionOptions}
|
||||
placeholder="Choose process statuses..."
|
||||
selected={processStatusSelection}
|
||||
/>
|
||||
</InputGroup>
|
||||
</Form.Group>
|
||||
);
|
||||
const clearFilters = () => {
|
||||
setProcessModelSelection(null);
|
||||
setProcessStatusSelection([]);
|
||||
setStartFrom('');
|
||||
setStartTo('');
|
||||
setEndFrom('');
|
||||
setEndTo('');
|
||||
};
|
||||
|
||||
const filterOptions = () => {
|
||||
if (!showFilterOptions) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
<div className="col">
|
||||
<form onSubmit={handleFilter}>
|
||||
<Stack direction="horizontal" gap={3}>
|
||||
{processModelSearch()}
|
||||
</Stack>
|
||||
<br />
|
||||
<Stack direction="horizontal" gap={3}>
|
||||
{dateComponent(
|
||||
'Start Range: ',
|
||||
'start-from',
|
||||
startFrom,
|
||||
setStartFrom
|
||||
)}
|
||||
{dateComponent('-', 'start-till', startTill, setStartTill)}
|
||||
</Stack>
|
||||
<br />
|
||||
<Stack direction="horizontal" gap={3}>
|
||||
{dateComponent(
|
||||
'End Range: \u00A0\u00A0',
|
||||
'end-from',
|
||||
endFrom,
|
||||
setEndFrom
|
||||
)}
|
||||
{dateComponent('-', 'end-till', endTill, setEndTill)}
|
||||
</Stack>
|
||||
<br />
|
||||
<Stack direction="horizontal" gap={3}>
|
||||
{processStatusSearch()}
|
||||
</Stack>
|
||||
<Stack direction="horizontal" gap={3}>
|
||||
<Button className="ms-auto" variant="secondary" type="submit">
|
||||
Filter
|
||||
</Button>
|
||||
</Stack>
|
||||
</form>
|
||||
</div>
|
||||
<div className="col" />
|
||||
</div>
|
||||
</div>
|
||||
<>
|
||||
<Grid fullWidth className="with-bottom-margin">
|
||||
<Column md={8}>
|
||||
<ProcessModelSearch
|
||||
onChange={(selection: any) =>
|
||||
setProcessModelSelection(selection.selectedItem)
|
||||
}
|
||||
processModels={processModelAvailableItems}
|
||||
selectedItem={processModelSelection}
|
||||
/>
|
||||
</Column>
|
||||
<Column md={8}>{processStatusSearch()}</Column>
|
||||
</Grid>
|
||||
<Grid fullWidth className="with-bottom-margin">
|
||||
<Column md={4}>
|
||||
{dateComponent(
|
||||
'Start date from',
|
||||
'start-from',
|
||||
startFrom,
|
||||
setStartFrom
|
||||
)}
|
||||
</Column>
|
||||
<Column md={4}>
|
||||
{dateComponent('Start date to', 'start-to', startTo, setStartTo)}
|
||||
</Column>
|
||||
<Column md={4}>
|
||||
{dateComponent('End date from', 'end-from', endFrom, setEndFrom)}
|
||||
</Column>
|
||||
<Column md={4}>
|
||||
{dateComponent('End date to', 'end-to', endTo, setEndTo)}
|
||||
</Column>
|
||||
</Grid>
|
||||
<Grid fullWidth className="with-bottom-margin">
|
||||
<Column md={4}>
|
||||
<ButtonSet>
|
||||
<Button
|
||||
kind=""
|
||||
className="button-white-background"
|
||||
onClick={clearFilters}
|
||||
>
|
||||
Clear
|
||||
</Button>
|
||||
<Button kind="secondary" onClick={applyFilter}>
|
||||
Filter
|
||||
</Button>
|
||||
</ButtonSet>
|
||||
</Column>
|
||||
</Grid>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -404,7 +415,7 @@ export default function ProcessInstanceList() {
|
|||
);
|
||||
});
|
||||
return (
|
||||
<Table striped bordered>
|
||||
<Table size="lg">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Process Instance Id</th>
|
||||
|
@ -436,20 +447,42 @@ export default function ProcessInstanceList() {
|
|||
);
|
||||
};
|
||||
|
||||
const toggleShowFilterOptions = () => {
|
||||
setShowFilterOptions(!showFilterOptions);
|
||||
};
|
||||
|
||||
if (pagination) {
|
||||
const { page, perPage } = getPageInfoFromSearchParams(searchParams);
|
||||
return (
|
||||
<>
|
||||
{processInstanceTitleElement()}
|
||||
<Grid fullWidth>
|
||||
<Column lg={15} />
|
||||
<Column lg={1}>
|
||||
<Button
|
||||
kind="ghost"
|
||||
renderIcon={Filter}
|
||||
iconDescription="Filter Options"
|
||||
hasIconOnly
|
||||
size="lg"
|
||||
onClick={toggleShowFilterOptions}
|
||||
/>
|
||||
</Column>
|
||||
</Grid>
|
||||
{filterOptions()}
|
||||
<PaginationForTable
|
||||
page={page}
|
||||
perPage={perPage}
|
||||
pagination={pagination}
|
||||
tableToDisplay={buildTable()}
|
||||
queryParamString={getSearchParamsAsQueryString()}
|
||||
path="/admin/process-instances"
|
||||
/>
|
||||
<br />
|
||||
<Grid fullWidth>
|
||||
<Column lg={16}>
|
||||
<PaginationForTable
|
||||
page={page}
|
||||
perPage={perPage}
|
||||
pagination={pagination}
|
||||
tableToDisplay={buildTable()}
|
||||
queryParamString={getSearchParamsAsQueryString()}
|
||||
path="/admin/process-instances"
|
||||
/>
|
||||
</Column>
|
||||
</Grid>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
import { Table } from 'react-bootstrap';
|
||||
// @ts-ignore
|
||||
import { Table } from '@carbon/react';
|
||||
import { useParams, useSearchParams, Link } from 'react-router-dom';
|
||||
import PaginationForTable from '../components/PaginationForTable';
|
||||
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
import { Button, Table } from 'react-bootstrap';
|
||||
// @ts-ignore
|
||||
import { Button, Table } from '@carbon/react';
|
||||
import { useParams, Link } from 'react-router-dom';
|
||||
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
||||
import HttpService from '../services/HttpService';
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
import { useParams, useSearchParams } from 'react-router-dom';
|
||||
|
||||
import { Button, Table } from 'react-bootstrap';
|
||||
// @ts-ignore
|
||||
import { Button, Table } from '@carbon/react';
|
||||
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
||||
|
||||
import PaginationForTable from '../components/PaginationForTable';
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { useContext, useEffect, useState } from 'react';
|
||||
import Editor from '@monaco-editor/react';
|
||||
import { useParams, useNavigate, Link } from 'react-router-dom';
|
||||
import { Button, Modal, Stack } from 'react-bootstrap';
|
||||
// @ts-ignore
|
||||
import { Button, Modal, Stack } from '@carbon/react';
|
||||
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
||||
import HttpService from '../services/HttpService';
|
||||
import ReactDiagramEditor from '../components/ReactDiagramEditor';
|
||||
|
@ -408,15 +409,15 @@ export default function ProcessInstanceShow() {
|
|||
const taskToUse: any = { ...taskToDisplay, data: taskDataToDisplay };
|
||||
if (taskToDisplay) {
|
||||
return (
|
||||
<Modal show={!!taskToUse} onHide={handleTaskDataDisplayClose}>
|
||||
<Modal.Header closeButton>
|
||||
<Modal.Title>
|
||||
<Stack direction="horizontal" gap={2}>
|
||||
{taskToUse.name} ({taskToUse.type}): {taskToUse.state}
|
||||
{taskDataButtons(taskToUse)}
|
||||
</Stack>
|
||||
</Modal.Title>
|
||||
</Modal.Header>
|
||||
<Modal
|
||||
open={!!taskToUse}
|
||||
passiveModal
|
||||
onRequestClose={handleTaskDataDisplayClose}
|
||||
>
|
||||
<Stack orientation="horizontal" gap={2}>
|
||||
{taskToUse.name} ({taskToUse.type}): {taskToUse.state}
|
||||
{taskDataButtons(taskToUse)}
|
||||
</Stack>
|
||||
{taskDataContainer()}
|
||||
</Modal>
|
||||
);
|
||||
|
@ -435,7 +436,7 @@ export default function ProcessInstanceShow() {
|
|||
processGroupId={params.process_group_id}
|
||||
linkProcessModel
|
||||
/>
|
||||
<Stack direction="horizontal" gap={3}>
|
||||
<Stack orientation="horizontal" gap={3}>
|
||||
<h2>Process Instance Id: {processInstanceToUse.id}</h2>
|
||||
<ButtonWithConfirmation
|
||||
description="Delete Process Instance?"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { useState, useEffect, useContext } from 'react';
|
||||
import { useParams, useNavigate } from 'react-router-dom';
|
||||
import { Button, Stack } from 'react-bootstrap';
|
||||
// @ts-ignore
|
||||
import { Button, Stack } from '@carbon/react';
|
||||
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
||||
import HttpService from '../services/HttpService';
|
||||
import ButtonWithConfirmation from '../components/ButtonWithConfirmation';
|
||||
|
@ -79,7 +80,7 @@ export default function ProcessModelEdit() {
|
|||
/>
|
||||
<br />
|
||||
<br />
|
||||
<Stack direction="horizontal" gap={3}>
|
||||
<Stack orientation="horizontal" gap={3}>
|
||||
<Button type="submit">Submit</Button>
|
||||
<Button variant="secondary" href={`/admin/${processModelPath}`}>
|
||||
Cancel
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { useContext, useEffect, useRef, useState } from 'react';
|
||||
import { useNavigate, useParams, useSearchParams } from 'react-router-dom';
|
||||
import { Button, Modal, Stack } from 'react-bootstrap';
|
||||
import Container from 'react-bootstrap/Container';
|
||||
// @ts-ignore
|
||||
import { Button, Modal, Stack, Content } from '@carbon/react';
|
||||
// import Container from 'react-bootstrap/Container';
|
||||
import Row from 'react-bootstrap/Row';
|
||||
import Col from 'react-bootstrap/Col';
|
||||
|
||||
|
@ -193,31 +194,25 @@ export default function ProcessModelEditDiagram() {
|
|||
const newFileNameBox = () => {
|
||||
const fileExtension = `.${searchParams.get('file_type')}`;
|
||||
return (
|
||||
<Modal show={showFileNameEditor} onHide={handleFileNameCancel}>
|
||||
<Modal.Header closeButton>
|
||||
<Modal.Title>Process Model File Name</Modal.Title>
|
||||
</Modal.Header>
|
||||
<form onSubmit={handleFileNameSave}>
|
||||
<label>File Name:</label>
|
||||
<span>
|
||||
<input
|
||||
name="file_name"
|
||||
type="text"
|
||||
value={newFileName}
|
||||
onChange={(e) => setNewFileName(e.target.value)}
|
||||
autoFocus
|
||||
/>
|
||||
{fileExtension}
|
||||
</span>
|
||||
<Modal.Footer>
|
||||
<Button variant="secondary" onClick={handleFileNameCancel}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button variant="primary" type="submit">
|
||||
Save Changes
|
||||
</Button>
|
||||
</Modal.Footer>
|
||||
</form>
|
||||
<Modal
|
||||
open={showFileNameEditor}
|
||||
modalHeading="Processs Model File Name"
|
||||
primaryButtonText="Save Changes"
|
||||
secondaryButtonText="Cancel"
|
||||
onSecondarySubmit={handleFileNameCancel}
|
||||
onRequestSubmit={handleFileNameSave}
|
||||
>
|
||||
<label>File Name:</label>
|
||||
<span>
|
||||
<input
|
||||
name="file_name"
|
||||
type="text"
|
||||
value={newFileName}
|
||||
onChange={(e) => setNewFileName(e.target.value)}
|
||||
autoFocus
|
||||
/>
|
||||
{fileExtension}
|
||||
</span>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
@ -288,7 +283,6 @@ export default function ProcessModelEditDiagram() {
|
|||
// we should update this to act like updating scripts
|
||||
// where we pass an event to bpmn-js
|
||||
setScriptModeling(modeling);
|
||||
|
||||
setScriptText(script || '');
|
||||
setScriptType(scriptTypeString);
|
||||
setScriptEventBus(eventBus);
|
||||
|
@ -478,7 +472,7 @@ export default function ProcessModelEditDiagram() {
|
|||
}
|
||||
return (
|
||||
<main>
|
||||
<Container>
|
||||
<Content>
|
||||
<Row>
|
||||
<Col xs={8}>
|
||||
<Button variant="link" disabled style={{ fontSize: '1.5em' }}>
|
||||
|
@ -519,11 +513,11 @@ export default function ProcessModelEditDiagram() {
|
|||
</Col>
|
||||
<Col xs={1}>{scriptUnitTestResultBoolElement}</Col>
|
||||
</Row>
|
||||
</Container>
|
||||
<Stack direction="horizontal" gap={3}>
|
||||
</Content>
|
||||
<Stack orientation="horizontal" gap={3}>
|
||||
{unitTestFailureElement()}
|
||||
</Stack>
|
||||
<Stack direction="horizontal" gap={3}>
|
||||
<Stack orientation="horizontal" gap={3}>
|
||||
<Stack>
|
||||
<div>Input Json:</div>
|
||||
<div>
|
||||
|
@ -564,28 +558,25 @@ export default function ProcessModelEditDiagram() {
|
|||
if (scriptElement) {
|
||||
scriptName = (scriptElement as any).di.bpmnElement.name;
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal size="xl" show={showScriptEditor} onHide={handleScriptEditorClose}>
|
||||
<Modal.Header closeButton>
|
||||
<Modal.Title>Editing Script: {scriptName}</Modal.Title>
|
||||
</Modal.Header>
|
||||
<Modal.Body>
|
||||
<Editor
|
||||
height={500}
|
||||
width="auto"
|
||||
options={generalEditorOptions()}
|
||||
defaultLanguage="python"
|
||||
defaultValue={scriptText}
|
||||
onChange={handleEditorScriptChange}
|
||||
onMount={handleEditorDidMount}
|
||||
/>
|
||||
{scriptUnitTestEditorElement()}
|
||||
</Modal.Body>
|
||||
<Modal.Footer>
|
||||
<Button variant="secondary" onClick={handleScriptEditorClose}>
|
||||
Close
|
||||
</Button>
|
||||
</Modal.Footer>
|
||||
<Modal
|
||||
open={showScriptEditor}
|
||||
modalHeading={`Editing Script: ${scriptName}`}
|
||||
primaryButtonText="Close"
|
||||
onRequestSubmit={handleScriptEditorClose}
|
||||
size="lg"
|
||||
>
|
||||
<Editor
|
||||
height={500}
|
||||
width="auto"
|
||||
options={generalEditorOptions()}
|
||||
defaultLanguage="python"
|
||||
value={scriptText}
|
||||
onChange={handleEditorScriptChange}
|
||||
onMount={handleEditorDidMount}
|
||||
/>
|
||||
{scriptUnitTestEditorElement()}
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { useContext, useEffect, useState } from 'react';
|
||||
import { Link, useParams } from 'react-router-dom';
|
||||
import { Button, Stack } from 'react-bootstrap';
|
||||
// @ts-ignore
|
||||
import { Button, Stack } from '@carbon/react';
|
||||
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
||||
import FileInput from '../components/FileInput';
|
||||
import HttpService from '../services/HttpService';
|
||||
|
@ -210,7 +211,7 @@ export default function ProcessModelShow() {
|
|||
|
||||
const processModelButtons = () => {
|
||||
return (
|
||||
<Stack direction="horizontal" gap={3}>
|
||||
<Stack orientation="horizontal" gap={3}>
|
||||
<Button onClick={processInstanceCreateAndRun} variant="primary">
|
||||
Run
|
||||
</Button>
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
import Editor from '@monaco-editor/react';
|
||||
import { useNavigate, useParams, useSearchParams } from 'react-router-dom';
|
||||
import { Button, Modal } from 'react-bootstrap';
|
||||
// @ts-ignore
|
||||
import { Button, Modal } from '@carbon/react';
|
||||
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
||||
import HttpService from '../services/HttpService';
|
||||
import ButtonWithConfirmation from '../components/ButtonWithConfirmation';
|
||||
|
@ -118,31 +119,25 @@ export default function ReactFormEditor() {
|
|||
|
||||
const newFileNameBox = () => {
|
||||
return (
|
||||
<Modal show={showFileNameEditor} onHide={handleFileNameCancel}>
|
||||
<Modal.Header closeButton>
|
||||
<Modal.Title>Process Model File Name</Modal.Title>
|
||||
</Modal.Header>
|
||||
<form onSubmit={handleFileNameSave}>
|
||||
<label>File Name:</label>
|
||||
<span>
|
||||
<input
|
||||
name="file_name"
|
||||
type="text"
|
||||
value={newFileName}
|
||||
onChange={(e) => setNewFileName(e.target.value)}
|
||||
autoFocus
|
||||
/>
|
||||
.{fileExtension}
|
||||
</span>
|
||||
<Modal.Footer>
|
||||
<Button variant="secondary" onClick={handleFileNameCancel}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button variant="primary" type="submit">
|
||||
Save Changes
|
||||
</Button>
|
||||
</Modal.Footer>
|
||||
</form>
|
||||
<Modal
|
||||
open={showFileNameEditor}
|
||||
modalHeading="Processs Model File Name"
|
||||
primaryButtonText="Save Changes"
|
||||
secondaryButtonText="Cancel"
|
||||
onSecondarySubmit={handleFileNameCancel}
|
||||
onRequestSubmit={handleFileNameSave}
|
||||
>
|
||||
<label>File Name:</label>
|
||||
<span>
|
||||
<input
|
||||
name="file_name"
|
||||
type="text"
|
||||
value={newFileName}
|
||||
onChange={(e) => setNewFileName(e.target.value)}
|
||||
autoFocus
|
||||
/>
|
||||
{fileExtension}
|
||||
</span>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
@ -160,7 +155,7 @@ export default function ReactFormEditor() {
|
|||
{processModelFile ? `: ${(processModelFile as any).name}` : ''}
|
||||
</h2>
|
||||
{newFileNameBox()}
|
||||
<Button onClick={saveFile} variant="danger">
|
||||
<Button onClick={saveFile} variant="danger" data-qa="file-save-button">
|
||||
Save
|
||||
</Button>
|
||||
{params.file_name ? (
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
import { Link, useSearchParams } from 'react-router-dom';
|
||||
import { Button, Table } from 'react-bootstrap';
|
||||
// @ts-ignore
|
||||
import { Button, Table } from '@carbon/react';
|
||||
import { MdDelete } from 'react-icons/md';
|
||||
import PaginationForTable from '../components/PaginationForTable';
|
||||
import HttpService from '../services/HttpService';
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Stack } from 'react-bootstrap';
|
||||
// @ts-ignore
|
||||
import { Stack } from '@carbon/react';
|
||||
import Button from 'react-bootstrap/Button';
|
||||
import Form from 'react-bootstrap/Form';
|
||||
import HttpService from '../services/HttpService';
|
||||
|
@ -67,7 +68,7 @@ export default function SecretNew() {
|
|||
}}
|
||||
/>
|
||||
</Form.Group>
|
||||
<Stack direction="horizontal" gap={3}>
|
||||
<Stack orientation="horizontal" gap={3}>
|
||||
<Button variant="primary" type="submit">
|
||||
Submit
|
||||
</Button>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
import { useParams, useNavigate } from 'react-router-dom';
|
||||
import { Stack, Table, Button } from 'react-bootstrap';
|
||||
// @ts-ignore
|
||||
import { Stack, Table, Button } from '@carbon/react';
|
||||
import HttpService from '../services/HttpService';
|
||||
import { Secret } from '../interfaces';
|
||||
import ButtonWithConfirmation from '../components/ButtonWithConfirmation';
|
||||
|
@ -64,8 +65,8 @@ export default function SecretShow() {
|
|||
if (secret) {
|
||||
return (
|
||||
<>
|
||||
<Stack direction="horizontal" gap={3}>
|
||||
<h2>Secret Key: {secret.key}</h2>
|
||||
<h2>Secret Key: {secret.key}</h2>
|
||||
<Stack orientation="horizontal" gap={3}>
|
||||
<ButtonWithConfirmation
|
||||
description="Delete Secret?"
|
||||
onConfirmation={deleteSecret}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { useContext, useEffect, useState } from 'react';
|
||||
import { Link, useNavigate, useParams } from 'react-router-dom';
|
||||
import Form from '@rjsf/core';
|
||||
import { Button, Stack } from 'react-bootstrap';
|
||||
// @ts-ignore
|
||||
import { Button, Stack } from '@carbon/react';
|
||||
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
|
@ -84,7 +85,7 @@ export default function TaskShow() {
|
|||
});
|
||||
}
|
||||
return (
|
||||
<Stack direction="horizontal" gap={3}>
|
||||
<Stack orientation="horizontal" gap={3}>
|
||||
<Button href="/tasks">Go Back To List</Button>
|
||||
{userTasksElement}
|
||||
</Stack>
|
||||
|
|
Loading…
Reference in New Issue