From c2046d31a30f446bd8fb7efa4ef3c81a4c9dd16c Mon Sep 17 00:00:00 2001 From: JEFFREY-Bonson Date: Tue, 30 Jan 2024 20:58:08 +0530 Subject: [PATCH] Method list dialog conversion --- app/controllers/miq_ae_class_controller.rb | 26 +++ .../AeInlineMethod/FilterNamespace.jsx | 56 +++++ .../AeInlineMethod/NamespaceSelector.jsx | 106 +++++++++ .../components/AeInlineMethod/helper.js | 61 +++++ .../components/AeInlineMethod/index.jsx | 190 +++++++++++++++ .../components/AeInlineMethod/style.scss | 79 +++++++ .../components/miq-data-table/index.jsx | 4 +- .../miq-data-table/miq-table-cell.jsx | 6 +- .../packs/component-definitions-common.js | 2 + app/stylesheet/miq-data-table.scss | 4 + .../miq_ae_class/_embedded_methods.html.haml | 31 +-- config/routes.rb | 3 + package.json | 1 + spec/config/routes.pending.yml | 3 + yarn.lock | 220 +++++++++++++----- 15 files changed, 698 insertions(+), 94 deletions(-) create mode 100644 app/javascript/components/AeInlineMethod/FilterNamespace.jsx create mode 100644 app/javascript/components/AeInlineMethod/NamespaceSelector.jsx create mode 100644 app/javascript/components/AeInlineMethod/helper.js create mode 100644 app/javascript/components/AeInlineMethod/index.jsx create mode 100644 app/javascript/components/AeInlineMethod/style.scss diff --git a/app/controllers/miq_ae_class_controller.rb b/app/controllers/miq_ae_class_controller.rb index d13ce6bb009..c59e120efcb 100644 --- a/app/controllers/miq_ae_class_controller.rb +++ b/app/controllers/miq_ae_class_controller.rb @@ -520,6 +520,7 @@ def edit_method id = x_node.split('-') end @ae_method = find_record_with_rbac(MiqAeMethod, id[1]) + @embedded_methods = MiqAeMethod.where(:relative_path => @ae_method[:embedded_methods].map { |str| str.sub(/^\//, '') }) @selectable_methods = embedded_method_regex(@ae_method.fqname) if playbook_style_location?(@ae_method.location) # these variants are implemented in Angular @@ -1815,6 +1816,31 @@ def namespace render :json => find_record_with_rbac(MiqAeNamespace, params[:id]).attributes.slice('name', 'description', 'enabled') end + def ae_domains + domains = MiqAeDomain.where("ancestry is null and enabled = ?", true).order("name").select("id, name") + render :json => {:domains => domains} + end + + def ae_methods + methods = MiqAeMethod + .name_path_search(params[:search]) + .domain_search(params[:domain_id]) + .selected_methods(params[:ids]) + .select("id, relative_path, name") + .order('name') + render :json => {:methods => methods} + end + + def ae_method_operations + @edit[:new][:embedded_methods] = MiqAeMethod.selected_methods(params[:ids]).map { |method| "/#{method.relative_path}" } + @changed = true + render :update do |page| + page << javascript_prologue + page << javascript_for_miq_button_visibility(@changed) + page << "miqSparkle(false);" + end + end + private def feature_by_action diff --git a/app/javascript/components/AeInlineMethod/FilterNamespace.jsx b/app/javascript/components/AeInlineMethod/FilterNamespace.jsx new file mode 100644 index 00000000000..70fb145ae9c --- /dev/null +++ b/app/javascript/components/AeInlineMethod/FilterNamespace.jsx @@ -0,0 +1,56 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { + Select, SelectItem, Search, +} from 'carbon-components-react'; +import { noSelect } from './helper'; + +const FilterNamespace = ({ domains, onSearch }) => { + /** Function to render the search text. */ + const renderSearchText = () => ( +
+ + onSearch({ searchText: noSelect })} + onChange={(event) => onSearch({ searchText: event.target.value || noSelect })} + /> +
+ ); + + /** Function to render the domain items in a drop-down list. */ + const renderDomainList = () => ( + + ); + + return ( +
+ {renderSearchText()} + {domains && renderDomainList()} +
+ ); +}; + +export default FilterNamespace; + +FilterNamespace.propTypes = { + domains: PropTypes.arrayOf(PropTypes.any), + onSearch: PropTypes.func.isRequired, +}; + +FilterNamespace.defaultProps = { + domains: undefined, +}; diff --git a/app/javascript/components/AeInlineMethod/NamespaceSelector.jsx b/app/javascript/components/AeInlineMethod/NamespaceSelector.jsx new file mode 100644 index 00000000000..8e6b9a39ccf --- /dev/null +++ b/app/javascript/components/AeInlineMethod/NamespaceSelector.jsx @@ -0,0 +1,106 @@ +import React, { useState, useMemo, useCallback } from 'react'; +import PropTypes from 'prop-types'; +import { useQuery } from 'react-query'; +import { Loading } from 'carbon-components-react'; +import { debounce } from 'lodash'; +import FilterNamespace from './FilterNamespace'; +import MiqDataTable from '../miq-data-table'; +import NotificationMessage from '../notification-message'; +import { CellAction } from '../miq-data-table/helper'; +import { + methodSelectorHeaders, formatMethods, searchUrl, namespaceUrls, +} from './helper'; +import './style.scss'; + +const NamespaceSelector = ({ onSelectMethod, selectedIds }) => { + const [filterData, setFilterData] = useState({ searchText: '', selectedDomain: '' }); + + /** Loads the domains and stores in domainData for 60 seconds. */ + const { data: domainsData, isLoading: domainsLoading } = useQuery( + 'domainsData', + async() => (await http.get(namespaceUrls.aeDomainsUrl)).domains, + { + staleTime: 60000, + } + ); + + /** Loads the methods and stores in methodsData for 60 seconds. + * If condition works on page load + * Else part would work if there is a change in filterData. + */ + const { data, isLoading: methodsLoading } = useQuery( + ['methodsData', filterData.searchText, filterData.selectedDomain], + async() => { + if (!filterData.searchText && !filterData.selectedDomain) { + const response = await http.get(namespaceUrls.aeMethodsUrl); + return formatMethods(response.methods); + } + const url = searchUrl(filterData.selectedDomain, filterData.searchText); + const response = await http.get(url); + return formatMethods(response.methods); + }, + { + keepPreviousData: true, + refetchOnWindowFocus: false, + staleTime: 60000, + } + ); + + /** Debounce the search text by delaying the text input provided to the API. */ + const debouncedSearch = debounce((newFilterData) => { + setFilterData(newFilterData); + }, 300); + + /** Function to handle the onSearch event during a filter change event. */ + const onSearch = useCallback( + (newFilterData) => debouncedSearch(newFilterData), + [debouncedSearch] + ); + + /** Function to handle the click event of a cell in the data table. */ + const onCellClick = (selectedRow, cellType, checked) => { + const selectedItems = cellType === CellAction.selectAll + ? data && data.map((item) => item.id) + : [selectedRow]; + onSelectMethod({ selectedItems, cellType, checked }); + }; + + /** Function to render the list which depends on the data and selectedIds. + * List is memoized to prevent unnecessary re-renders when other state values change. */ + const renderContents = useMemo(() => { + if (!data || data.length === 0) { + return ; + } + + return ( + onCellClick(selectedRow, cellType, event.target.checked)} + /> + ); + }, [data, selectedIds]); + + return ( +
+ +
+ {(domainsLoading || methodsLoading) + ? + : renderContents} +
+
+ ); +}; + +NamespaceSelector.propTypes = { + onSelectMethod: PropTypes.func.isRequired, + selectedIds: PropTypes.arrayOf(PropTypes.any).isRequired, +}; + +export default NamespaceSelector; diff --git a/app/javascript/components/AeInlineMethod/helper.js b/app/javascript/components/AeInlineMethod/helper.js new file mode 100644 index 00000000000..f846d4fe4df --- /dev/null +++ b/app/javascript/components/AeInlineMethod/helper.js @@ -0,0 +1,61 @@ +export const namespaceUrls = { + aeMethodsUrl: '/miq_ae_class/ae_methods', + aeMethodOperationsUrl: '/miq_ae_class/ae_method_operations', + aeDomainsUrl: '/miq_ae_class/ae_domains', +}; + +export const noSelect = 'NONE'; + +/** Headers needed for the data-table list. */ +export const methodSelectorHeaders = [ + { + key: 'name', + header: 'Name', + }, + { + key: 'path', + header: 'Relative path', + }, +]; + +export const methodListHeaders = [ + ...methodSelectorHeaders, + { key: 'remove', header: __('Remove'), actionCell: true }, +]; + +/** Function to format the method data needed for the data-table list. */ +export const formatMethods = (methods) => (methods.map((item) => ({ + id: item.id.toString(), + name: { text: item.name, icon: 'icon node-icon fa-ruby' }, + path: item.relative_path, +}))); + +const removeMethodButton = () => ({ + is_button: true, + actionCell: true, + title: __('Remove'), + text: __('Remove'), + alt: __('Remove'), + kind: 'danger', + callback: 'removeMethod', +}); + +export const formatListMethods = (methods) => (methods.map((item, index) => ({ + id: item.id.toString(), + name: { text: item.name, icon: 'icon node-icon fa-ruby' }, + path: item.relative_path, + remove: removeMethodButton(item, index), +}))); + +/** Function to return a conditional URL based on the selected filters. */ +export const searchUrl = (selectedDomain, text) => { + const queryParams = []; + if (selectedDomain && selectedDomain !== noSelect) { + queryParams.push(`domain_id=${selectedDomain}`); + } + if (text && text !== noSelect) { + queryParams.push(`search=${text}`); + } + const queryString = queryParams.length > 0 ? `?${queryParams.join('&')}` : ''; + return `${namespaceUrls.aeMethodsUrl}${queryString}`; +}; diff --git a/app/javascript/components/AeInlineMethod/index.jsx b/app/javascript/components/AeInlineMethod/index.jsx new file mode 100644 index 00000000000..09dc91e7b2a --- /dev/null +++ b/app/javascript/components/AeInlineMethod/index.jsx @@ -0,0 +1,190 @@ +import React, { useState, useEffect } from 'react'; +import { QueryClient, QueryClientProvider } from 'react-query'; +import PropTypes from 'prop-types'; +import { + Modal, Button, ModalBody, Accordion, AccordionItem, +} from 'carbon-components-react'; +import { AddAlt16 } from '@carbon/icons-react'; +import NotificationMessage from '../notification-message'; +import MiqDataTable from '../miq-data-table'; +import NamespaceSelector from './NamespaceSelector'; +import { CellAction } from '../miq-data-table/helper'; +import { formatListMethods, methodListHeaders, namespaceUrls } from './helper'; + +/** Component to render a tree and to select an embedded method. */ +const AeInlineMethod = ({ type, selected }) => { + const queryClient = new QueryClient(); + + const [data, setData] = useState({ + isModalOpen: false, + selectedIds: selected ? selected.map((item) => item.id.toString()) : [], + rows: selected ? formatListMethods(selected) : [], + notification: false, + }); + + useEffect(() => { + setData({ ...data, notification: data.selectedIds.length > 20 }); + }, [data.selectedIds]); + + /** Function to show/hide the modal. */ + const showModal = (status) => setData({ ...data, isModalOpen: status }); + + /** Function to handle the select-all check-box click event. */ + const onSelectAll = (selectedItems, checked) => setData({ ...data, selectedIds: checked ? [...selectedItems] : [] }); + + /** Function to handle the list row selection events. + * selectedItem is passed as an array. */ + const onItemSelect = (selectedItems, checked) => { + if (checked) { + data.selectedIds.push(selectedItems[0].id); + } else { + data.selectedIds = data.selectedIds.filter((item) => item !== selectedItems[0].id); + } + setData({ ...data, selectedIds: [...data.selectedIds] }); + }; + + /** Function to add/remove an selected items. */ + const onSelectMethod = (selectedItems, cellType, checked) => { + switch (cellType) { + case CellAction.selectAll: onSelectAll(selectedItems, checked); break; + default: onItemSelect(selectedItems, checked); break; + } + }; + + /** Updates the ruby form with the selected methods. */ + const updateRubyForm = (ids) => $.get(`${namespaceUrls.aeMethodOperationsUrl}?&ids=${ids}`); + + /** Function to handle the click events for the list. */ + const onCellClickHandler = (item) => { + if (item && item.callbackAction && item.callbackAction === 'removeMethod') { + const ids = data.selectedIds.filter((id) => id !== item.id); + setData({ + rows: data.rows.filter((row) => row.id !== item.id), + selectedIds: ids, + }); + updateRubyForm(ids.map((str) => parseInt(str, 10))); + } + }; + + /** Function to handle the modal submit action. */ + const submitModal = () => { + if (data.selectedIds.length > 0) { + const ids = data.selectedIds.map((str) => parseInt(str, 10)); + http.get(`${namespaceUrls.aeMethodsUrl}?ids=${ids}`) + .then(({ methods }) => { + setData({ + ...data, rows: formatListMethods(methods), isModalOpen: false, + }); + updateRubyForm(ids); + }); + } else { + setData({ + ...data, rows: [], isModalOpen: false, + }); + } + }; + + /** Function to render the modal with namespace selector component. */ + const renderModalSelector = () => ( + showModal(false)} + onRequestSubmit={() => submitModal()} + onSecondarySubmit={() => showModal(false)} + primaryButtonDisabled={data.selectedIds.length > 20 || data.selectedIds.length === 0} + > + + { + data.isModalOpen + && ( + + { + data.notification && + } + onSelectMethod(selectedItems, cellType, checked)} + selectedIds={data.selectedIds} + /> + + ) + } + + + ); + + /** Function to render the contents of the list. */ + const renderList = () => (data.rows && data.rows.length > 0 + ? ( +
+ onCellClickHandler(selectedRow)} + /> +
+ ) + : ( +
+ +
+ )); + + const renderAddButton = () => ( +
+ { + data.selectedIds.length > 0 && ( +
+ {__('Listing')} + {` ${data.selectedIds.length} `} + {__('Method(s)')} +
+ ) + } + +
+ ); + + const renderAccordionContents = () => ( + + + {renderAddButton()} + {renderList()} + + + ); + + return ( +
+ {renderAccordionContents()} + {renderModalSelector()} +
+ ); +}; + +export default AeInlineMethod; + +AeInlineMethod.propTypes = { + type: PropTypes.string.isRequired, + selected: PropTypes.arrayOf(PropTypes.any), +}; + +AeInlineMethod.defaultProps = { + selected: undefined, +}; diff --git a/app/javascript/components/AeInlineMethod/style.scss b/app/javascript/components/AeInlineMethod/style.scss new file mode 100644 index 00000000000..1c89e69cb43 --- /dev/null +++ b/app/javascript/components/AeInlineMethod/style.scss @@ -0,0 +1,79 @@ +.ae-inline-method-modal { + .bx--modal-content { + margin-bottom: 0; + } + + .inline-method-selector { + display: flex; + flex-direction: column; + min-height: 520px; + + .inline-filters { + display: flex; + flex-direction: row; + align-items: end; + gap: 10px; + + .search-wrapper { + display: flex; + flex-grow: 1; + flex-direction: column; + align-items: flex-start; + } + } + + .inline-contents-wrapper { + display: flex; + flex-direction: column; + margin-top: 20px; + + .miq-inline-method-list { + margin-top: 0; + + .bx--data-table-content { + margin-bottom: 0; + + .bx--data-table--sticky-header { + max-height: 25rem; + } + } + } + + .miq-notification-message-container { + margin: 0; + } + } + } +} + + +.miq-custom-form-accordion +{ + border: 1px solid #e0e0e0; + + li button.bx--accordion__heading { + background: #e0e0e0; + } + .bx--accordion__item:last-child{ + border: 0; + } + + .bx--accordion__content { + padding: 20px; + margin: 0; + + .custom-form-buttons { + display: flex; + justify-content: flex-end; + + .custom-form-buttons-label { + flex-grow: 1; + font-size: 14px; + } + } + + .ae-inline-methods-notification { + margin-top: 20px; + } + } +} diff --git a/app/javascript/components/miq-data-table/index.jsx b/app/javascript/components/miq-data-table/index.jsx index ee1d1603eb1..a9d1332861d 100644 --- a/app/javascript/components/miq-data-table/index.jsx +++ b/app/javascript/components/miq-data-table/index.jsx @@ -100,7 +100,9 @@ const MiqDataTable = ({ isSortable={isSortable} isSortHeader={sortHeader} sortDirection={sortDirection} - className={classNames('miq-data-table-header', (header.contentButton ? 'header-button' : ''))} + className={ + classNames('miq-data-table-header', (header.contentButton ? 'header-button' : ''), (header.actionCell ? 'action-cell-holder' : '')) + } > {headerLabel(header.header)} diff --git a/app/javascript/components/miq-data-table/miq-table-cell.jsx b/app/javascript/components/miq-data-table/miq-table-cell.jsx index 70ce994af6e..709c1e0d6fc 100644 --- a/app/javascript/components/miq-data-table/miq-table-cell.jsx +++ b/app/javascript/components/miq-data-table/miq-table-cell.jsx @@ -248,7 +248,7 @@ const MiqTableCell = ({ cellClick && onCellClick(row, CellAction.itemClick, event)} - className={classNames(showText ? '' : 'no_text', wrapClass ? 'vertical_align_top' : '')} + className={classNames(showText ? '' : 'no_text', wrapClass ? 'vertical_align_top' : '', cell.data.actionCell ? 'action-cell-holder' : '')} > {component} @@ -259,7 +259,9 @@ export default MiqTableCell; MiqTableCell.propTypes = { onCellClick: PropTypes.func, - row: PropTypes.shape({}), + row: PropTypes.shape({ + actionCell: PropTypes.bool, + }), cell: PropTypes.shape({ id: PropTypes.string, value: PropTypes.string, diff --git a/app/javascript/packs/component-definitions-common.js b/app/javascript/packs/component-definitions-common.js index 42171651cc1..5f44a3e43f3 100644 --- a/app/javascript/packs/component-definitions-common.js +++ b/app/javascript/packs/component-definitions-common.js @@ -11,6 +11,7 @@ import { Toolbar } from '../components/toolbar'; import ActionForm from '../components/action-form'; import AddRemoveHostAggregateForm from '../components/host-aggregate-form/add-remove-host-aggregate-form'; import AddRemoveSecurityGroupForm from '../components/vm-cloud-add-remove-security-group-form'; +import AeInlineMethod from '../components/AeInlineMethod'; import AggregateStatusCard from '../components/aggregate_status_card'; import AnsibleCredentialsForm from '../components/ansible-credentials-form'; import AnsiblePlayBookEditCatalogForm from '../components/ansible-playbook-edit-catalog-form'; @@ -186,6 +187,7 @@ ManageIQ.component.addReact('ActionForm', ActionForm); ManageIQ.component.addReact('AddRemoveHostAggregateForm', AddRemoveHostAggregateForm); ManageIQ.component.addReact('AddRemoveSecurityGroupForm', AddRemoveSecurityGroupForm); ManageIQ.component.addReact('AggregateStatusCard', AggregateStatusCard); +ManageIQ.component.addReact('AeInlineMethod', AeInlineMethod); ManageIQ.component.addReact('AnsibleCredentialsForm', AnsibleCredentialsForm); ManageIQ.component.addReact('AnsiblePlayBookEditCatalogForm', AnsiblePlayBookEditCatalogForm); ManageIQ.component.addReact('AnsiblePlaybookWorkflow', AnsiblePlaybookWorkflow); diff --git a/app/stylesheet/miq-data-table.scss b/app/stylesheet/miq-data-table.scss index 53a66b56761..2097fba9820 100644 --- a/app/stylesheet/miq-data-table.scss +++ b/app/stylesheet/miq-data-table.scss @@ -310,6 +310,10 @@ table.miq_preview { width: 100px !important; } +.action-cell-holder { + max-width: 150px !important; +} + .reconfigure-form { .reconfigure-sub-form { display: flex; diff --git a/app/views/miq_ae_class/_embedded_methods.html.haml b/app/views/miq_ae_class/_embedded_methods.html.haml index bfce9a82565..aae0a544bfd 100644 --- a/app/views/miq_ae_class/_embedded_methods.html.haml +++ b/app/views/miq_ae_class/_embedded_methods.html.haml @@ -3,33 +3,4 @@ = embedded_method_list(@record[:embedded_methods]) - else %hr - %h3 - = _('Embedded Methods') - #automate-inline-method-select{'ng-controller' => 'aeInlineMethodSelectionController as vm', 'ng-init' => "vm.selectable = {key: '^aem-(?!#{@selectable_methods}$)'};"} - .pull-right - %button.btn.btn-primary{:type => "button", - 'ng-click' => 'vm.openModal();', - :align => "left"}= _('Add Method') - .clearfix - :javascript - miq_bootstrap('#automate-inline-method-select'); - - if !@edit[:new][:embedded_methods].nil? && !@edit[:new][:embedded_methods].empty? - %table.table.table-striped.table-hover.table-condensed.table-bordered - %thead - %th= _('Path') - %th= _('Actions') - %tbody - - @edit[:new][:embedded_methods].try(:each_with_index) do |method, i| - %tr - %td - %text_field_tag - = _(method.to_s) - %td{:class => "action-cell"} - = link_to(_('Remove'), - {:action => "embedded_methods_remove", :id => i}, - {"data-miq_sparkle_on" => true, - "data-miq_sparkle_off" => true, - 'data-method' => :post, - :remote => true, - :class => "btn btn-default btn-block btn-sm", - :title => _("Click to delete this input field from method")}) + = react('AeInlineMethod', {:type => "aeInlineMethod", :selected => @embedded_methods}) diff --git a/config/routes.rb b/config/routes.rb index ee0a80aa46b..8f705708af1 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1907,6 +1907,9 @@ explorer method_form_fields namespace + ae_domains + ae_methods + ae_method_operations show ], :post => %w[ diff --git a/package.json b/package.json index edcf5fec2e1..abdd7b155d9 100644 --- a/package.json +++ b/package.json @@ -90,6 +90,7 @@ "react-codemirror2": "^6.0.0", "react-dom": "~16.13.1", "react-markdown": "6.0.0", + "react-query": "^3.39.3", "react-redux": "^7.1.1", "react-router": "~5.1.2", "react-router-dom": "~5.1.2", diff --git a/spec/config/routes.pending.yml b/spec/config/routes.pending.yml index 2ac9ca1ab9b..f89eba359f4 100644 --- a/spec/config/routes.pending.yml +++ b/spec/config/routes.pending.yml @@ -722,6 +722,9 @@ MiqActionController: - x_search_by_name - x_show MiqAeClassController: +- ae_domains +- ae_methods +- ae_method_operations - adv_search_button - adv_search_clear - adv_search_load_choice diff --git a/yarn.lock b/yarn.lock index 299ee640857..15ad7aa4433 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1282,9 +1282,9 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.0, @babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.16.7, @babel/runtime@npm:^7.19.4, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.6.3, @babel/runtime@npm:^7.8.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.9.1, @babel/runtime@npm:^7.9.2": - version: 7.24.7 - resolution: "@babel/runtime@npm:7.24.7" +"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.0, @babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.16.7, @babel/runtime@npm:^7.19.4, @babel/runtime@npm:^7.23.8, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.2, @babel/runtime@npm:^7.6.3, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.8.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.9.1, @babel/runtime@npm:^7.9.2": + version: 7.24.5 + resolution: "@babel/runtime@npm:7.24.5" dependencies: regenerator-runtime: "npm:^0.14.0" checksum: 10/7b77f566165dee62db3db0296e71d08cafda3f34e1b0dcefcd68427272e17c1704f4e4369bff76651b07b6e49d3ea5a0ce344818af9116e9292e4381e0918c76 @@ -1402,15 +1402,15 @@ __metadata: linkType: hard "@carbon/icon-helpers@npm:^10.28.4": - version: 10.49.1 - resolution: "@carbon/icon-helpers@npm:10.49.1" + version: 10.48.0 + resolution: "@carbon/icon-helpers@npm:10.48.0" dependencies: "@ibm/telemetry-js": "npm:^1.5.0" - checksum: 10/9e3615888d7ab89d3c049964ca9a8220c026e9c73467f2c43a510303fb6bef32e1033adca5ac838cad63d9b0da967ddbee8a25289ccdd1405870f5a9307f65a0 + checksum: 10/361b72df213c72f5f052a2da53bf3e673f92ee205404baa44e2a1d08d138d763f3660bc1fdc52f63345ed744bcb6d89568b54f4e129df8cb9cd3745e178930f2 languageName: node linkType: hard -"@carbon/icons-react@npm:^10.49.0, @carbon/icons-react@npm:^10.49.5, @carbon/icons-react@npm:~10.49.5": +"@carbon/icons-react@npm:^10.49.0, @carbon/icons-react@npm:^10.49.5, @carbon/icons-react@npm:~10.49.2": version: 10.49.5 resolution: "@carbon/icons-react@npm:10.49.5" dependencies: @@ -1450,7 +1450,7 @@ __metadata: languageName: node linkType: hard -"@carbon/themes@npm:~10.55.5": +"@carbon/themes@npm:~10.55.3": version: 10.55.5 resolution: "@carbon/themes@npm:10.55.5" dependencies: @@ -1640,11 +1640,11 @@ __metadata: linkType: hard "@ibm/telemetry-js@npm:^1.5.0": - version: 1.5.2 - resolution: "@ibm/telemetry-js@npm:1.5.2" + version: 1.5.1 + resolution: "@ibm/telemetry-js@npm:1.5.1" bin: ibmtelemetry: dist/collect.js - checksum: 10/1dcc971e78a927baba382a7179f75bc2b6fb1b237d8e9e88941c6410810e716a862e9135c709887a245daaf0e3e158ac3d01bf7e830457933ec91afffc479146 + checksum: 10/af59db5c01c7786c0a999e36e68f2928572e328549b4607dc57a706f1cdb2c3d8f00fa5e4bbcb7200f909982146aa0cde79b30544c35a382bfbab667f561d4b9 languageName: node linkType: hard @@ -2576,11 +2576,11 @@ __metadata: linkType: hard "@types/node@npm:*": - version: 20.14.8 - resolution: "@types/node@npm:20.14.8" + version: 20.12.12 + resolution: "@types/node@npm:20.12.12" dependencies: undici-types: "npm:~5.26.4" - checksum: 10/73822f66f269ce865df7e2f586787ac7444bd1169fd265cbed1e851b72787f1170517c5b616e0308ec2fbc0934ec6403b0f28d4152acbb0486071aec41167d51 + checksum: 10/e3945da0a3017bdc1f88f15bdfb823f526b2a717bd58d4640082d6eb0bd2794b5c99bfb914b9e9324ec116dce36066990353ed1c777e8a7b0641f772575793c4 languageName: node linkType: hard @@ -2639,12 +2639,12 @@ __metadata: linkType: hard "@types/react@npm:*, @types/react@npm:>=16.9.11": - version: 18.3.3 - resolution: "@types/react@npm:18.3.3" + version: 18.3.2 + resolution: "@types/react@npm:18.3.2" dependencies: "@types/prop-types": "npm:*" csstype: "npm:^3.0.2" - checksum: 10/68e203b7f1f91d6cf21f33fc7af9d6d228035a26c83f514981e54aa3da695d0ec6af10c277c6336de1dd76c4adbe9563f3a21f80c4462000f41e5f370b46e96c + checksum: 10/a85eed82c1009dc9d979281d9ea1f5322255003de3378390f35d897b4bdaf1d34ea748636c03e9e9b4b7cc97c2f4582993d2d60e40846226ad497d97c7d8565a languageName: node linkType: hard @@ -4137,6 +4137,13 @@ __metadata: languageName: node linkType: hard +"big-integer@npm:^1.6.16": + version: 1.6.52 + resolution: "big-integer@npm:1.6.52" + checksum: 10/4bc6ae152a96edc9f95020f5fc66b13d26a9ad9a021225a9f0213f7e3dc44269f423aa8c42e19d6ac4a63bb2b22140b95d10be8f9ca7a6d9aa1b22b330d1f514 + languageName: node + linkType: hard + "big.js@npm:^3.1.3": version: 3.2.0 resolution: "big.js@npm:3.2.0" @@ -4393,6 +4400,22 @@ __metadata: languageName: node linkType: hard +"broadcast-channel@npm:^3.4.1": + version: 3.7.0 + resolution: "broadcast-channel@npm:3.7.0" + dependencies: + "@babel/runtime": "npm:^7.7.2" + detect-node: "npm:^2.1.0" + js-sha3: "npm:0.8.0" + microseconds: "npm:0.2.0" + nano-time: "npm:1.0.0" + oblivious-set: "npm:1.0.0" + rimraf: "npm:3.0.2" + unload: "npm:2.2.0" + checksum: 10/ccf6be63c5ed03965f00c28f2cc55028ca3d6eb6f47cb430cc7a5e1ed404c54601c32bc87db24d11f229c80201fd2e606f5c9683543875a7e26ca06e23079782 + languageName: node + linkType: hard + "brorand@npm:^1.0.1, brorand@npm:^1.1.0": version: 1.1.0 resolution: "brorand@npm:1.1.0" @@ -4741,10 +4764,10 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.30000981, caniuse-lite@npm:^1.0.30001109, caniuse-lite@npm:^1.0.30001629": - version: 1.0.30001636 - resolution: "caniuse-lite@npm:1.0.30001636" - checksum: 10/9e6c5ab4c20df31df36720dda77cf6a781549ac2ad844bc0a416b327a793da21486358a1f85fdd6c39e22d336f70aac3b0e232f5f228cdff0ceb6e3e1c5e98fd +"caniuse-lite@npm:^1.0.30000981, caniuse-lite@npm:^1.0.30001109, caniuse-lite@npm:^1.0.30001587": + version: 1.0.30001620 + resolution: "caniuse-lite@npm:1.0.30001620" + checksum: 10/d615ab66eb14d9b621004297a8f61e435dca67e9311f3979e47ee1af1be2a8f14997b947a101073d949b5454dad745cc35134bc3c4295c7f33968f3f665eba19 languageName: node linkType: hard @@ -4757,9 +4780,9 @@ __metadata: languageName: node linkType: hard -"carbon-components-react@npm:~7.59.24": - version: 7.59.24 - resolution: "carbon-components-react@npm:7.59.24" +"carbon-components-react@npm:~7.59.17": + version: 7.59.23 + resolution: "carbon-components-react@npm:7.59.23" dependencies: "@babel/runtime": "npm:^7.16.7" "@carbon/feature-flags": "npm:^0.7.2" @@ -4785,7 +4808,7 @@ __metadata: carbon-icons: ^7.0.7 react: ^16.8.6 || ^17.0.1 react-dom: ^16.8.6 || ^17.0.1 - checksum: 10/8006fbfc21aa85e4212974c2437a2f16e40665b42cf70e24b86abb4ca6f24b714f077c5c4d401c3a99c26e77a89ed76ee4ae6ae27065eb45b89a2b5bb49350d2 + checksum: 10/a67edf67750876cbf5787202c73ba2e73180df2c1bb66940fec0c150e93c31c174979e704488f17dab9ba233394e80551a595e5672d9ac056c14e364df88c99e languageName: node linkType: hard @@ -4801,7 +4824,7 @@ __metadata: languageName: node linkType: hard -"carbon-components@npm:~10.58.15": +"carbon-components@npm:~10.58.12": version: 10.58.15 resolution: "carbon-components@npm:10.58.15" dependencies: @@ -6632,7 +6655,7 @@ __metadata: languageName: node linkType: hard -"detect-node@npm:^2.0.4": +"detect-node@npm:^2.0.4, detect-node@npm:^2.1.0": version: 2.1.0 resolution: "detect-node@npm:2.1.0" checksum: 10/832184ec458353e41533ac9c622f16c19f7c02d8b10c303dfd3a756f56be93e903616c0bb2d4226183c9351c15fc0b3dba41a17a2308262afabcfa3776e6ae6e @@ -6770,9 +6793,9 @@ __metadata: linkType: hard "dompurify@npm:^2.3.6": - version: 2.5.5 - resolution: "dompurify@npm:2.5.5" - checksum: 10/4429b9b22a0e67391c27b497b77d6417dd434b63e4d96de6470b6bc37faf2db8669a81aa05b012fbccb6c4ac694e7d8008204cf560b321cd23b97d79611cdc16 + version: 2.5.3 + resolution: "dompurify@npm:2.5.3" + checksum: 10/e5b4325e0b643bfd08c1d8500769d970924a1943b87976fb30c4e55d08bd7c3e7a09c1e1d1cb7f33425f72c1d643448c09e81209ef89a3e3fd01c4d713c94bc5 languageName: node linkType: hard @@ -6858,10 +6881,10 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.4.796": - version: 1.4.810 - resolution: "electron-to-chromium@npm:1.4.810" - checksum: 10/425de710336094330fd026cc2cfa0b383bfc9a49a2f575ceec2ac76198663ff95d0109bb45b243a43f0bf0f91a2e9c2768693a136d0968ae59728d5e8eea22ef +"electron-to-chromium@npm:^1.4.668": + version: 1.4.774 + resolution: "electron-to-chromium@npm:1.4.774" + checksum: 10/1424a1d4c89b498eaa02146ed89d79b3d9536b8c745753433b1f8b9ed12cc701aa3528e87a86c6c07ac4e35490dc1c44a3955408274a32d1446fbb56a0cffc2d languageName: node linkType: hard @@ -8673,18 +8696,17 @@ __metadata: linkType: hard "glob@npm:^10.2.2, glob@npm:^10.3.10": - version: 10.4.2 - resolution: "glob@npm:10.4.2" + version: 10.3.15 + resolution: "glob@npm:10.3.15" dependencies: foreground-child: "npm:^3.1.0" - jackspeak: "npm:^3.1.2" - minimatch: "npm:^9.0.4" - minipass: "npm:^7.1.2" - package-json-from-dist: "npm:^1.0.0" - path-scurry: "npm:^1.11.1" + jackspeak: "npm:^2.3.6" + minimatch: "npm:^9.0.1" + minipass: "npm:^7.0.4" + path-scurry: "npm:^1.11.0" bin: glob: dist/esm/bin.mjs - checksum: 10/e412776b5952a818eba790c830bea161c9a56813fd767d8c4c49f855603b1fb962b3e73f1f627a47298a57d2992b9f0f2fe15cf93e74ecaaa63fb45d63fdd090 + checksum: 10/b2b1c74309979b34fd6010afb50418a12525def32f1d3758d5827fc75d6143fc3ee5d1f3180a43111f6386c9e297c314f208d9d09955a6c6b69f22e92ee97635 languageName: node linkType: hard @@ -9308,9 +9330,9 @@ __metadata: linkType: hard "hyphenate-style-name@npm:^1.0.3": - version: 1.1.0 - resolution: "hyphenate-style-name@npm:1.1.0" - checksum: 10/b9ed74e29181d96bd58a2d0e62fc4a19879db591dba268275829ff0ae595fcdf11faafaeaa63330a45c3004664d7db1f0fc7cdb372af8ee4615ed8260302c207 + version: 1.0.5 + resolution: "hyphenate-style-name@npm:1.0.5" + checksum: 10/1eda2ea5bf6798cb16317edce62658791371b0e371bbf15c95f49f41c44a2c3fae42aec945be55bd1e453df13f377c20998952e1019393687f962eb42e46d6ab languageName: node linkType: hard @@ -10801,6 +10823,13 @@ __metadata: languageName: node linkType: hard +"js-sha3@npm:0.8.0": + version: 0.8.0 + resolution: "js-sha3@npm:0.8.0" + checksum: 10/a49ac6d3a6bfd7091472a28ab82a94c7fb8544cc584ee1906486536ba1cb4073a166f8c7bb2b0565eade23c5b3a7b8f7816231e0309ab5c549b737632377a20c + languageName: node + linkType: hard + "js-tokens@npm:^3.0.0 || ^4.0.0, js-tokens@npm:^4.0.0": version: 4.0.0 resolution: "js-tokens@npm:4.0.0" @@ -11762,6 +11791,7 @@ __metadata: react-codemirror2: "npm:^6.0.0" react-dom: "npm:~16.13.1" react-markdown: "npm:6.0.0" + react-query: "npm:^3.39.3" react-redux: "npm:^7.1.1" react-router: "npm:~5.1.2" react-router-dom: "npm:~5.1.2" @@ -11826,6 +11856,16 @@ __metadata: languageName: node linkType: hard +"match-sorter@npm:^6.0.2": + version: 6.3.4 + resolution: "match-sorter@npm:6.3.4" + dependencies: + "@babel/runtime": "npm:^7.23.8" + remove-accents: "npm:0.5.0" + checksum: 10/80b6cb04415b68b32cc7ec1242cc125f95ca6a8739a787dbc5e8058a120aaf5cb4ff8f8467b6f9949a8d8a6430a44d64659894d26138a03a8c0dd6ba239d5519 + languageName: node + linkType: hard + "mathml-tag-names@npm:^2.1.3": version: 2.1.3 resolution: "mathml-tag-names@npm:2.1.3" @@ -12021,6 +12061,13 @@ __metadata: languageName: node linkType: hard +"microseconds@npm:0.2.0": + version: 0.2.0 + resolution: "microseconds@npm:0.2.0" + checksum: 10/22bfa8553f92c7d95afff6de0aeb2aecf750680d41b8c72b02098ccc5bbbb0a384380ff539292dbd3788f5dfc298682f9d38a2b4c101f5ee2c9471d53934c5fa + languageName: node + linkType: hard + "miller-rabin@npm:^4.0.0": version: 4.0.1 resolution: "miller-rabin@npm:4.0.1" @@ -12209,10 +12256,10 @@ __metadata: languageName: node linkType: hard -"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.1.2": - version: 7.1.2 - resolution: "minipass@npm:7.1.2" - checksum: 10/c25f0ee8196d8e6036661104bacd743785b2599a21de5c516b32b3fa2b83113ac89a2358465bc04956baab37ffb956ae43be679b2262bf7be15fce467ccd7950 +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4": + version: 7.1.1 + resolution: "minipass@npm:7.1.1" + checksum: 10/6f4f920f1b5ea585d08fa3739b9bd81726cd85a0c972fb371c0fa6c1544d468813fb1694c7bc64ad81f138fd8abf665e2af0f406de9ba5741d8e4a377ed346b1 languageName: node linkType: hard @@ -12383,6 +12430,15 @@ __metadata: languageName: node linkType: hard +"nano-time@npm:1.0.0": + version: 1.0.0 + resolution: "nano-time@npm:1.0.0" + dependencies: + big-integer: "npm:^1.6.16" + checksum: 10/eef8548546cc1020625f8e44751a7263e9eddf0412a6a1a6c80a8d2be2ea7973622804a977cdfe796807b85b20ff6c8ba340e8dd20effcc7078193ed5edbb5d4 + languageName: node + linkType: hard + "nanoid@npm:^3.3.7": version: 3.3.7 resolution: "nanoid@npm:3.3.7" @@ -12845,6 +12901,13 @@ __metadata: languageName: node linkType: hard +"oblivious-set@npm:1.0.0": + version: 1.0.0 + resolution: "oblivious-set@npm:1.0.0" + checksum: 10/f31740ea9c3a8242ad2324e4ebb9a35359fbc2e6e7131731a0fc1c8b7b1238eb07e4c8c631a38535243a7b8e3042b7e89f7dc2a95d2989afd6f80bd5793b0aab + languageName: node + linkType: hard + "obuf@npm:^1.0.0, obuf@npm:^1.1.2": version: 1.1.2 resolution: "obuf@npm:1.1.2" @@ -13269,7 +13332,7 @@ __metadata: languageName: node linkType: hard -"path-scurry@npm:^1.11.1": +"path-scurry@npm:^1.11.0": version: 1.11.1 resolution: "path-scurry@npm:1.11.1" dependencies: @@ -14755,6 +14818,24 @@ __metadata: languageName: node linkType: hard +"react-query@npm:^3.39.3": + version: 3.39.3 + resolution: "react-query@npm:3.39.3" + dependencies: + "@babel/runtime": "npm:^7.5.5" + broadcast-channel: "npm:^3.4.1" + match-sorter: "npm:^6.0.2" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + checksum: 10/17dc4eb75d2ebc262b685096dfaa203202a883ac43768d0faf80f3ad4bdf791dff0691569d6e8ec2ac81b9377c5477e0a1ebea9f51bae1482ca154f5dde50d2d + languageName: node + linkType: hard + "react-redux@npm:^7.1.1": version: 7.2.9 resolution: "react-redux@npm:7.2.9" @@ -15215,6 +15296,13 @@ __metadata: languageName: node linkType: hard +"remove-accents@npm:0.5.0": + version: 0.5.0 + resolution: "remove-accents@npm:0.5.0" + checksum: 10/4aa1a9d0c18468515a33c6760b0f8e28dfbceddcb846fac90b2189445445b27b11cc1df9fbceb97b4449438bc13250d77b27d4ab325b2d69933acc156d6c5b50 + languageName: node + linkType: hard + "remove-trailing-separator@npm:^1.0.1": version: 1.1.0 resolution: "remove-trailing-separator@npm:1.1.0" @@ -15524,25 +15612,25 @@ __metadata: languageName: node linkType: hard -"rimraf@npm:^2.5.4, rimraf@npm:^2.6.3": - version: 2.7.1 - resolution: "rimraf@npm:2.7.1" +"rimraf@npm:3.0.2, rimraf@npm:^3.0.2": + version: 3.0.2 + resolution: "rimraf@npm:3.0.2" dependencies: glob: "npm:^7.1.3" bin: - rimraf: ./bin.js - checksum: 10/4586c296c736483e297da7cffd19475e4a3e41d07b1ae124aad5d687c79e4ffa716bdac8732ed1db942caf65271cee9dd39f8b639611de161a2753e2112ffe1d + rimraf: bin.js + checksum: 10/063ffaccaaaca2cfd0ef3beafb12d6a03dd7ff1260d752d62a6077b5dfff6ae81bea571f655bb6b589d366930ec1bdd285d40d560c0dae9b12f125e54eb743d5 languageName: node linkType: hard -"rimraf@npm:^3.0.2": - version: 3.0.2 - resolution: "rimraf@npm:3.0.2" +"rimraf@npm:^2.5.4, rimraf@npm:^2.6.3": + version: 2.7.1 + resolution: "rimraf@npm:2.7.1" dependencies: glob: "npm:^7.1.3" bin: - rimraf: bin.js - checksum: 10/063ffaccaaaca2cfd0ef3beafb12d6a03dd7ff1260d752d62a6077b5dfff6ae81bea571f655bb6b589d366930ec1bdd285d40d560c0dae9b12f125e54eb743d5 + rimraf: ./bin.js + checksum: 10/4586c296c736483e297da7cffd19475e4a3e41d07b1ae124aad5d687c79e4ffa716bdac8732ed1db942caf65271cee9dd39f8b639611de161a2753e2112ffe1d languageName: node linkType: hard @@ -17769,6 +17857,16 @@ __metadata: languageName: node linkType: hard +"unload@npm:2.2.0": + version: 2.2.0 + resolution: "unload@npm:2.2.0" + dependencies: + "@babel/runtime": "npm:^7.6.2" + detect-node: "npm:^2.0.4" + checksum: 10/382f676f24b774dc84beaf424326a227929ecad0ea0f319d4fd0812376b3306ea6d7ccf7ea85c6663ed7be552e9e004f429146bad8faf976b43084e29e265d10 + languageName: node + linkType: hard + "unpipe@npm:1.0.0, unpipe@npm:~1.0.0": version: 1.0.0 resolution: "unpipe@npm:1.0.0" @@ -17800,7 +17898,7 @@ __metadata: languageName: node linkType: hard -"update-browserslist-db@npm:^1.0.16": +"update-browserslist-db@npm:^1.0.13": version: 1.0.16 resolution: "update-browserslist-db@npm:1.0.16" dependencies: