From cea1cf804e0a4cea9baa7eafeb17b2278f055b8c Mon Sep 17 00:00:00 2001 From: Karl Tarvas Date: Wed, 4 Sep 2024 20:09:06 +0300 Subject: [PATCH] Hard integrate UI stories (#9220) * Add ui debug page controller * Add build time tooling to bundle stories * Add ui debug page frontend * Add missing types * Migrate all stories, refactor directory structure * Fix lint * Add changes --- .../src/com/suse/manager/webui/Router.java | 4 + .../controllers/StorybookController.java | 56 +++ .../webui/templates/storybook/storybook.jade | 10 + .../suse/manager/webui/utils/ViewHelper.java | 3 +- java/spacewalk-java.changes.eth.ui-debug | 1 + web/html/src/.eslintrc.js | 2 + .../build/plugins/generate-stories-plugin.js | 96 +++++ web/html/src/build/webpack.config.js | 31 +- web/html/src/components/CoCoScansList.tsx | 2 +- web/html/src/components/FormulaForm.tsx | 2 +- web/html/src/components/action-schedule.tsx | 2 +- .../components/action/ActionStatus.stories.md | 6 - .../action/ActionStatus.stories.tsx | 12 + web/html/src/components/buttons.stories.tsx | 56 +++ web/html/src/components/buttons.tsx | 22 +- web/html/src/components/combobox.tsx | 2 +- web/html/src/components/config-channels.tsx | 2 +- .../datetime/DateTimePicker.stories.md | 71 ---- .../datetime/DateTimePicker.stories.tsx | 84 ++++ .../components/datetime/FromNow.stories.md | 32 -- .../components/datetime/FromNow.stories.tsx | 35 ++ .../src/components/dialog/Dialog.stories.md | 63 --- .../dialog/action-confirm.stories.tsx | 41 ++ .../src/components/dialog/delete.stories.tsx | 27 ++ web/html/src/components/formula-selection.tsx | 2 +- web/html/src/components/icontag.tsx | 2 + .../src/components/input/Check.stories.md | 23 -- .../src/components/input/DateTime.stories.md | 27 -- web/html/src/components/input/Form.stories.md | 31 -- .../input/FormMultiInput.stories.md | 204 ---------- .../src/components/input/InputBase.test.tsx | 2 +- web/html/src/components/input/InputBase.tsx | 2 +- .../src/components/input/Password.stories.md | 31 -- .../src/components/input/Radio.stories.md | 149 ------- .../src/components/input/Range.stories.md | 31 -- .../src/components/input/Select.stories.md | 148 ------- web/html/src/components/input/Text.stories.md | 39 -- .../components/input/check/Check.stories.tsx | 25 ++ .../components/input/{ => check}/Check.tsx | 4 +- .../input/datetime/DateTime.stories.tsx | 29 ++ .../input/{ => datetime}/DateTime.tsx | 4 +- .../{ => form-multi-input}/FormMultiInput.tsx | 2 +- .../multiple-fields.stories.tsx | 70 ++++ .../form-multi-input/single-field.stories.tsx | 59 +++ .../form-multi-input/table-fields.stories.tsx | 79 ++++ .../components/input/form/Form.stories.tsx | 33 ++ .../src/components/input/{ => form}/Form.tsx | 2 +- web/html/src/components/input/index.ts | 18 +- .../input/password/Password.stories.tsx | 33 ++ .../input/{ => password}/Password.tsx | 4 +- .../input/{ => radio}/Radio.module.css | 0 .../components/input/{ => radio}/Radio.tsx | 4 +- .../input/radio/horizontal-open.stories.tsx | 41 ++ .../input/radio/horizontal.stories.tsx | 40 ++ .../input/radio/vertical-open.stories.tsx | 40 ++ .../input/radio/vertical.stories.tsx | 39 ++ .../components/input/range/Range.stories.tsx | 27 ++ .../input/{ => range}/Range.test.tsx | 2 +- .../components/input/{ => range}/Range.tsx | 4 +- .../input/{ => select}/Select.test.tsx | 2 +- .../components/input/{ => select}/Select.tsx | 4 +- .../components/input/select/async.stories.tsx | 54 +++ .../input/select/custom.stories.tsx | 66 ++++ .../{ => select}/select-test-attributes.tsx | 0 .../input/select/simple.stories.tsx | 36 ++ .../components/input/text/Text.stories.tsx | 41 ++ .../src/components/input/{ => text}/Text.tsx | 4 +- web/html/src/components/messages.stories.md | 22 -- .../components/{ => messages}/messages.tsx | 0 .../messages/severities.stories.tsx | 17 + .../components/messages/utilities.stories.tsx | 10 + .../package/PackageListActionScheduler.tsx | 2 +- .../panels/BootstrapPanel.stories.md | 7 - .../panels/BootstrapPanel.stories.tsx | 12 + .../src/components/panels/TopPanel.stories.md | 13 - .../components/panels/TopPanel.stories.tsx | 12 + .../picker/recurring-event-picker.tsx | 4 +- web/html/src/components/states-picker.tsx | 4 +- web/html/src/components/table/SearchField.tsx | 4 +- web/html/src/components/table/TableFilter.tsx | 2 +- .../src/components/toastr/toastr.stories.md | 9 - .../src/components/toastr/toastr.stories.tsx | 12 + web/html/src/components/tree/tree.stories.md | 60 --- web/html/src/components/tree/tree.stories.tsx | 57 +++ .../src/components/utils/HelpIcon.stories.md | 5 - .../src/components/utils/HelpIcon.stories.tsx | 5 + .../src/components/utils/HelpLink.stories.md | 5 - .../src/components/utils/HelpLink.stories.tsx | 5 + .../src/components/utils/Loading.stories.md | 23 -- web/html/src/components/utils/index.ts | 2 +- .../utils/{ => loading}/Loading.tsx | 0 .../utils/loading/simple.stories.tsx | 10 + .../utils/loading/text-border.stories.tsx | 10 + .../components/utils/loading/text.stories.tsx | 10 + .../api/use-mandatory-channels-api.ts | 2 +- web/html/src/core/debugUtils/index.ts | 14 +- web/html/src/core/spa/view-helper.ts | 1 + web/html/src/imports.d.ts | 1 + .../manager/admin/config/monitoring-admin.tsx | 2 +- .../admin/config/use-monitoring-api.ts | 2 +- .../admin/list-payg/list-payg.renderer.tsx | 2 +- .../src/manager/admin/list-payg/list-payg.tsx | 2 +- .../setup/products/products-scc-dialog.tsx | 2 +- .../manager/admin/setup/products/products.tsx | 4 +- .../admin/task-engine-status/taskotop.tsx | 2 +- .../src/manager/appstreams/appstreams.tsx | 2 +- .../src/manager/audit/cveaudit/cveaudit.tsx | 2 +- .../subscription-matching.tsx | 4 +- .../list-filters/filter-edit.tsx | 2 +- .../list-projects/list-projects.renderer.tsx | 2 +- .../list-projects/list-projects.tsx | 2 +- .../shared/components/messages/messages.tsx | 2 +- .../shared/components/panels/build/build.tsx | 8 +- .../environment-lifecycle.tsx | 4 +- .../filters-project-selection.tsx | 2 +- .../components/panels/promote/promote.tsx | 2 +- .../panels/properties/properties-edit.tsx | 2 +- .../sources/channels/channels-selection.tsx | 4 +- .../config-channels/group-config-channels.tsx | 2 +- web/html/src/manager/images/image-build.tsx | 10 +- web/html/src/manager/images/image-import.tsx | 10 +- .../src/manager/images/image-profile-edit.tsx | 8 +- .../src/manager/images/image-profiles.tsx | 2 +- .../src/manager/images/image-store-edit.tsx | 12 +- web/html/src/manager/images/image-stores.tsx | 2 +- .../manager/images/image-view-overview.tsx | 4 +- web/html/src/manager/images/image-view.tsx | 4 +- web/html/src/manager/index.ts | 13 +- web/html/src/manager/login/messages.tsx | 2 +- .../src/manager/login/susemanager/login.tsx | 2 +- web/html/src/manager/login/uyuni/login.tsx | 2 +- .../maintenance/calendar/web-calendar.tsx | 2 +- .../maintenance/details/calendar-details.tsx | 6 +- .../details/maintenance-windows-details.tsx | 2 +- .../maintenance/details/schedule-details.tsx | 4 +- .../maintenance/edit/calendar-edit.tsx | 8 +- .../maintenance/edit/schedule-edit.tsx | 8 +- .../maintenance/list/calendar-list.tsx | 4 +- .../maintenance/maintenance-windows.tsx | 4 +- .../maintenance/ssm/schedule-picker.tsx | 10 +- .../maintenance/ssm/system-assignment.tsx | 2 +- .../minion/ansible/accordion-path-content.tsx | 4 +- .../minion/ansible/ansible-control-node.tsx | 4 +- .../minion/ansible/ansible-path-content.tsx | 4 +- .../minion/ansible/schedule-playbook.tsx | 4 +- .../src/manager/minion/coco/coco-settings.tsx | 2 +- .../minion-config-channels.tsx | 2 +- .../minion/packages/package-states.tsx | 2 +- .../packages/use-package-states.api.tsx | 2 +- .../minion/ptf/ptf-overview.renderer.tsx | 2 +- .../notifications/notification-messages.tsx | 2 +- .../config-channels/org-config-channels.tsx | 2 +- .../proxy/container-config-messages.tsx | 2 +- .../src/manager/proxy/container-config.tsx | 8 +- .../recurring/recurring-actions-details.tsx | 2 +- .../recurring/recurring-actions-edit.tsx | 2 +- .../recurring/recurring-actions-list.tsx | 2 +- .../manager/recurring/recurring-actions.tsx | 4 +- .../org-formula-catalog.renderer.tsx | 2 +- .../formula-catalog/org-formula-catalog.tsx | 2 +- web/html/src/manager/state/highstate.tsx | 4 +- web/html/src/manager/storybook/index.ts | 3 + .../src/manager/storybook/layout.module.less | 29 ++ web/html/src/manager/storybook/layout.tsx | 31 ++ .../manager/storybook/stories.generated.ts | 370 ++++++++++++++++++ web/html/src/manager/storybook/stories.ts | 5 + .../manager/storybook/storybook.module.less | 29 ++ .../manager/storybook/storybook.renderer.tsx | 16 + web/html/src/manager/storybook/storybook.tsx | 113 ++++++ .../activation-key-channels.tsx | 6 +- .../activation-keys-appstreams.tsx | 2 +- .../systems/activation-key/child-channels.tsx | 2 +- .../systems/bootstrap/bootstrap-minions.tsx | 2 +- .../src/manager/systems/coco/ssm-schedule.tsx | 2 +- .../src/manager/systems/coco/ssm-settings.tsx | 2 +- .../src/manager/systems/delete-system.tsx | 4 +- .../systems/details/mgr-server-info.tsx | 4 +- web/html/src/manager/systems/proxy.tsx | 4 +- .../systems/ssm/ssm-subscribe-channels.tsx | 4 +- .../subscribe-channels/subscribe-channels.tsx | 4 +- .../virtualhostmanager-details.tsx | 4 +- .../virtualhostmanager-edit.tsx | 10 +- .../virtualhostmanager/virtualhostmanager.tsx | 4 +- .../src/manager/virtualization/ActionApi.tsx | 4 +- .../virtualization/HypervisorCheck.tsx | 4 +- .../src/manager/virtualization/ListTab.tsx | 6 +- .../virtualization/guests/GuestProperties.tsx | 14 +- .../guests/console/MessagePopUp.tsx | 6 +- .../guests/create/guests-create.tsx | 4 +- .../guests/edit/guests-edit.tsx | 4 +- .../guests/list/MigrateDialog.tsx | 4 +- .../guests/properties/GuestDiskFields.tsx | 8 +- .../guests/properties/GuestDiskFileFields.tsx | 6 +- .../properties/GuestDiskVolumeFields.tsx | 6 +- .../guests/properties/GuestDisksPanel.tsx | 10 +- .../guests/properties/guest-nics-panel.tsx | 12 +- .../properties/guest-properties-form.tsx | 6 +- .../guest-properties-traditional.tsx | 6 +- .../guests/virtualization-domains-caps-api.ts | 2 +- .../virtualization-guest-definition-api.ts | 2 +- .../virtualization/nets/edit/nets-edit.tsx | 2 +- .../virtualization/nets/list/nets-list.tsx | 2 +- .../nets/network-properties.tsx | 18 +- .../nets/properties/DnsConfig.tsx | 8 +- .../nets/properties/IpConfig.tsx | 8 +- .../nets/properties/NetworkAddress.tsx | 2 +- .../nets/properties/VirtualPortFields.tsx | 6 +- .../virtualization/nets/properties/Vlans.tsx | 8 +- .../virtualization-network-definition-api.tsx | 4 +- .../nets/virtualization-network-devs-api.ts | 2 +- .../virtualization/pools/edit/pools-edit.tsx | 2 +- .../virtualization/pools/list/pools-list.tsx | 6 +- .../virtualization/pools/pool-properties.tsx | 18 +- .../virtualization-pool-definition-api.tsx | 4 +- .../pools/virtualization-pools-action-api.tsx | 2 +- .../virtualization-pools-capabilities-api.ts | 2 +- web/html/src/object.d.ts | 21 + web/html/src/tsconfig.json | 3 +- web/html/src/utils/network.ts | 2 +- web/spacewalk-web.changes.eth.ui-debug | 1 + 220 files changed, 2263 insertions(+), 1306 deletions(-) create mode 100644 java/code/src/com/suse/manager/webui/controllers/StorybookController.java create mode 100644 java/code/src/com/suse/manager/webui/templates/storybook/storybook.jade create mode 100644 java/spacewalk-java.changes.eth.ui-debug create mode 100644 web/html/src/build/plugins/generate-stories-plugin.js delete mode 100644 web/html/src/components/action/ActionStatus.stories.md create mode 100644 web/html/src/components/action/ActionStatus.stories.tsx create mode 100644 web/html/src/components/buttons.stories.tsx delete mode 100644 web/html/src/components/datetime/DateTimePicker.stories.md create mode 100644 web/html/src/components/datetime/DateTimePicker.stories.tsx delete mode 100644 web/html/src/components/datetime/FromNow.stories.md create mode 100644 web/html/src/components/datetime/FromNow.stories.tsx delete mode 100644 web/html/src/components/dialog/Dialog.stories.md create mode 100644 web/html/src/components/dialog/action-confirm.stories.tsx create mode 100644 web/html/src/components/dialog/delete.stories.tsx delete mode 100644 web/html/src/components/input/Check.stories.md delete mode 100644 web/html/src/components/input/DateTime.stories.md delete mode 100644 web/html/src/components/input/Form.stories.md delete mode 100644 web/html/src/components/input/FormMultiInput.stories.md delete mode 100644 web/html/src/components/input/Password.stories.md delete mode 100644 web/html/src/components/input/Radio.stories.md delete mode 100644 web/html/src/components/input/Range.stories.md delete mode 100644 web/html/src/components/input/Select.stories.md delete mode 100644 web/html/src/components/input/Text.stories.md create mode 100644 web/html/src/components/input/check/Check.stories.tsx rename web/html/src/components/input/{ => check}/Check.tsx (93%) create mode 100644 web/html/src/components/input/datetime/DateTime.stories.tsx rename web/html/src/components/input/{ => datetime}/DateTime.tsx (91%) rename web/html/src/components/input/{ => form-multi-input}/FormMultiInput.tsx (99%) create mode 100644 web/html/src/components/input/form-multi-input/multiple-fields.stories.tsx create mode 100644 web/html/src/components/input/form-multi-input/single-field.stories.tsx create mode 100644 web/html/src/components/input/form-multi-input/table-fields.stories.tsx create mode 100644 web/html/src/components/input/form/Form.stories.tsx rename web/html/src/components/input/{ => form}/Form.tsx (99%) create mode 100644 web/html/src/components/input/password/Password.stories.tsx rename web/html/src/components/input/{ => password}/Password.tsx (88%) rename web/html/src/components/input/{ => radio}/Radio.module.css (100%) rename web/html/src/components/input/{ => radio}/Radio.tsx (96%) create mode 100644 web/html/src/components/input/radio/horizontal-open.stories.tsx create mode 100644 web/html/src/components/input/radio/horizontal.stories.tsx create mode 100644 web/html/src/components/input/radio/vertical-open.stories.tsx create mode 100644 web/html/src/components/input/radio/vertical.stories.tsx create mode 100644 web/html/src/components/input/range/Range.stories.tsx rename web/html/src/components/input/{ => range}/Range.test.tsx (98%) rename web/html/src/components/input/{ => range}/Range.tsx (96%) rename web/html/src/components/input/{ => select}/Select.test.tsx (98%) rename web/html/src/components/input/{ => select}/Select.tsx (98%) create mode 100644 web/html/src/components/input/select/async.stories.tsx create mode 100644 web/html/src/components/input/select/custom.stories.tsx rename web/html/src/components/input/{ => select}/select-test-attributes.tsx (100%) create mode 100644 web/html/src/components/input/select/simple.stories.tsx create mode 100644 web/html/src/components/input/text/Text.stories.tsx rename web/html/src/components/input/{ => text}/Text.tsx (94%) delete mode 100644 web/html/src/components/messages.stories.md rename web/html/src/components/{ => messages}/messages.tsx (100%) create mode 100644 web/html/src/components/messages/severities.stories.tsx create mode 100644 web/html/src/components/messages/utilities.stories.tsx delete mode 100644 web/html/src/components/panels/BootstrapPanel.stories.md create mode 100644 web/html/src/components/panels/BootstrapPanel.stories.tsx delete mode 100644 web/html/src/components/panels/TopPanel.stories.md create mode 100644 web/html/src/components/panels/TopPanel.stories.tsx delete mode 100644 web/html/src/components/toastr/toastr.stories.md create mode 100644 web/html/src/components/toastr/toastr.stories.tsx delete mode 100644 web/html/src/components/tree/tree.stories.md create mode 100644 web/html/src/components/tree/tree.stories.tsx delete mode 100644 web/html/src/components/utils/HelpIcon.stories.md create mode 100644 web/html/src/components/utils/HelpIcon.stories.tsx delete mode 100644 web/html/src/components/utils/HelpLink.stories.md create mode 100644 web/html/src/components/utils/HelpLink.stories.tsx delete mode 100644 web/html/src/components/utils/Loading.stories.md rename web/html/src/components/utils/{ => loading}/Loading.tsx (100%) create mode 100644 web/html/src/components/utils/loading/simple.stories.tsx create mode 100644 web/html/src/components/utils/loading/text-border.stories.tsx create mode 100644 web/html/src/components/utils/loading/text.stories.tsx create mode 100644 web/html/src/manager/storybook/index.ts create mode 100644 web/html/src/manager/storybook/layout.module.less create mode 100644 web/html/src/manager/storybook/layout.tsx create mode 100644 web/html/src/manager/storybook/stories.generated.ts create mode 100644 web/html/src/manager/storybook/stories.ts create mode 100644 web/html/src/manager/storybook/storybook.module.less create mode 100644 web/html/src/manager/storybook/storybook.renderer.tsx create mode 100644 web/html/src/manager/storybook/storybook.tsx create mode 100644 web/html/src/object.d.ts create mode 100644 web/spacewalk-web.changes.eth.ui-debug diff --git a/java/code/src/com/suse/manager/webui/Router.java b/java/code/src/com/suse/manager/webui/Router.java index 19adc6f1a3ae..ffc0dd911478 100644 --- a/java/code/src/com/suse/manager/webui/Router.java +++ b/java/code/src/com/suse/manager/webui/Router.java @@ -59,6 +59,7 @@ import com.suse.manager.webui.controllers.SetController; import com.suse.manager.webui.controllers.SsmController; import com.suse.manager.webui.controllers.StatesAPI; +import com.suse.manager.webui.controllers.StorybookController; import com.suse.manager.webui.controllers.SubscriptionMatchingController; import com.suse.manager.webui.controllers.SystemsController; import com.suse.manager.webui.controllers.TaskoTop; @@ -249,6 +250,9 @@ public void init() { // Saltboot SaltbootController.initRoutes(); + // Storybook + StorybookController.initRoutes(jade); + // if the calls above opened Hibernate session, close it now HibernateFactory.closeSession(); } diff --git a/java/code/src/com/suse/manager/webui/controllers/StorybookController.java b/java/code/src/com/suse/manager/webui/controllers/StorybookController.java new file mode 100644 index 000000000000..2d6987fc6bae --- /dev/null +++ b/java/code/src/com/suse/manager/webui/controllers/StorybookController.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2024 SUSE LLC + * + * This software is licensed to you under the GNU General Public License, + * version 2 (GPLv2). There is NO WARRANTY for this software, express or + * implied, including the implied warranties of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 + * along with this software; if not, see + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. + * + * Red Hat trademarks are not licensed under GPLv2. No permission is + * granted to use or replicate Red Hat trademarks that are incorporated + * in this software or its documentation. + */ + +package com.suse.manager.webui.controllers; + +import static com.suse.manager.webui.utils.SparkApplicationHelper.withCsrfToken; +import static com.suse.manager.webui.utils.SparkApplicationHelper.withUser; +import static com.suse.manager.webui.utils.SparkApplicationHelper.withUserPreferences; +import static spark.Spark.get; + +import com.redhat.rhn.domain.user.User; + +import java.util.HashMap; + +import spark.ModelAndView; +import spark.Request; +import spark.Response; +import spark.template.jade.JadeTemplateEngine; + +public class StorybookController { + private StorybookController() { } + + /** + * Initialize routes + * + * @param jade the Jade engine to use to render the pages + */ + public static void initRoutes(JadeTemplateEngine jade) { + get("/manager/storybook", + withUserPreferences(withCsrfToken(withUser(StorybookController::view))), jade); + } + + /** + * Returns the ui debug page + * + * @param req the request object + * @param res the response object + * @param user the authorized user + * @return the model and view + */ + public static ModelAndView view(Request req, Response res, User user) { + return new ModelAndView(new HashMap(), "templates/storybook/storybook.jade"); + } +} diff --git a/java/code/src/com/suse/manager/webui/templates/storybook/storybook.jade b/java/code/src/com/suse/manager/webui/templates/storybook/storybook.jade new file mode 100644 index 000000000000..80df7429d425 --- /dev/null +++ b/java/code/src/com/suse/manager/webui/templates/storybook/storybook.jade @@ -0,0 +1,10 @@ +include ../common.jade + +#storybook + +script(type='text/javascript'). + window.csrfToken = "#{csrf_token}"; + +script(type='text/javascript'). + spaImportReactPage('storybook') + .then(function(module) { module.renderer('storybook') }); diff --git a/java/code/src/com/suse/manager/webui/utils/ViewHelper.java b/java/code/src/com/suse/manager/webui/utils/ViewHelper.java index 725e0cfd962c..bf197a37fbdb 100644 --- a/java/code/src/com/suse/manager/webui/utils/ViewHelper.java +++ b/java/code/src/com/suse/manager/webui/utils/ViewHelper.java @@ -110,7 +110,8 @@ public enum ViewHelper { "/rhn/errata/manage/CloneErrata.do", "/rhn/admin/setup/ProxySettings.do", "/rhn/admin/setup/MirrorCredentials.do", - "/rhn/manager/admin/setup/payg" + "/rhn/manager/admin/setup/payg", + "/rhn/manager/storybook" ); ViewHelper() { } diff --git a/java/spacewalk-java.changes.eth.ui-debug b/java/spacewalk-java.changes.eth.ui-debug new file mode 100644 index 000000000000..d03887491585 --- /dev/null +++ b/java/spacewalk-java.changes.eth.ui-debug @@ -0,0 +1 @@ +- Integrate ui debugging stories diff --git a/web/html/src/.eslintrc.js b/web/html/src/.eslintrc.js index 7773946cdcc4..a83436f5a002 100644 --- a/web/html/src/.eslintrc.js +++ b/web/html/src/.eslintrc.js @@ -70,6 +70,8 @@ module.exports = { }, ], "sort-imports": "off", + // We use a `DEPRECATED_` prefix for old components that doesn't conform with this rule + "react/jsx-pascal-case": "off", ...(process.env.NODE_ENV === "production" ? productionRules : {}), }, diff --git a/web/html/src/build/plugins/generate-stories-plugin.js b/web/html/src/build/plugins/generate-stories-plugin.js new file mode 100644 index 000000000000..425aeb6caa9f --- /dev/null +++ b/web/html/src/build/plugins/generate-stories-plugin.js @@ -0,0 +1,96 @@ +const fs = require("fs").promises; +const path = require("path"); + +/** Automatically gather all imports for story files */ +module.exports = class GenerateStoriesPlugin { + didApply = false; + outputFile = undefined; + + constructor({ outputFile }) { + if (!outputFile) { + throw new Error("GenerateStoriesPlugin: `outputFile` is not set"); + } + this.outputFile = outputFile; + } + + /** + * @param {import("webpack").Compiler} compiler + */ + apply(compiler) { + // See https://webpack.js.org/api/compiler-hooks/#hooks + compiler.hooks.watchRun.tapAsync("GenerateStoriesPlugin", async (params, callback) => + this.beforeOrWatchRun(params, callback) + ); + compiler.hooks.beforeRun.tapAsync("GenerateStoriesPlugin", async (params, callback) => + this.beforeOrWatchRun(params, callback) + ); + } + + /** + * + * @param {import("webpack").Compiler} compiler + * @param {Function} callback + */ + async beforeOrWatchRun(compiler, callback) { + if (this.didApply) { + callback(); + return; + } + this.didApply = true; + + /** Source directory for the compilation, an absolute path to `/web/html/src` */ + const webHtmlSrc = compiler.context; + if (!this.outputFile.startsWith(webHtmlSrc)) { + throw new RangeError("GenerateStoriesPlugin: `outputFile` is outside of the source code directory"); + } + + const files = await fs.readdir(webHtmlSrc, { recursive: true }); + const storyFilePaths = files + .filter( + (item) => !item.startsWith("node_modules") && (item.endsWith(".stories.ts") || item.endsWith(".stories.tsx")) + ) + .sort(); + + const stories = storyFilePaths.map((filePath) => { + const safeName = this.wordify(filePath); + // We use the parent directory name as the group name + const groupName = path.dirname(filePath).split("/").pop() ?? "Unknown"; + return storyTemplate(filePath, safeName, groupName); + }); + + const output = fileTemplate(stories.join("")); + await fs.writeFile(this.outputFile, output, "utf-8"); + console.log(`GenerateStoriesPlugin: wrote ${storyFilePaths.length} stories to ${this.outputFile}`); + callback(); + } + + wordify(input) { + return input.replace(/[\W_]+/g, "_"); + } +}; + +const storyTemplate = (filePath, safeName, groupName) => + ` +import ${safeName}_component from "${filePath}"; +import ${safeName}_raw from "${filePath}?raw"; + +export const ${safeName} = { + path: "${filePath}", + title: "${path.basename(filePath)}", + groupName: "${groupName}", + component: ${safeName}_component, + raw: ${safeName}_raw, +}; +`; + +const fileTemplate = (content) => + ` +/** + * NB! This is a generated file! + * Any changes you make here will be lost. + * See: web/html/src/build/plugins/generate-stories-plugin.js + */ + +/* eslint-disable */ +${content} +`.trim(); diff --git a/web/html/src/build/webpack.config.js b/web/html/src/build/webpack.config.js index ad197445b9b4..8c1347e1de98 100644 --- a/web/html/src/build/webpack.config.js +++ b/web/html/src/build/webpack.config.js @@ -7,6 +7,8 @@ const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const SpeedMeasurePlugin = require("speed-measure-webpack-plugin"); const autoprefixer = require("autoprefixer"); +const GenerateStoriesPlugin = require("./plugins/generate-stories-plugin"); + const DEVSERVER_WEBSOCKET_PATHNAME = "/ws"; module.exports = (env, argv) => { @@ -82,6 +84,10 @@ module.exports = (env, argv) => { new MiniCssExtractPlugin({ chunkFilename: "css/[name].css", }), + new GenerateStoriesPlugin({ + inputDir: path.resolve(__dirname, "../manager"), + outputFile: path.resolve(__dirname, "../manager/storybook/stories.generated.ts"), + }), ]; if (isProductionMode) { @@ -118,15 +124,30 @@ module.exports = (env, argv) => { publicPath: "/", hashFunction: "md5", }, + // context: __dirname, + node: { + __filename: true, + __dirname: true, + }, devtool: isProductionMode ? "source-map" : "eval-source-map", module: { rules: [ { - test: /\.(ts|js)x?$/, - exclude: /node_modules/, - use: { - loader: "babel-loader", - }, + oneOf: [ + { + resourceQuery: /raw/, + type: "asset/source", + }, + { + test: /\.(ts|js)x?$/, + exclude: /node_modules/, + use: [ + { + loader: "babel-loader", + }, + ], + }, + ], }, { // Stylesheets that are imported directly by components diff --git a/web/html/src/components/CoCoScansList.tsx b/web/html/src/components/CoCoScansList.tsx index c10a1c57d632..ddbc3e16d16a 100644 --- a/web/html/src/components/CoCoScansList.tsx +++ b/web/html/src/components/CoCoScansList.tsx @@ -1,6 +1,6 @@ import * as React from "react"; -import { Messages, MessageType, Utils as MessagesUtils } from "components/messages"; +import { Messages, MessageType, Utils as MessagesUtils } from "components/messages/messages"; import { TopPanel } from "components/panels/TopPanel"; import { LocalizedMoment, localizedMoment } from "utils/datetime"; diff --git a/web/html/src/components/FormulaForm.tsx b/web/html/src/components/FormulaForm.tsx index f1613b69d36d..1a95660e13ae 100644 --- a/web/html/src/components/FormulaForm.tsx +++ b/web/html/src/components/FormulaForm.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import { Button } from "components/buttons"; -import { Messages, MessageType } from "components/messages"; +import { Messages, MessageType } from "components/messages/messages"; import { BootstrapPanel } from "components/panels/BootstrapPanel"; import { SectionToolbar } from "components/section-toolbar/section-toolbar"; diff --git a/web/html/src/components/action-schedule.tsx b/web/html/src/components/action-schedule.tsx index 8560cca3926a..832743c6b1e2 100644 --- a/web/html/src/components/action-schedule.tsx +++ b/web/html/src/components/action-schedule.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import { DateTimePicker } from "components/datetime"; -import { Loading } from "components/utils/Loading"; +import { Loading } from "components/utils/loading/Loading"; import { localizedMoment } from "utils"; import { DEPRECATED_unsafeEquals } from "utils/legacy"; diff --git a/web/html/src/components/action/ActionStatus.stories.md b/web/html/src/components/action/ActionStatus.stories.md deleted file mode 100644 index 2b523dcb7d94..000000000000 --- a/web/html/src/components/action/ActionStatus.stories.md +++ /dev/null @@ -1,6 +0,0 @@ -```jsx -, -, -, -, -``` diff --git a/web/html/src/components/action/ActionStatus.stories.tsx b/web/html/src/components/action/ActionStatus.stories.tsx new file mode 100644 index 000000000000..c30497966d34 --- /dev/null +++ b/web/html/src/components/action/ActionStatus.stories.tsx @@ -0,0 +1,12 @@ +import { ActionStatus } from "./ActionStatus"; + +export default () => { + return ( + <> + , + , + , + , + + ); +}; diff --git a/web/html/src/components/buttons.stories.tsx b/web/html/src/components/buttons.stories.tsx new file mode 100644 index 000000000000..bab59a1bb05d --- /dev/null +++ b/web/html/src/components/buttons.stories.tsx @@ -0,0 +1,56 @@ +import { StoryRow, StripedStorySection } from "manager/storybook/layout"; + +import { Button } from "components/buttons"; + +export default () => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +}; diff --git a/web/html/src/components/buttons.tsx b/web/html/src/components/buttons.tsx index f0d234d5ab70..a1f4be5633f5 100644 --- a/web/html/src/components/buttons.tsx +++ b/web/html/src/components/buttons.tsx @@ -8,6 +8,8 @@ import * as React from "react"; type BaseProps = { /** Text to display on the button. */ text?: React.ReactNode; + /** Text to display on the button. */ + children?: React.ReactNode; /** * FontAwesome icon class of the button. Can also include additional FA classes @@ -37,7 +39,8 @@ type BaseState = {}; */ class _ButtonBase

extends React.Component { renderIcon() { - const margin = this.props.text ? "" : " no-margin"; + const text = this.props.text ?? this.props.children; + const margin = text ? "" : " no-margin"; const icon = this.props.icon && ; return icon; @@ -124,7 +127,8 @@ export class AsyncButton extends _ButtonBase { style += " " + this.props.className; } - const margin = this.props.text ? "" : " no-margin"; + const text = this.props.text ?? this.props.children; + const margin = text ? "" : " no-margin"; return ( ); } @@ -154,6 +158,7 @@ export type ButtonProps = BaseProps & { */ export class Button extends _ButtonBase { render() { + const text = this.props.text ?? this.props.children; return ( ); } @@ -186,6 +191,7 @@ type LinkProps = BaseProps & { */ export class LinkButton extends _ButtonBase { render() { + const text = this.props.text ?? this.props.children; const targetProps: Partial> = this.props.target === "_blank" ? { @@ -205,7 +211,7 @@ export class LinkButton extends _ButtonBase { {...targetProps} > {this.renderIcon()} - {this.props.text} + {text} ); } @@ -216,10 +222,11 @@ export class LinkButton extends _ButtonBase { */ export class SubmitButton extends _ButtonBase { render() { + const text = this.props.text ?? this.props.children; return ( ); } @@ -240,6 +247,7 @@ type DropdownProps = BaseProps & { */ export class DropdownButton extends _ButtonBase { render() { + const text = this.props.text ?? this.props.children; return (

    {this.props.items.map((i) => ( diff --git a/web/html/src/components/combobox.tsx b/web/html/src/components/combobox.tsx index 50ff06c09e28..23de43a03d55 100644 --- a/web/html/src/components/combobox.tsx +++ b/web/html/src/components/combobox.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import Creatable from "react-select/creatable"; -import withTestAttributes from "./input/select-test-attributes"; +import withTestAttributes from "./input/select/select-test-attributes"; type ReactSelectItem = { value: string | null | undefined; diff --git a/web/html/src/components/config-channels.tsx b/web/html/src/components/config-channels.tsx index f788a8dd4b31..80e0b1bd3b67 100644 --- a/web/html/src/components/config-channels.tsx +++ b/web/html/src/components/config-channels.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import { StatesPicker } from "components/states-picker"; -import { Messages, MessageType } from "../components/messages"; +import { Messages, MessageType } from "./messages/messages"; type ConfigChannelsProps = { matchUrl: (filter?: string) => any; diff --git a/web/html/src/components/datetime/DateTimePicker.stories.md b/web/html/src/components/datetime/DateTimePicker.stories.md deleted file mode 100644 index d41770669cdc..000000000000 --- a/web/html/src/components/datetime/DateTimePicker.stories.md +++ /dev/null @@ -1,71 +0,0 @@ -This demo is mostly useful for debugging updates to the picker and ensuring all the values still line up correctly. - -```jsx -import { useState } from "react"; - -import moment from "moment"; - -import { localizedMoment } from "utils"; - -import { DEPRECATED_DateTimePicker } from "./DEPRECATED_DateTimePicker"; - -import { DateTimePicker } from "./DateTimePicker"; - -const [value, setValue] = useState(localizedMoment()); -const legacyId = "legacy"; - -const [newPickerValue, setNewPickerValue] = useState(localizedMoment()); -const newPickerLegacyId = "new-legacy"; - -
    -
    -

    old date time picker

    -

    - user time zone: {localizedMoment.userTimeZone.displayValue} ( - {localizedMoment(value).tz(localizedMoment.userTimeZone).format("Z")}) -

    -

    - server time zone: {localizedMoment.serverTimeZone.displayValue} ( - {localizedMoment(value).tz(localizedMoment.serverTimeZone).format("Z")}) -

    -

    - user time: - {localizedMoment(value).tz(localizedMoment.userTimeZone).toISOString(true)} -

    -

    - server time: - {localizedMoment(value).tz(localizedMoment.serverTimeZone).toISOString(true)} -

    -

    iso time: {value.toISOString()}

    - {/* eslint-disable-next-line local-rules/no-raw-date */} -

    browser time: {moment().toISOString(true)}

    -

    legacy id: "{legacyId}"

    - setValue(newValue)} legacyId={legacyId} /> -
    - -
    -

    new date time picker

    -

    - user time zone: {localizedMoment.userTimeZone.displayValue} ( - {localizedMoment(newPickerValue).tz(localizedMoment.userTimeZone).format("Z")}) -

    -

    - server time zone: {localizedMoment.serverTimeZone.displayValue} ( - {localizedMoment(newPickerValue).tz(localizedMoment.serverTimeZone).format("Z")}) -

    -

    - user time: - {localizedMoment(newPickerValue).tz(localizedMoment.userTimeZone).toISOString(true)} -

    -

    - server time: - {localizedMoment(newPickerValue).tz(localizedMoment.serverTimeZone).toISOString(true)} -

    -

    iso time: {newPickerValue.toISOString()}

    - {/* eslint-disable-next-line local-rules/no-raw-date */} -

    browser time: {moment().toISOString(true)}

    -

    legacy id: "{newPickerLegacyId}"

    - setNewPickerValue(newValue)} legacyId={newPickerLegacyId} /> -
    -
    -``` diff --git a/web/html/src/components/datetime/DateTimePicker.stories.tsx b/web/html/src/components/datetime/DateTimePicker.stories.tsx new file mode 100644 index 000000000000..48a6e8f15e47 --- /dev/null +++ b/web/html/src/components/datetime/DateTimePicker.stories.tsx @@ -0,0 +1,84 @@ +import { useState } from "react"; + +import moment from "moment"; + +import { localizedMoment } from "utils"; + +import { DateTimePicker } from "./DateTimePicker"; +import { DEPRECATED_DateTimePicker } from "./DEPRECATED_DateTimePicker"; + +export default () => { + const [value, setValue] = useState(localizedMoment()); + const legacyId = "legacy"; + + const [newPickerValue, setNewPickerValue] = useState(localizedMoment()); + const newPickerLegacyId = "new-legacy"; + + return ( + <> +

    + This demo is mostly useful for debugging updates to the picker and ensuring all the values still line up + correctly. +

    +
    +
    +

    + old date time picker +

    +

    + user time zone: {localizedMoment.userTimeZone} ( + {localizedMoment(value).tz(localizedMoment.userTimeZone).format("Z")}) +

    +

    + server time zone: {localizedMoment.serverTimeZone} ( + {localizedMoment(value).tz(localizedMoment.serverTimeZone).format("Z")}) +

    +

    + user time: + {localizedMoment(value).tz(localizedMoment.userTimeZone).toISOString(true)} +

    +

    + server time: + {localizedMoment(value).tz(localizedMoment.serverTimeZone).toISOString(true)} +

    +

    iso time: {value.toISOString()}

    + {/* eslint-disable-next-line local-rules/no-raw-date */} +

    browser time: {moment().toISOString(true)}

    +

    legacy id: "{legacyId}"

    + setValue(newValue)} legacyId={legacyId} /> +
    + +
    +

    + new date time picker +

    +

    + user time zone: {localizedMoment.userTimeZone} ( + {localizedMoment(newPickerValue).tz(localizedMoment.userTimeZone).format("Z")}) +

    +

    + server time zone: {localizedMoment.serverTimeZone} ( + {localizedMoment(newPickerValue).tz(localizedMoment.serverTimeZone).format("Z")}) +

    +

    + user time: + {localizedMoment(newPickerValue).tz(localizedMoment.userTimeZone).toISOString(true)} +

    +

    + server time: + {localizedMoment(newPickerValue).tz(localizedMoment.serverTimeZone).toISOString(true)} +

    +

    iso time: {newPickerValue.toISOString()}

    + {/* eslint-disable-next-line local-rules/no-raw-date */} +

    browser time: {moment().toISOString(true)}

    +

    legacy id: "{newPickerLegacyId}"

    + setNewPickerValue(newValue)} + legacyId={newPickerLegacyId} + /> +
    +
    + + ); +}; diff --git a/web/html/src/components/datetime/FromNow.stories.md b/web/html/src/components/datetime/FromNow.stories.md deleted file mode 100644 index 665a01f3d5df..000000000000 --- a/web/html/src/components/datetime/FromNow.stories.md +++ /dev/null @@ -1,32 +0,0 @@ -```jsx -import { useState } from "react"; - -import { localizedMoment } from "utils"; - -import { fromNow, FromNow } from "./FromNow"; -import { DateTimePicker } from "./DateTimePicker"; - -const [value, setValue] = useState(localizedMoment()); - -
    -

    value:

    -

    - setValue(newValue)} /> -

    - -

    fromNow function

    -

    -

    {fromNow(value)}
    -

    - -

    FromNow component with prop value

    -

    - -

    - -

    FromNow component with child value

    -

    - {value} -

    -
    -``` diff --git a/web/html/src/components/datetime/FromNow.stories.tsx b/web/html/src/components/datetime/FromNow.stories.tsx new file mode 100644 index 000000000000..2cc8fe6bf405 --- /dev/null +++ b/web/html/src/components/datetime/FromNow.stories.tsx @@ -0,0 +1,35 @@ +import { useState } from "react"; + +import { StorySection } from "manager/storybook/layout"; + +import { localizedMoment } from "utils"; + +import { DateTimePicker } from "./DateTimePicker"; +import { FromNow, fromNow } from "./FromNow"; + +export default () => { + const [value, setValue] = useState(localizedMoment()); + + return ( + +

    value:

    +
    + setValue(newValue)} /> +
    + +

    + fromNow function +

    +

    + {fromNow(value)} +

    + +

    + FromNow component with prop value +

    +

    + +

    +
    + ); +}; diff --git a/web/html/src/components/dialog/Dialog.stories.md b/web/html/src/components/dialog/Dialog.stories.md deleted file mode 100644 index 8be98ff784ca..000000000000 --- a/web/html/src/components/dialog/Dialog.stories.md +++ /dev/null @@ -1,63 +0,0 @@ -Delete dialog: - -```jsx -import { DeleteDialog } from "./DeleteDialog"; -import { ModalLink } from "./ModalLink"; - -
    -
    - -
    - - {t("Are you sure you want to delete project ")} - {"CLM2"} - - } - onConfirm={() => alert("deleted pressed")} - onClosePopUp={() => alert("modal closed")} - /> -
    -``` - -Action confirmation dialog: - -```jsx -import * as React from "react"; - -import { Button } from "../buttons"; -import { ActionConfirm } from "./ActionConfirm"; - -const [open, setOpen] = React.useState(false); -const items = [{ name: "Item 1" }, { name: "Item 2" }, { name: "Item 3" }]; -const doAction = (type, toAct, params) => { - const names = toAct.map((obj) => obj.name).join(); - alert(`doAction: ${type}, ${names}, force? ${params.force || false}`); -}; - -
    -
    -
    - setOpen(false)} - /> -
    -``` diff --git a/web/html/src/components/dialog/action-confirm.stories.tsx b/web/html/src/components/dialog/action-confirm.stories.tsx new file mode 100644 index 000000000000..2f29d46b4fe3 --- /dev/null +++ b/web/html/src/components/dialog/action-confirm.stories.tsx @@ -0,0 +1,41 @@ +import * as React from "react"; + +import { Button } from "../buttons"; +import { ActionConfirm } from "./ActionConfirm"; + +export default () => { + const [open, setOpen] = React.useState(false); + const items = [{ name: "Item 1" }, { name: "Item 2" }, { name: "Item 3" }]; + const doAction = (type, toAct, params) => { + const names = toAct.map((obj) => obj.name).join(); + alert(`doAction: ${type}, ${names}, force? ${params.force || false}`); + }; + + return ( + <> +

    Action confirmation dialog:

    +
    +
    +
    + setOpen(false)} + /> +
    + + ); +}; diff --git a/web/html/src/components/dialog/delete.stories.tsx b/web/html/src/components/dialog/delete.stories.tsx new file mode 100644 index 000000000000..4f3d82605cdc --- /dev/null +++ b/web/html/src/components/dialog/delete.stories.tsx @@ -0,0 +1,27 @@ +import { DeleteDialog } from "./DeleteDialog"; +import { ModalLink } from "./ModalLink"; + +export default () => { + return ( + <> +

    Delete dialog:

    +
    +
    + +
    + + {t("Are you sure you want to delete project ")} + {"CLM2"} + + } + onConfirm={() => alert("deleted pressed")} + onClosePopUp={() => alert("modal closed")} + /> +
    + + ); +}; diff --git a/web/html/src/components/formula-selection.tsx b/web/html/src/components/formula-selection.tsx index 54bf44de5dc2..3d1def74d260 100644 --- a/web/html/src/components/formula-selection.tsx +++ b/web/html/src/components/formula-selection.tsx @@ -6,8 +6,8 @@ import { Utils } from "utils/functions"; import { DEPRECATED_unsafeEquals } from "utils/legacy"; import { AsyncButton, Button } from "../components/buttons"; -import { Messages, MessageType } from "../components/messages"; import Network from "../utils/network"; +import { Messages, MessageType } from "./messages/messages"; const capitalize = Utils.capitalize; diff --git a/web/html/src/components/icontag.tsx b/web/html/src/components/icontag.tsx index 6fe074b9e3c6..5fb8d4caac80 100644 --- a/web/html/src/components/icontag.tsx +++ b/web/html/src/components/icontag.tsx @@ -6,6 +6,7 @@ type Props = { title?: string; }; +// See https://fontawesome.com/v4/icons/ function IconTag(props: Props) { const icons = { "action-failed": "fa fa-times-circle-o fa-1-5x text-danger", @@ -131,6 +132,7 @@ function IconTag(props: Props) { "system-virt-guest": "fa fa-1-5x spacewalk-icon-virtual-guest", "system-virt-host": "fa fa-1-5x spacewalk-icon-virtual-host", "system-warn": "fa fa-exclamation-triangle fa-1-5x text-warning", + experimental: "fa fa-flask", }; return ; diff --git a/web/html/src/components/input/Check.stories.md b/web/html/src/components/input/Check.stories.md deleted file mode 100644 index 3413e73809a1..000000000000 --- a/web/html/src/components/input/Check.stories.md +++ /dev/null @@ -1,23 +0,0 @@ -```jsx -import { SubmitButton } from "components/buttons"; - -import { Check } from "./Check"; -import { Form } from "./Form"; - -const model = { - booleanValue: false, -}; - -
    console.log(model)} - divClass="col-md-12" - formDirection="form-horizontal" - onChange={(newModel) => { - model["booleanValue"] = newModel["booleanValue"]; - }} -> - - - -``` diff --git a/web/html/src/components/input/DateTime.stories.md b/web/html/src/components/input/DateTime.stories.md deleted file mode 100644 index 39c0a091bb5b..000000000000 --- a/web/html/src/components/input/DateTime.stories.md +++ /dev/null @@ -1,27 +0,0 @@ -Dates and times are shown in the user's configured timezone. - -```jsx -import { SubmitButton } from "components/buttons"; - -import { localizedMoment } from "utils"; - -import { DateTime } from "./DateTime"; -import { Form } from "./Form"; - -const model = { - time: localizedMoment(), -}; - -
    { - model["time"] = newModel["time"]; - }} - onSubmit={() => console.log(model)} - divClass="col-md-12" - formDirection="form-horizontal" -> - - - -``` diff --git a/web/html/src/components/input/Form.stories.md b/web/html/src/components/input/Form.stories.md deleted file mode 100644 index 76c9ca2dd4de..000000000000 --- a/web/html/src/components/input/Form.stories.md +++ /dev/null @@ -1,31 +0,0 @@ -```jsx -import { SubmitButton } from "components/buttons"; - -import { Form } from "./Form"; -import { Text } from "./Text"; - -const model = { - name: "John", -}; - -
    { - model["name"] = newModel["name"]; - }} - onSubmit={() => console.log(model)} - divClass="col-md-12" - formDirection="form-horizontal" -> - value.length > 2]} - /> - - -``` diff --git a/web/html/src/components/input/FormMultiInput.stories.md b/web/html/src/components/input/FormMultiInput.stories.md deleted file mode 100644 index 4a59824f6086..000000000000 --- a/web/html/src/components/input/FormMultiInput.stories.md +++ /dev/null @@ -1,204 +0,0 @@ -Multiple fields: - -```jsx -import { useState } from "react"; - -import { SubmitButton } from "components/buttons"; - -import { Form } from "./Form"; -import { FormMultiInput } from "./FormMultiInput"; -import { Text } from "./Text"; - - -const [model, setModel] = useState({ user0_firstname: "John", user0_lastname: "Doe" }); - -
    console.log(result)} - divClass="col-md-12" - formDirection="form-horizontal" -> - { - const newModel = Object.assign({}, model, { - [`user${index}_firstname`]: "", - [`user${index}_lastname`]: "", - }); - setModel(newModel); - }} - onRemove={(index) => { - const newModel = Object.entries(model).reduce((res, entry) => { - const property = !entry[0].startsWith(`user${index}_`) ? { [entry[0]]: entry[1] } : undefined; - return Object.assign(res, property); - }, {}); - setModel(newModel); - }} - disabled={false} - panelTitle={(index) => model[`user${index}_lastname`] || "New user"} - > - {(index) => ( - <> - value.length > 2]} - /> - value.length > 2]} - /> - - )} - - - -``` - -Single field: - -```jsx -import { useState } from "react"; - -import { SubmitButton } from "components/buttons"; - -import { Form } from "./Form"; -import { FormMultiInput } from "./FormMultiInput"; -import { Text } from "./Text"; - - -const [model, setModel] = useState({ user0_login: "jdoe" }); - -
    console.log(result)} - divClass="col-md-12" - formDirection="form-horizontal" -> - { - const newModel = Object.assign({}, model, { - [`user${index}_login`]: "", - }); - setModel(newModel); - }} - onRemove={(index) => { - const newModel = Object.entries(model).reduce((res, entry) => { - const property = !entry[0].startsWith(`user${index}_`) ? { [entry[0]]: entry[1] } : undefined; - return Object.assign(res, property); - }, {}); - setModel(newModel); - }} - disabled={false} - > - {(index) => ( - <> - value.length > 2]} - /> - - )} - - - -``` - -As fields in a table: - -```jsx -import { useState } from "react"; - -import { SubmitButton } from "components/buttons"; - -import { Form } from "./Form"; -import { FormMultiInput } from "./FormMultiInput"; -import { Text } from "./Text"; - - -const [model, setModel] = useState({ user0_firstname: "John", user0_lastname: "Doe", user0_age: 42 }); - -const header = ( -
    -
    Firstname
    -
    Lastname
    -
    Age
    -
    -); - -
    console.log(result)} - divClass="col-md-12" - formDirection="form-horizontal" -> - { - const newModel = Object.assign({}, model, { - [`user${index}_firstname`]: "", - [`user${index}_lastname`]: "", - [`user${index}_age`]: "", - }); - setModel(newModel); - }} - onRemove={(index) => { - const newModel = Object.entries(model).reduce((res, entry) => { - const property = !entry[0].startsWith(`user${index}_`) ? { [entry[0]]: entry[1] } : undefined; - return Object.assign(res, property); - }, {}); - setModel(newModel); - }} - disabled={false} - header={header} - rowClass="multi-input-table-row" - > - {(index) => ( - <> - value.length > 2]} - className="col-md-4" - /> - value.length > 2]} - /> - - - )} - - - -``` diff --git a/web/html/src/components/input/InputBase.test.tsx b/web/html/src/components/input/InputBase.test.tsx index a0398e0c6a4a..0cfbf66d740f 100644 --- a/web/html/src/components/input/InputBase.test.tsx +++ b/web/html/src/components/input/InputBase.test.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import { render, screen } from "utils/test-utils"; -import { Form } from "./Form"; +import { Form } from "./form/Form"; import { InputBase } from "./InputBase"; describe("InputBase", () => { diff --git a/web/html/src/components/input/InputBase.tsx b/web/html/src/components/input/InputBase.tsx index 6dd2e31a5785..cf4f649cbca3 100644 --- a/web/html/src/components/input/InputBase.tsx +++ b/web/html/src/components/input/InputBase.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import _isNil from "lodash/isNil"; -import { FormContext } from "./Form"; +import { FormContext } from "./form/Form"; import { FormGroup } from "./FormGroup"; import { Label } from "./Label"; diff --git a/web/html/src/components/input/Password.stories.md b/web/html/src/components/input/Password.stories.md deleted file mode 100644 index 4200926355ce..000000000000 --- a/web/html/src/components/input/Password.stories.md +++ /dev/null @@ -1,31 +0,0 @@ -```jsx -import { SubmitButton } from "components/buttons"; - -import { Form } from "./Form"; -import { Password } from "./Password"; - -const model = { - password: "secret", -}; - -
    { - model["password"] = newModel["password"]; - }} - onSubmit={() => console.log(model)} - divClass="col-md-12" - formDirection="form-horizontal" -> - value.length > 4]} - /> - - -``` diff --git a/web/html/src/components/input/Radio.stories.md b/web/html/src/components/input/Radio.stories.md deleted file mode 100644 index b79a968be5e5..000000000000 --- a/web/html/src/components/input/Radio.stories.md +++ /dev/null @@ -1,149 +0,0 @@ -Vertical: - -```jsx -import { SubmitButton } from "components/buttons"; - -import { Form } from "./Form"; -import { Radio } from "./Radio"; - -const model = { - level: "beginner", -}; - -
    { - model["level"] = newModel["level"]; - }} - onSubmit={() => console.log(model)} - divClass="col-md-12" - formDirection="form-horizontal" -> - - - -``` - -Vertical with open option: -```jsx -import { SubmitButton } from "components/buttons"; - -import { Form } from "./Form"; -import { Radio } from "./Radio"; - -const model = { - level: "beginner", -}; - -
    { - model["level"] = newModel["level"]; - }} - onSubmit={() => console.log(model)} - divClass="col-md-12" - formDirection="form-horizontal" -> - - - -``` - -Horizontal: -```jsx -import { SubmitButton } from "components/buttons"; - -import { Form } from "./Form"; -import { Radio } from "./Radio"; - -const model = { - level: "beginner", -}; - -
    { - model["level"] = newModel["level"]; - }} - onSubmit={() => console.log(model)} - divClass="col-md-12" - formDirection="form-horizontal" -> - - - -``` - -Horizontal with open option: - -```jsx -import { SubmitButton } from "components/buttons"; - -import { Form } from "./Form"; -import { Radio } from "./Radio"; - -const model = { - level: "beginner", -}; - -
    { - model["level"] = newModel["level"]; - }} - onSubmit={() => console.log(model)} - divClass="col-md-12" - formDirection="form-horizontal" -> - - - -``` diff --git a/web/html/src/components/input/Range.stories.md b/web/html/src/components/input/Range.stories.md deleted file mode 100644 index ac8a4ef8e69d..000000000000 --- a/web/html/src/components/input/Range.stories.md +++ /dev/null @@ -1,31 +0,0 @@ -```jsx -import { SubmitButton } from "components/buttons"; - -import { Form } from "./Form"; -import { Range } from "./Range"; - -const model = { - port_start: "1000", - port_end: "1100", -}; - -
    { - model["port_start"] = newModel["port_start"]; - model["port_end"] = newModel["port_end"]; - }} - onSubmit={() => console.log(model)} - divClass="col-md-12" - formDirection="form-horizontal" -> - - - -``` diff --git a/web/html/src/components/input/Select.stories.md b/web/html/src/components/input/Select.stories.md deleted file mode 100644 index b5a91e5e5433..000000000000 --- a/web/html/src/components/input/Select.stories.md +++ /dev/null @@ -1,148 +0,0 @@ -A simple dropdown: - -```tsx -import { SubmitButton } from "components/buttons"; - -import { Form } from "./Form"; -import { Select } from "./Select"; - -const model = { - level: "beginner", -}; - -
    { - model["level"] = newModel["level"]; - }} - onSubmit={() => console.log(model)} - divClass="col-md-12" - formDirection="form-horizontal" -> - { - if (context === "menu") { - return
    {object.label}
    ; - } else { - const dotStyle = { - backgroundColor: object.color, - borderRadius: 10, - display: "block", - marginRight: 8, - height: 10, - width: 10, - }; - return ( -
    -
    -
    {object.label}
    -
    - ); - } - }} - required - /> -
    -
- -``` - -Async example. To show a prefilled value for async data, use the `defaultValueOption` option with a value that matches the expected schema. - -```jsx -import { SubmitButton } from "components/buttons"; - -import { Form } from "./Form"; -import { Select } from "./Select"; - -const model = { - level: 2, -}; - -const loadOptions = () => { - return new Promise((resolve) => { - setTimeout(() => { - resolve([ - { - value: 1, - label: "Level 1", - }, - { - value: 2, - label: "Level 2", - }, - ]); - }, 100); - }); -}; - -
{ - model["level"] = newModel["level"]; - }} - onSubmit={() => console.log(model)} - divClass="col-md-12" - formDirection="form-horizontal" -> - element */ diff --git a/web/html/src/components/input/datetime/DateTime.stories.tsx b/web/html/src/components/input/datetime/DateTime.stories.tsx new file mode 100644 index 000000000000..23b560a8ec3e --- /dev/null +++ b/web/html/src/components/input/datetime/DateTime.stories.tsx @@ -0,0 +1,29 @@ +import { SubmitButton } from "components/buttons"; + +import { localizedMoment } from "utils"; + +import { Form } from "../form/Form"; +import { DateTime } from "./DateTime"; + +export default () => { + const model = { time: localizedMoment() }; + + return ( + <> +

Dates and times are shown in the user's configured timezone.

+ + { + model["time"] = newModel["time"]; + }} + onSubmit={() => Loggerhead.info(model)} + divClass="col-md-12" + formDirection="form-horizontal" + > + + + + + ); +}; diff --git a/web/html/src/components/input/DateTime.tsx b/web/html/src/components/input/datetime/DateTime.tsx similarity index 91% rename from web/html/src/components/input/DateTime.tsx rename to web/html/src/components/input/datetime/DateTime.tsx index 97074abad1c5..b0270d86ffed 100644 --- a/web/html/src/components/input/DateTime.tsx +++ b/web/html/src/components/input/datetime/DateTime.tsx @@ -4,8 +4,8 @@ import { DateTimePicker } from "components/datetime"; import { localizedMoment } from "utils"; -import { FormContext } from "./Form"; -import { InputBase, InputBaseProps } from "./InputBase"; +import { FormContext } from "../form/Form"; +import { InputBase, InputBaseProps } from "../InputBase"; type Props = InputBaseProps & { /** name of the field to map in the form model */ diff --git a/web/html/src/components/input/FormMultiInput.tsx b/web/html/src/components/input/form-multi-input/FormMultiInput.tsx similarity index 99% rename from web/html/src/components/input/FormMultiInput.tsx rename to web/html/src/components/input/form-multi-input/FormMultiInput.tsx index 5180fa9f2d94..da2f66bd4d74 100644 --- a/web/html/src/components/input/FormMultiInput.tsx +++ b/web/html/src/components/input/form-multi-input/FormMultiInput.tsx @@ -4,7 +4,7 @@ import { Button } from "components/buttons"; import { Panel } from "components/panels/Panel"; import { PanelRow } from "components/panels/PanelRow"; -import { FormContext } from "./Form"; +import { FormContext } from "../form/Form"; type Props = { /** Id of the component */ diff --git a/web/html/src/components/input/form-multi-input/multiple-fields.stories.tsx b/web/html/src/components/input/form-multi-input/multiple-fields.stories.tsx new file mode 100644 index 000000000000..4030c118784d --- /dev/null +++ b/web/html/src/components/input/form-multi-input/multiple-fields.stories.tsx @@ -0,0 +1,70 @@ +import { useState } from "react"; + +import { SubmitButton } from "components/buttons"; + +import { Form } from "../form/Form"; +import { Text } from "../text/Text"; +import { FormMultiInput } from "./FormMultiInput"; + +export default () => { + const [model, setModel] = useState({ user0_firstname: "John", user0_lastname: "Doe" }); + + return ( + <> +

Multiple fields:

+
Loggerhead.info(result)} + divClass="col-md-12" + formDirection="form-horizontal" + > + { + const newModel = Object.assign({}, model, { + [`user${index}_firstname`]: "", + [`user${index}_lastname`]: "", + }); + setModel(newModel); + }} + onRemove={(index) => { + const newModel = Object.entries(model).reduce((res, entry) => { + const property = !entry[0].startsWith(`user${index}_`) ? { [entry[0]]: entry[1] } : undefined; + return Object.assign(res, property); + }, {} as typeof model); + setModel(newModel); + }} + disabled={false} + panelTitle={(index) => model[`user${index}_lastname`] || "New user"} + > + {(index) => ( + <> + value.length > 2]} + /> + value.length > 2]} + /> + + )} + + + + + ); +}; diff --git a/web/html/src/components/input/form-multi-input/single-field.stories.tsx b/web/html/src/components/input/form-multi-input/single-field.stories.tsx new file mode 100644 index 000000000000..2f0041252878 --- /dev/null +++ b/web/html/src/components/input/form-multi-input/single-field.stories.tsx @@ -0,0 +1,59 @@ +import { useState } from "react"; + +import { SubmitButton } from "components/buttons"; + +import { Form } from "../form/Form"; +import { Text } from "../text/Text"; +import { FormMultiInput } from "./FormMultiInput"; + +export default () => { + const [model, setModel] = useState({ user0_login: "jdoe" }); + + return ( + <> +

Single field:

+
Loggerhead.info(result)} + divClass="col-md-12" + formDirection="form-horizontal" + > + { + const newModel = Object.assign({}, model, { + [`user${index}_login`]: "", + }); + setModel(newModel); + }} + onRemove={(index) => { + const newModel = Object.entries(model).reduce((res, entry) => { + const property = !entry[0].startsWith(`user${index}_`) ? { [entry[0]]: entry[1] } : undefined; + return Object.assign(res, property); + }, {} as typeof model); + setModel(newModel); + }} + disabled={false} + > + {(index) => ( + <> + value.length > 2]} + /> + + )} + + + + + ); +}; diff --git a/web/html/src/components/input/form-multi-input/table-fields.stories.tsx b/web/html/src/components/input/form-multi-input/table-fields.stories.tsx new file mode 100644 index 000000000000..10b05b508866 --- /dev/null +++ b/web/html/src/components/input/form-multi-input/table-fields.stories.tsx @@ -0,0 +1,79 @@ +import { useState } from "react"; + +import { SubmitButton } from "components/buttons"; + +import { Form } from "../form/Form"; +import { Text } from "../text/Text"; +import { FormMultiInput } from "./FormMultiInput"; + +export default () => { + const [model, setModel] = useState({ user0_firstname: "John", user0_lastname: "Doe", user0_age: 42 }); + + const header = ( +
+
Firstname
+
Lastname
+
Age
+
+ ); + + return ( + <> +

As fields in a table:

+
Loggerhead.info(result)} + divClass="col-md-12" + formDirection="form-horizontal" + > + { + const newModel = Object.assign({}, model, { + [`user${index}_firstname`]: "", + [`user${index}_lastname`]: "", + [`user${index}_age`]: "", + }); + setModel(newModel); + }} + onRemove={(index) => { + const newModel = Object.entries(model).reduce((res, entry) => { + const property = !entry[0].startsWith(`user${index}_`) ? { [entry[0]]: entry[1] } : undefined; + return Object.assign(res, property); + }, {} as typeof model); + setModel(newModel); + }} + disabled={false} + header={header} + rowClass="multi-input-table-row" + > + {(index) => ( + <> + value.length > 2]} + className="col-md-4" + /> + value.length > 2]} + /> + + + )} + + + + + ); +}; diff --git a/web/html/src/components/input/form/Form.stories.tsx b/web/html/src/components/input/form/Form.stories.tsx new file mode 100644 index 000000000000..2520173ba537 --- /dev/null +++ b/web/html/src/components/input/form/Form.stories.tsx @@ -0,0 +1,33 @@ +import { SubmitButton } from "components/buttons"; + +import { Text } from "../text/Text"; +import { Form } from "./Form"; + +export default () => { + const model = { + name: "John", + }; + + return ( +
{ + model["name"] = newModel["name"]; + }} + onSubmit={() => Loggerhead.info(model)} + divClass="col-md-12" + formDirection="form-horizontal" + > + value.length > 2]} + /> + + + ); +}; diff --git a/web/html/src/components/input/Form.tsx b/web/html/src/components/input/form/Form.tsx similarity index 99% rename from web/html/src/components/input/Form.tsx rename to web/html/src/components/input/form/Form.tsx index 73ab54705ac2..a21180f56923 100644 --- a/web/html/src/components/input/Form.tsx +++ b/web/html/src/components/input/form/Form.tsx @@ -1,6 +1,6 @@ import * as React from "react"; -import { InputBase } from "./InputBase"; +import { InputBase } from "../InputBase"; type InputBaseRef = React.ElementRef; diff --git a/web/html/src/components/input/index.ts b/web/html/src/components/input/index.ts index 24d34233213a..89b30a695c2d 100644 --- a/web/html/src/components/input/index.ts +++ b/web/html/src/components/input/index.ts @@ -1,11 +1,11 @@ -export * from "./Check"; -export * from "./DateTime"; -export * from "./Form"; +export * from "./check/Check"; +export * from "./datetime/DateTime"; +export * from "./form/Form"; export * from "./FormGroup"; -export * from "./FormMultiInput"; +export * from "./form-multi-input/FormMultiInput"; export * from "./Label"; -export * from "./Password"; -export * from "./Radio"; -export * from "./Range"; -export * from "./Select"; -export * from "./Text"; +export * from "./password/Password"; +export * from "./radio/Radio"; +export * from "./range/Range"; +export * from "./select/Select"; +export * from "./text/Text"; diff --git a/web/html/src/components/input/password/Password.stories.tsx b/web/html/src/components/input/password/Password.stories.tsx new file mode 100644 index 000000000000..58f9efe602c3 --- /dev/null +++ b/web/html/src/components/input/password/Password.stories.tsx @@ -0,0 +1,33 @@ +import { SubmitButton } from "components/buttons"; + +import { Form } from "../form/Form"; +import { Password } from "./Password"; + +export default () => { + const model = { + password: "secret", + }; + + return ( +
{ + model["password"] = newModel["password"]; + }} + onSubmit={() => Loggerhead.info(model)} + divClass="col-md-12" + formDirection="form-horizontal" + > + value.length > 4]} + /> + + + ); +}; diff --git a/web/html/src/components/input/Password.tsx b/web/html/src/components/input/password/Password.tsx similarity index 88% rename from web/html/src/components/input/Password.tsx rename to web/html/src/components/input/password/Password.tsx index 5fecd2f4fd53..04427204af65 100644 --- a/web/html/src/components/input/Password.tsx +++ b/web/html/src/components/input/password/Password.tsx @@ -1,7 +1,7 @@ import * as React from "react"; -import { InputBaseProps } from "./InputBase"; -import { Text } from "./Text"; +import { InputBaseProps } from "../InputBase"; +import { Text } from "../text/Text"; type Props = InputBaseProps & { /** Value placeholder to display when no value is entered */ diff --git a/web/html/src/components/input/Radio.module.css b/web/html/src/components/input/radio/Radio.module.css similarity index 100% rename from web/html/src/components/input/Radio.module.css rename to web/html/src/components/input/radio/Radio.module.css diff --git a/web/html/src/components/input/Radio.tsx b/web/html/src/components/input/radio/Radio.tsx similarity index 96% rename from web/html/src/components/input/Radio.tsx rename to web/html/src/components/input/radio/Radio.tsx index 7b63040ea92f..a1d8446ad62d 100644 --- a/web/html/src/components/input/Radio.tsx +++ b/web/html/src/components/input/radio/Radio.tsx @@ -1,8 +1,8 @@ import * as React from "react"; import { useState } from "react"; -import { FormContext } from "./Form"; -import { InputBase, InputBaseProps } from "./InputBase"; +import { FormContext } from "../form/Form"; +import { InputBase, InputBaseProps } from "../InputBase"; import styles from "./Radio.module.css"; type Props = InputBaseProps & { diff --git a/web/html/src/components/input/radio/horizontal-open.stories.tsx b/web/html/src/components/input/radio/horizontal-open.stories.tsx new file mode 100644 index 000000000000..b7f8f992cf1f --- /dev/null +++ b/web/html/src/components/input/radio/horizontal-open.stories.tsx @@ -0,0 +1,41 @@ +import { SubmitButton } from "components/buttons"; + +import { Form } from "../form/Form"; +import { Radio } from "./Radio"; + +export default () => { + const model = { + level: "beginner", + }; + + return ( + <> +

Horizontal with open option:

+
{ + model["level"] = newModel["level"]; + }} + onSubmit={() => Loggerhead.info(model)} + divClass="col-md-12" + formDirection="form-horizontal" + > + + + + + ); +}; diff --git a/web/html/src/components/input/radio/horizontal.stories.tsx b/web/html/src/components/input/radio/horizontal.stories.tsx new file mode 100644 index 000000000000..613bbf2e4a51 --- /dev/null +++ b/web/html/src/components/input/radio/horizontal.stories.tsx @@ -0,0 +1,40 @@ +import { SubmitButton } from "components/buttons"; + +import { Form } from "../form/Form"; +import { Radio } from "./Radio"; + +export default () => { + const model = { + level: "beginner", + }; + + return ( + <> +

Horizontal:

+
{ + model["level"] = newModel["level"]; + }} + onSubmit={() => Loggerhead.info(model)} + divClass="col-md-12" + formDirection="form-horizontal" + > + + + + + ); +}; diff --git a/web/html/src/components/input/radio/vertical-open.stories.tsx b/web/html/src/components/input/radio/vertical-open.stories.tsx new file mode 100644 index 000000000000..7085db5166fd --- /dev/null +++ b/web/html/src/components/input/radio/vertical-open.stories.tsx @@ -0,0 +1,40 @@ +import { SubmitButton } from "components/buttons"; + +import { Form } from "../form/Form"; +import { Radio } from "./Radio"; + +export default () => { + const model = { + level: "beginner", + }; + + return ( + <> +

Vertical with open option:

+
{ + model["level"] = newModel["level"]; + }} + onSubmit={() => Loggerhead.info(model)} + divClass="col-md-12" + formDirection="form-horizontal" + > + + + + + ); +}; diff --git a/web/html/src/components/input/radio/vertical.stories.tsx b/web/html/src/components/input/radio/vertical.stories.tsx new file mode 100644 index 000000000000..10e7a64c94de --- /dev/null +++ b/web/html/src/components/input/radio/vertical.stories.tsx @@ -0,0 +1,39 @@ +import { SubmitButton } from "components/buttons"; + +import { Form } from "../form/Form"; +import { Radio } from "./Radio"; + +export default () => { + const model = { + level: "beginner", + }; + + return ( + <> +

Vertical:

+
{ + model["level"] = newModel["level"]; + }} + onSubmit={() => Loggerhead.info(model)} + divClass="col-md-12" + formDirection="form-horizontal" + > + + + + + ); +}; diff --git a/web/html/src/components/input/range/Range.stories.tsx b/web/html/src/components/input/range/Range.stories.tsx new file mode 100644 index 000000000000..5a1cc28cc424 --- /dev/null +++ b/web/html/src/components/input/range/Range.stories.tsx @@ -0,0 +1,27 @@ +import { SubmitButton } from "components/buttons"; + +import { Form } from "../form/Form"; +import { Range } from "./Range"; + +export default () => { + const model = { + port_start: "1000", + port_end: "1100", + }; + + return ( +
{ + model["port_start"] = newModel["port_start"]; + model["port_end"] = newModel["port_end"]; + }} + onSubmit={() => Loggerhead.info(model)} + divClass="col-md-12" + formDirection="form-horizontal" + > + + + + ); +}; diff --git a/web/html/src/components/input/Range.test.tsx b/web/html/src/components/input/range/Range.test.tsx similarity index 98% rename from web/html/src/components/input/Range.test.tsx rename to web/html/src/components/input/range/Range.test.tsx index 302eb1a4f667..fb6547fea05d 100644 --- a/web/html/src/components/input/Range.test.tsx +++ b/web/html/src/components/input/range/Range.test.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import { clear, render, screen, type, waitForElementToBeRemoved } from "utils/test-utils"; -import { Form } from "./Form"; +import { Form } from "../form/Form"; import { Range } from "./Range"; describe("Range", () => { diff --git a/web/html/src/components/input/Range.tsx b/web/html/src/components/input/range/Range.tsx similarity index 96% rename from web/html/src/components/input/Range.tsx rename to web/html/src/components/input/range/Range.tsx index cac8ada535ea..6cbee73df1f7 100644 --- a/web/html/src/components/input/Range.tsx +++ b/web/html/src/components/input/range/Range.tsx @@ -1,7 +1,7 @@ import * as React from "react"; -import { FormContext } from "./Form"; -import { InputBase, InputBaseProps } from "./InputBase"; +import { FormContext } from "../form/Form"; +import { InputBase, InputBaseProps } from "../InputBase"; type Props = InputBaseProps & { /** Value placeholder to display when no value is entered */ diff --git a/web/html/src/components/input/Select.test.tsx b/web/html/src/components/input/select/Select.test.tsx similarity index 98% rename from web/html/src/components/input/Select.test.tsx rename to web/html/src/components/input/select/Select.test.tsx index a9295769da33..5867d6ddccd0 100644 --- a/web/html/src/components/input/Select.test.tsx +++ b/web/html/src/components/input/select/Select.test.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import { clearFirst, getFieldValuesByName, openMenu, render, screen, select, type } from "utils/test-utils"; -import { Form } from "./Form"; +import { Form } from "../form/Form"; import { Select } from "./Select"; describe("Select", () => { diff --git a/web/html/src/components/input/Select.tsx b/web/html/src/components/input/select/Select.tsx similarity index 98% rename from web/html/src/components/input/Select.tsx rename to web/html/src/components/input/select/Select.tsx index f35795deb697..0b719b888aed 100644 --- a/web/html/src/components/input/Select.tsx +++ b/web/html/src/components/input/select/Select.tsx @@ -5,8 +5,8 @@ import ReactSelect from "react-select"; import AsyncSelect from "react-select/async"; import { AsyncPaginate as AsyncPaginateSelect } from "react-select-async-paginate"; -import { FormContext } from "./Form"; -import { InputBase, InputBaseProps } from "./InputBase"; +import { FormContext } from "../form/Form"; +import { InputBase, InputBaseProps } from "../InputBase"; import withTestAttributes from "./select-test-attributes"; type SingleMode = InputBaseProps & { diff --git a/web/html/src/components/input/select/async.stories.tsx b/web/html/src/components/input/select/async.stories.tsx new file mode 100644 index 000000000000..650195aeeead --- /dev/null +++ b/web/html/src/components/input/select/async.stories.tsx @@ -0,0 +1,54 @@ +import { Form } from "../form/Form"; +import { Select } from "./Select"; + +export default () => { + const model = { + level: 2, + }; + + const loadOptions = () => { + return new Promise((resolve) => { + setTimeout(() => { + resolve([ + { + value: 1, + label: "Level 1", + }, + { + value: 2, + label: "Level 2", + }, + ]); + }, 100); + }); + }; + + return ( + <> +

+ Async example. To show a prefilled value for async data, use the `defaultValueOption` option with a value that + matches the expected schema. +

+
{ + model["level"] = newModel["level"]; + }} + onSubmit={() => Loggerhead.info(model)} + divClass="col-md-12" + formDirection="form-horizontal" + > + { + if (context === "menu") { + return
{object.label}
; + } else { + const dotStyle = { + backgroundColor: object.color, + borderRadius: 10, + display: "block", + marginRight: 8, + height: 10, + width: 10, + }; + return ( +
+
+
{object.label}
+
+ ); + } + }} + required + /> +
+ + + + ); +}; diff --git a/web/html/src/components/input/select-test-attributes.tsx b/web/html/src/components/input/select/select-test-attributes.tsx similarity index 100% rename from web/html/src/components/input/select-test-attributes.tsx rename to web/html/src/components/input/select/select-test-attributes.tsx diff --git a/web/html/src/components/input/select/simple.stories.tsx b/web/html/src/components/input/select/simple.stories.tsx new file mode 100644 index 000000000000..ec95bb5dd748 --- /dev/null +++ b/web/html/src/components/input/select/simple.stories.tsx @@ -0,0 +1,36 @@ +import { SubmitButton } from "components/buttons"; + +import { Form } from "../form/Form"; +import { Select } from "./Select"; + +export default () => { + const model = { + level: "beginner", + }; + + return ( + <> +

A simple dropdown:

+ +
{ + model["level"] = newModel["level"]; + }} + onSubmit={() => Loggerhead.info(model)} + divClass="col-md-12" + formDirection="form-horizontal" + > + type */ diff --git a/web/html/src/components/messages.stories.md b/web/html/src/components/messages.stories.md deleted file mode 100644 index 412d60c44749..000000000000 --- a/web/html/src/components/messages.stories.md +++ /dev/null @@ -1,22 +0,0 @@ -Messages can have different types: - -```jsx -import { Messages } from "components/messages"; - - -``` - -Creating messages using helper utilities: - -```jsx -import { Messages, Utils } from "components/messages"; - - -``` diff --git a/web/html/src/components/messages.tsx b/web/html/src/components/messages/messages.tsx similarity index 100% rename from web/html/src/components/messages.tsx rename to web/html/src/components/messages/messages.tsx diff --git a/web/html/src/components/messages/severities.stories.tsx b/web/html/src/components/messages/severities.stories.tsx new file mode 100644 index 000000000000..d5c0c3895c4a --- /dev/null +++ b/web/html/src/components/messages/severities.stories.tsx @@ -0,0 +1,17 @@ +import { Messages } from "./messages"; + +export default () => { + return ( + <> +

Messages can have different types:

+ + + ); +}; diff --git a/web/html/src/components/messages/utilities.stories.tsx b/web/html/src/components/messages/utilities.stories.tsx new file mode 100644 index 000000000000..15cafd5d88f3 --- /dev/null +++ b/web/html/src/components/messages/utilities.stories.tsx @@ -0,0 +1,10 @@ +import { Messages, Utils } from "./messages"; + +export default () => { + return ( + <> +

Creating messages using helper utilities:

+ + + ); +}; diff --git a/web/html/src/components/package/PackageListActionScheduler.tsx b/web/html/src/components/package/PackageListActionScheduler.tsx index 56d2986ed561..e09bff43740d 100644 --- a/web/html/src/components/package/PackageListActionScheduler.tsx +++ b/web/html/src/components/package/PackageListActionScheduler.tsx @@ -3,7 +3,7 @@ import * as React from "react"; import { ActionChain, ActionSchedule } from "components/action-schedule"; import { AsyncButton, Button } from "components/buttons"; import { ActionChainLink, ActionLink } from "components/links"; -import { Messages, MessageType, Utils as MessagesUtils } from "components/messages"; +import { Messages, MessageType, Utils as MessagesUtils } from "components/messages/messages"; import { InnerPanel } from "components/panels/InnerPanel"; import { Column } from "components/table/Column"; import { SearchField } from "components/table/SearchField"; diff --git a/web/html/src/components/panels/BootstrapPanel.stories.md b/web/html/src/components/panels/BootstrapPanel.stories.md deleted file mode 100644 index 9136f24057af..000000000000 --- a/web/html/src/components/panels/BootstrapPanel.stories.md +++ /dev/null @@ -1,7 +0,0 @@ -With title: - -```jsx - - stuff - -``` diff --git a/web/html/src/components/panels/BootstrapPanel.stories.tsx b/web/html/src/components/panels/BootstrapPanel.stories.tsx new file mode 100644 index 000000000000..53849bc96229 --- /dev/null +++ b/web/html/src/components/panels/BootstrapPanel.stories.tsx @@ -0,0 +1,12 @@ +import { BootstrapPanel } from "./BootstrapPanel"; + +export default () => { + return ( + <> +

BootstrapPanel with title:

+ + stuff + + + ); +}; diff --git a/web/html/src/components/panels/TopPanel.stories.md b/web/html/src/components/panels/TopPanel.stories.md deleted file mode 100644 index 6b6a58571274..000000000000 --- a/web/html/src/components/panels/TopPanel.stories.md +++ /dev/null @@ -1,13 +0,0 @@ -With title: - -```jsx -stuff -``` - -With icon and help link: - -```jsx - - stuff - -``` diff --git a/web/html/src/components/panels/TopPanel.stories.tsx b/web/html/src/components/panels/TopPanel.stories.tsx new file mode 100644 index 000000000000..f5e6be8932d9 --- /dev/null +++ b/web/html/src/components/panels/TopPanel.stories.tsx @@ -0,0 +1,12 @@ +import { TopPanel } from "./TopPanel"; + +export default () => { + return ( + <> +

TopPanel with icon and help link:

+ + stuff + + + ); +}; diff --git a/web/html/src/components/picker/recurring-event-picker.tsx b/web/html/src/components/picker/recurring-event-picker.tsx index 59fcbbc665b1..ea5b5dd46fd6 100644 --- a/web/html/src/components/picker/recurring-event-picker.tsx +++ b/web/html/src/components/picker/recurring-event-picker.tsx @@ -1,8 +1,8 @@ import * as React from "react"; import { DateTimePicker } from "components/datetime"; -import { Form } from "components/input/Form"; -import { Text } from "components/input/Text"; +import { Form } from "components/input/form/Form"; +import { Text } from "components/input/text/Text"; import { localizedMoment } from "utils"; diff --git a/web/html/src/components/states-picker.tsx b/web/html/src/components/states-picker.tsx index 7c17acc3f575..795289fc21a8 100644 --- a/web/html/src/components/states-picker.tsx +++ b/web/html/src/components/states-picker.tsx @@ -18,8 +18,8 @@ import { Utils } from "utils/functions"; import Network from "../utils/network"; import { AsyncButton } from "./buttons"; import { TextField } from "./fields"; -import { Messages, MessageType } from "./messages"; -import { Utils as MessagesUtils } from "./messages"; +import { Messages, MessageType } from "./messages/messages"; +import { Utils as MessagesUtils } from "./messages/messages"; import { RankingTable } from "./ranking-table"; import { SaltStatePopup } from "./salt-state-popup"; import { Table } from "./table/Table"; diff --git a/web/html/src/components/table/SearchField.tsx b/web/html/src/components/table/SearchField.tsx index 642184f88eb0..cee8a8a6681e 100644 --- a/web/html/src/components/table/SearchField.tsx +++ b/web/html/src/components/table/SearchField.tsx @@ -1,7 +1,7 @@ import * as React from "react"; -import { Form } from "components/input/Form"; -import { Select } from "components/input/Select"; +import { Select } from "components/input"; +import { Form } from "components/input/form/Form"; type SearchFieldOption = { label: string; diff --git a/web/html/src/components/table/TableFilter.tsx b/web/html/src/components/table/TableFilter.tsx index 11a34b3c6327..4266831e2c96 100644 --- a/web/html/src/components/table/TableFilter.tsx +++ b/web/html/src/components/table/TableFilter.tsx @@ -1,7 +1,7 @@ import { useState } from "react"; import { Select } from "components/input"; -import { Form } from "components/input/Form"; +import { Form } from "components/input/form/Form"; import { SelectSearchField } from "components/table/SelectSearchField"; const renderSearchField = ({ filterOptions, field, criteria, onSearch, placeholder, name }) => { diff --git a/web/html/src/components/toastr/toastr.stories.md b/web/html/src/components/toastr/toastr.stories.md deleted file mode 100644 index e78af99e5db2..000000000000 --- a/web/html/src/components/toastr/toastr.stories.md +++ /dev/null @@ -1,9 +0,0 @@ -```jsx -import * as React from "react"; -import { showSuccessToastr } from "./toastr"; - - - - - -``` diff --git a/web/html/src/components/toastr/toastr.stories.tsx b/web/html/src/components/toastr/toastr.stories.tsx new file mode 100644 index 000000000000..6c9d751d0de3 --- /dev/null +++ b/web/html/src/components/toastr/toastr.stories.tsx @@ -0,0 +1,12 @@ +import * as React from "react"; + +import { MessagesContainer, showSuccessToastr } from "./toastr"; + +export default () => { + return ( + <> + + + + ); +}; diff --git a/web/html/src/components/tree/tree.stories.md b/web/html/src/components/tree/tree.stories.md deleted file mode 100644 index 8b9ab9edd07b..000000000000 --- a/web/html/src/components/tree/tree.stories.md +++ /dev/null @@ -1,60 +0,0 @@ -Simple data: - -```jsx -const simpleTreeData = { - rootId: "2", - items: [ - { id: "2", children: ["3", "4", "8"] }, - { id: "3", data: { key: "three", description: "I am #3" } }, - { id: "4", data: { key: "four", description: "I am #4" }, children: ["5", "6", "7"] }, - { id: "5", data: { key: "five", description: "I am #5" } }, - { id: "6", data: { key: "six", description: "I am #6" }, children: ["7"] }, - { id: "7", data: { key: "seven", description: "I am #7" } }, - { id: "8", data: { key: "eight", description: "I am #8" } }, - ], -}; -Simple Data} - data={simpleTreeData} - renderItem={(item, renderNameColumn) => { - return ( - <> - {renderNameColumn(<>Name Column: {item.data.key})} -
{item.data.description}
- - ); - }} -/> -``` - -Tree with selection and initially expanded: - -```jsx -const simpleTreeData = { - rootId: "2", - items: [ - { id: "2", children: ["3", "4", "8"] }, - { id: "3", data: { key: "three", description: "I am #3" } }, - { id: "4", data: { key: "four", description: "I am #4" }, children: ["5", "6", "7"] }, - { id: "5", data: { key: "five", description: "I am #5" } }, - { id: "6", data: { key: "six", description: "I am #6" }, children: ["7"] }, - { id: "7", data: { key: "seven", description: "I am #7" } }, - { id: "8", data: { key: "eight", description: "I am #8" } }, - ], -}; -Tree with selection and initially expanded} - data={simpleTreeData} - initiallyExpanded={["4"]} - initiallySelected={["6"]} - onItemSelectionChanged={(item, checked) => alert(`checkbox changed to ${checked} : ${JSON.stringify(item)}`)} - renderItem={(item, renderNameColumn) => { - return ( - <> - {renderNameColumn(<>Name Column: {item.data.key})} -
{item.data.description}
- - ); - }} -/> -``` diff --git a/web/html/src/components/tree/tree.stories.tsx b/web/html/src/components/tree/tree.stories.tsx new file mode 100644 index 000000000000..654964d5063f --- /dev/null +++ b/web/html/src/components/tree/tree.stories.tsx @@ -0,0 +1,57 @@ +import { StorySection } from "manager/storybook/layout"; + +import { Tree } from "./tree"; + +export default () => { + const simpleTreeData = { + rootId: "2", + items: [ + { id: "2", children: ["3", "4", "8"] }, + { id: "3", data: { key: "three", description: "I am #3" } }, + { id: "4", data: { key: "four", description: "I am #4" }, children: ["5", "6", "7"] }, + { id: "5", data: { key: "five", description: "I am #5" } }, + { id: "6", data: { key: "six", description: "I am #6" }, children: ["7"] }, + { id: "7", data: { key: "seven", description: "I am #7" } }, + { id: "8", data: { key: "eight", description: "I am #8" } }, + ], + }; + + return ( + <> +

Simple data:

+ + Simple Data} + data={simpleTreeData} + renderItem={(item, renderNameColumn) => { + return ( + <> + {renderNameColumn(<>Name Column: {item.data.key})} +
{item.data.description}
+ + ); + }} + /> +
+ +

Tree with selection and initially expanded:

+ + Tree with selection and initially expanded} + data={simpleTreeData} + initiallyExpanded={["4"]} + initiallySelected={["6"]} + onItemSelectionChanged={(item, checked) => alert(`checkbox changed to ${checked} : ${JSON.stringify(item)}`)} + renderItem={(item, renderNameColumn) => { + return ( + <> + {renderNameColumn(<>Name Column: {item.data.key})} +
{item.data.description}
+ + ); + }} + /> +
+ + ); +}; diff --git a/web/html/src/components/utils/HelpIcon.stories.md b/web/html/src/components/utils/HelpIcon.stories.md deleted file mode 100644 index 95b2ca91e55d..000000000000 --- a/web/html/src/components/utils/HelpIcon.stories.md +++ /dev/null @@ -1,5 +0,0 @@ -```jsx -import HelpIcon from "./HelpIcon"; - - -``` diff --git a/web/html/src/components/utils/HelpIcon.stories.tsx b/web/html/src/components/utils/HelpIcon.stories.tsx new file mode 100644 index 000000000000..6ea1d9b80b35 --- /dev/null +++ b/web/html/src/components/utils/HelpIcon.stories.tsx @@ -0,0 +1,5 @@ +import HelpIcon from "./HelpIcon"; + +export default () => { + return ; +}; diff --git a/web/html/src/components/utils/HelpLink.stories.md b/web/html/src/components/utils/HelpLink.stories.md deleted file mode 100644 index b0d48a0b7052..000000000000 --- a/web/html/src/components/utils/HelpLink.stories.md +++ /dev/null @@ -1,5 +0,0 @@ -```jsx -import { HelpLink } from "./HelpLink"; - - -``` diff --git a/web/html/src/components/utils/HelpLink.stories.tsx b/web/html/src/components/utils/HelpLink.stories.tsx new file mode 100644 index 000000000000..e5bbcf3221db --- /dev/null +++ b/web/html/src/components/utils/HelpLink.stories.tsx @@ -0,0 +1,5 @@ +import { HelpLink } from "./HelpLink"; + +export default () => { + return ; +}; diff --git a/web/html/src/components/utils/Loading.stories.md b/web/html/src/components/utils/Loading.stories.md deleted file mode 100644 index 82193366b881..000000000000 --- a/web/html/src/components/utils/Loading.stories.md +++ /dev/null @@ -1,23 +0,0 @@ -Loading indicator: - -```jsx -import { Loading } from "./Loading"; - -; -``` - -Loading indicator with text: - -```jsx -import { Loading } from "./Loading"; - - -``` - -Loading indicator with text and borders: - -```jsx -import { Loading } from "./Loading"; - - -``` diff --git a/web/html/src/components/utils/index.ts b/web/html/src/components/utils/index.ts index 9be7cf8aa199..7a24feb9dab5 100644 --- a/web/html/src/components/utils/index.ts +++ b/web/html/src/components/utils/index.ts @@ -1,4 +1,4 @@ export * from "./cloneReactElement"; export * from "./HelpIcon"; export * from "./HelpLink"; -export * from "./Loading"; +export * from "./loading/Loading"; diff --git a/web/html/src/components/utils/Loading.tsx b/web/html/src/components/utils/loading/Loading.tsx similarity index 100% rename from web/html/src/components/utils/Loading.tsx rename to web/html/src/components/utils/loading/Loading.tsx diff --git a/web/html/src/components/utils/loading/simple.stories.tsx b/web/html/src/components/utils/loading/simple.stories.tsx new file mode 100644 index 000000000000..00fec2a24bcc --- /dev/null +++ b/web/html/src/components/utils/loading/simple.stories.tsx @@ -0,0 +1,10 @@ +import { Loading } from "./Loading"; + +export default () => { + return ( + <> +

Loading indicator:

+ + + ); +}; diff --git a/web/html/src/components/utils/loading/text-border.stories.tsx b/web/html/src/components/utils/loading/text-border.stories.tsx new file mode 100644 index 000000000000..317eee5805f8 --- /dev/null +++ b/web/html/src/components/utils/loading/text-border.stories.tsx @@ -0,0 +1,10 @@ +import { Loading } from "./Loading"; + +export default () => { + return ( + <> +

Loading indicator with text and borders:

+ + + ); +}; diff --git a/web/html/src/components/utils/loading/text.stories.tsx b/web/html/src/components/utils/loading/text.stories.tsx new file mode 100644 index 000000000000..91a620231aa7 --- /dev/null +++ b/web/html/src/components/utils/loading/text.stories.tsx @@ -0,0 +1,10 @@ +import { Loading } from "./Loading"; + +export default () => { + return ( + <> +

Loading indicator with text:

+ + + ); +}; diff --git a/web/html/src/core/channels/api/use-mandatory-channels-api.ts b/web/html/src/core/channels/api/use-mandatory-channels-api.ts index 04e96c2a0054..50d9d21d6ec3 100644 --- a/web/html/src/core/channels/api/use-mandatory-channels-api.ts +++ b/web/html/src/core/channels/api/use-mandatory-channels-api.ts @@ -9,7 +9,7 @@ import { processChannelDependencies, } from "core/channels/utils/channels-dependencies.utils"; -import { MessageType } from "components/messages"; +import { MessageType } from "components/messages/messages"; import { JsonResult } from "utils/network"; import Network from "utils/network"; diff --git a/web/html/src/core/debugUtils/index.ts b/web/html/src/core/debugUtils/index.ts index 50d94b2563d6..aef5eaca9add 100644 --- a/web/html/src/core/debugUtils/index.ts +++ b/web/html/src/core/debugUtils/index.ts @@ -15,12 +15,12 @@ const debugUtils = { return `the theme is: ${oldTheme.getAttribute("href")} ${newTheme.getAttribute("href")}`; }, toggleTheme() { - // const oldWrapper = document.querySelector(".old-theme"); - // const newWrapper = document.querySelector(".new-theme"); - // oldWrapper?.classList.remove("old-theme"); - // oldWrapper?.classList.add("new-theme"); - // newWrapper?.classList.remove("new-theme"); - // newWrapper?.classList.add("old-theme"); + if (document.body.className.includes("theme-susemanager-")) { + document.body.className = document.body.className.replace("theme-susemanager-light", "theme-uyuni"); + document.body.className = document.body.className.replace("theme-susemanager-dark", "theme-uyuni"); + } else if (document.body.className.includes("theme-uyuni")) { + document.body.className = document.body.className.replace("theme-uyuni", "theme-susemanager-light"); + } const oldLightTheme = document.querySelector('link[href^="/css/susemanager-light"]'); const newLightTheme = document.querySelector('link[href^="/css/updated-susemanager-light"]'); @@ -88,4 +88,4 @@ declare global { } window.debugUtils = debugUtils; -export default {}; +export default debugUtils; diff --git a/web/html/src/core/spa/view-helper.ts b/web/html/src/core/spa/view-helper.ts index 948b73d798b3..3292a45e6bb8 100644 --- a/web/html/src/core/spa/view-helper.ts +++ b/web/html/src/core/spa/view-helper.ts @@ -57,6 +57,7 @@ const BOOTSTRAP_READY_PAGES: PathString[] = [ "/rhn/admin/setup/ProxySettings.do", "/rhn/admin/setup/MirrorCredentials.do", "/rhn/manager/admin/setup/payg", + "/rhn/manager/storybook", ]; export const onEndNavigate = () => { diff --git a/web/html/src/imports.d.ts b/web/html/src/imports.d.ts index 6176c11ac964..2305d5016c1c 100644 --- a/web/html/src/imports.d.ts +++ b/web/html/src/imports.d.ts @@ -1,3 +1,4 @@ declare module "*.css"; declare module "*.less"; declare module "*.svg"; +declare module "*?raw"; diff --git a/web/html/src/manager/admin/config/monitoring-admin.tsx b/web/html/src/manager/admin/config/monitoring-admin.tsx index 60454a1cb833..1e6a5f452981 100644 --- a/web/html/src/manager/admin/config/monitoring-admin.tsx +++ b/web/html/src/manager/admin/config/monitoring-admin.tsx @@ -8,7 +8,7 @@ import { docsLocale } from "core/user-preferences"; import { AsyncButton, Button } from "components/buttons"; import withPageWrapper from "components/general/with-page-wrapper"; import { IconTag as Icon } from "components/icontag"; -import { Messages, Utils as MessagesUtils } from "components/messages"; +import { Messages, Utils as MessagesUtils } from "components/messages/messages"; import { Panel } from "components/panels/Panel"; import { HelpLink } from "components/utils/HelpLink"; diff --git a/web/html/src/manager/admin/config/use-monitoring-api.ts b/web/html/src/manager/admin/config/use-monitoring-api.ts index c76b84a76574..d5adf1bc8c3c 100644 --- a/web/html/src/manager/admin/config/use-monitoring-api.ts +++ b/web/html/src/manager/admin/config/use-monitoring-api.ts @@ -1,6 +1,6 @@ import { useState } from "react"; -import { MessageType } from "components/messages"; +import { MessageType } from "components/messages/messages"; import Network, { JsonResult } from "utils/network"; diff --git a/web/html/src/manager/admin/list-payg/list-payg.renderer.tsx b/web/html/src/manager/admin/list-payg/list-payg.renderer.tsx index f738bc551ace..afe5d2234966 100644 --- a/web/html/src/manager/admin/list-payg/list-payg.renderer.tsx +++ b/web/html/src/manager/admin/list-payg/list-payg.renderer.tsx @@ -3,7 +3,7 @@ import * as React from "react"; import { RolesProvider } from "core/auth/roles-context"; import SpaRenderer from "core/spa/spa-renderer"; -import { ServerMessageType } from "components/messages"; +import { ServerMessageType } from "components/messages/messages"; import { MessagesContainer } from "components/toastr/toastr"; import ListPayg from "./list-payg"; diff --git a/web/html/src/manager/admin/list-payg/list-payg.tsx b/web/html/src/manager/admin/list-payg/list-payg.tsx index 42b692c99193..444740c43702 100644 --- a/web/html/src/manager/admin/list-payg/list-payg.tsx +++ b/web/html/src/manager/admin/list-payg/list-payg.tsx @@ -10,7 +10,7 @@ import PaygStatus from "manager/admin/payg-shared/common/payg-status"; import { Button } from "components/buttons"; import { FromNow } from "components/datetime/FromNow"; import withPageWrapper from "components/general/with-page-wrapper"; -import { ServerMessageType } from "components/messages"; +import { ServerMessageType } from "components/messages/messages"; import { SectionToolbar } from "components/section-toolbar/section-toolbar"; import { Column } from "components/table/Column"; import { SearchField } from "components/table/SearchField"; diff --git a/web/html/src/manager/admin/setup/products/products-scc-dialog.tsx b/web/html/src/manager/admin/setup/products/products-scc-dialog.tsx index 8959f54fcc3e..99be5754455c 100644 --- a/web/html/src/manager/admin/setup/products/products-scc-dialog.tsx +++ b/web/html/src/manager/admin/setup/products/products-scc-dialog.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import { Button } from "components/buttons"; -import { Messages, MessageType } from "components/messages"; +import { Messages, MessageType } from "components/messages/messages"; import Network from "utils/network"; diff --git a/web/html/src/manager/admin/setup/products/products.tsx b/web/html/src/manager/admin/setup/products/products.tsx index ecc53793adb5..103857816978 100644 --- a/web/html/src/manager/admin/setup/products/products.tsx +++ b/web/html/src/manager/admin/setup/products/products.tsx @@ -10,8 +10,8 @@ import { DangerDialog } from "components/dialog/DangerDialog"; import { Dialog } from "components/dialog/Dialog"; import { Form, Select } from "components/input"; import { ChannelLink } from "components/links"; -import { Messages, MessageType } from "components/messages"; -import { Utils as MessagesUtils } from "components/messages"; +import { Messages, MessageType } from "components/messages/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; import { SectionToolbar } from "components/section-toolbar/section-toolbar"; import { CustomDataHandler } from "components/table/CustomDataHandler"; import { SearchField } from "components/table/SearchField"; diff --git a/web/html/src/manager/admin/task-engine-status/taskotop.tsx b/web/html/src/manager/admin/task-engine-status/taskotop.tsx index 5f292651a396..130cde9910f3 100644 --- a/web/html/src/manager/admin/task-engine-status/taskotop.tsx +++ b/web/html/src/manager/admin/task-engine-status/taskotop.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import SpaRenderer from "core/spa/spa-renderer"; -import { Messages as MessageContainer, Utils as MessagesUtils } from "components/messages"; +import { Messages as MessageContainer, Utils as MessagesUtils } from "components/messages/messages"; import { Column } from "components/table/Column"; import { SearchField } from "components/table/SearchField"; import { Table } from "components/table/Table"; diff --git a/web/html/src/manager/appstreams/appstreams.tsx b/web/html/src/manager/appstreams/appstreams.tsx index 8fcdc27908a3..16e297a256e6 100644 --- a/web/html/src/manager/appstreams/appstreams.tsx +++ b/web/html/src/manager/appstreams/appstreams.tsx @@ -1,7 +1,7 @@ import { useState } from "react"; import { ActionChain } from "components/action-schedule"; -import { Messages, MessageType, Utils as MessageUtils } from "components/messages"; +import { Messages, MessageType, Utils as MessageUtils } from "components/messages/messages"; import { ChannelAppStream } from "./appstreams.type"; import { AppStreamsChangesConfirm } from "./changes-confirm-appstreams"; diff --git a/web/html/src/manager/audit/cveaudit/cveaudit.tsx b/web/html/src/manager/audit/cveaudit/cveaudit.tsx index ff5ec857ffb8..113ac9970f19 100644 --- a/web/html/src/manager/audit/cveaudit/cveaudit.tsx +++ b/web/html/src/manager/audit/cveaudit/cveaudit.tsx @@ -4,7 +4,7 @@ import SpaRenderer from "core/spa/spa-renderer"; import { AsyncButton, LinkButton } from "components/buttons"; import { IconTag } from "components/icontag"; -import { Messages } from "components/messages"; +import { Messages } from "components/messages/messages"; import { TopPanel } from "components/panels/TopPanel"; import { Column } from "components/table/Column"; import { Highlight } from "components/table/Highlight"; diff --git a/web/html/src/manager/audit/subscription-matching/subscription-matching.tsx b/web/html/src/manager/audit/subscription-matching/subscription-matching.tsx index 7ba329b45e46..79166bcd6bf7 100644 --- a/web/html/src/manager/audit/subscription-matching/subscription-matching.tsx +++ b/web/html/src/manager/audit/subscription-matching/subscription-matching.tsx @@ -2,8 +2,8 @@ import * as React from "react"; import SpaRenderer from "core/spa/spa-renderer"; -import { Messages as MessageContainer } from "components/messages"; -import { Utils as MessagesUtils } from "components/messages"; +import { Messages as MessageContainer } from "components/messages/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; import { TopPanel } from "components/panels/TopPanel"; import { TabContainer } from "components/tab-container"; diff --git a/web/html/src/manager/content-management/list-filters/filter-edit.tsx b/web/html/src/manager/content-management/list-filters/filter-edit.tsx index 8c4c6afa24a8..5b9610c3595b 100644 --- a/web/html/src/manager/content-management/list-filters/filter-edit.tsx +++ b/web/html/src/manager/content-management/list-filters/filter-edit.tsx @@ -6,7 +6,7 @@ import { closeDialog, Dialog } from "components/dialog/LegacyDialog"; import { ModalLink } from "components/dialog/ModalLink"; import { showDialog } from "components/dialog/util"; import { showErrorToastr, showSuccessToastr } from "components/toastr/toastr"; -import { Loading } from "components/utils/Loading"; +import { Loading } from "components/utils/loading/Loading"; import useLifecycleActionsApi from "../shared/api/use-lifecycle-actions-api"; import { FilterFormType } from "../shared/type/filter.type"; diff --git a/web/html/src/manager/content-management/list-projects/list-projects.renderer.tsx b/web/html/src/manager/content-management/list-projects/list-projects.renderer.tsx index 159f28b37b79..1ed0656206f0 100644 --- a/web/html/src/manager/content-management/list-projects/list-projects.renderer.tsx +++ b/web/html/src/manager/content-management/list-projects/list-projects.renderer.tsx @@ -3,7 +3,7 @@ import * as React from "react"; import { RolesProvider } from "core/auth/roles-context"; import SpaRenderer from "core/spa/spa-renderer"; -import { ServerMessageType } from "components/messages"; +import { ServerMessageType } from "components/messages/messages"; import { MessagesContainer } from "components/toastr/toastr"; import ListProjects from "./list-projects"; diff --git a/web/html/src/manager/content-management/list-projects/list-projects.tsx b/web/html/src/manager/content-management/list-projects/list-projects.tsx index 324fbc3c1e12..8cd3ebb00774 100644 --- a/web/html/src/manager/content-management/list-projects/list-projects.tsx +++ b/web/html/src/manager/content-management/list-projects/list-projects.tsx @@ -11,7 +11,7 @@ import useRoles from "core/auth/use-roles"; import { LinkButton } from "components/buttons"; import { FromNow } from "components/datetime/FromNow"; import withPageWrapper from "components/general/with-page-wrapper"; -import { ServerMessageType } from "components/messages"; +import { ServerMessageType } from "components/messages/messages"; import { TopPanel } from "components/panels/TopPanel"; import { Column } from "components/table/Column"; import { SearchField } from "components/table/SearchField"; diff --git a/web/html/src/manager/content-management/shared/components/messages/messages.tsx b/web/html/src/manager/content-management/shared/components/messages/messages.tsx index efd34fd09362..823e50b970ed 100644 --- a/web/html/src/manager/content-management/shared/components/messages/messages.tsx +++ b/web/html/src/manager/content-management/shared/components/messages/messages.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import _isEmpty from "lodash/isEmpty"; -import { Messages } from "components/messages"; +import { Messages } from "components/messages/messages"; import { ProjectMessageType } from "../../type"; diff --git a/web/html/src/manager/content-management/shared/components/panels/build/build.tsx b/web/html/src/manager/content-management/shared/components/panels/build/build.tsx index c526feddfb55..4a40fce2732b 100644 --- a/web/html/src/manager/content-management/shared/components/panels/build/build.tsx +++ b/web/html/src/manager/content-management/shared/components/panels/build/build.tsx @@ -6,11 +6,11 @@ import _last from "lodash/last"; import { Button } from "components/buttons"; import { closeDialog, Dialog } from "components/dialog/LegacyDialog"; import { ModalButton } from "components/dialog/ModalButton"; -import { Form } from "components/input/Form"; -import { Text } from "components/input/Text"; -import { Messages, Utils as MsgUtils } from "components/messages"; +import { Form } from "components/input/form/Form"; +import { Text } from "components/input/text/Text"; +import { Messages, Utils as MsgUtils } from "components/messages/messages"; import { showErrorToastr, showSuccessToastr } from "components/toastr/toastr"; -import { Loading } from "components/utils/Loading"; +import { Loading } from "components/utils/loading/Loading"; import statesEnum from "../../../../shared/business/states.enum"; import useLifecycleActionsApi from "../../../api/use-lifecycle-actions-api"; diff --git a/web/html/src/manager/content-management/shared/components/panels/environment-lifecycle/environment-lifecycle.tsx b/web/html/src/manager/content-management/shared/components/panels/environment-lifecycle/environment-lifecycle.tsx index 3f3b6fbb19ce..2c74ee528afb 100644 --- a/web/html/src/manager/content-management/shared/components/panels/environment-lifecycle/environment-lifecycle.tsx +++ b/web/html/src/manager/content-management/shared/components/panels/environment-lifecycle/environment-lifecycle.tsx @@ -3,10 +3,10 @@ import * as React from "react"; import { isOrgAdmin } from "core/auth/auth.utils"; import useRoles from "core/auth/use-roles"; -import { Messages, Utils as MsgUtils } from "components/messages"; +import { Messages, Utils as MsgUtils } from "components/messages/messages"; import CreatorPanel from "components/panels/CreatorPanel"; import { showErrorToastr, showSuccessToastr } from "components/toastr"; -import { Loading } from "components/utils/Loading"; +import { Loading } from "components/utils/loading/Loading"; import useLifecycleActionsApi from "../../../api/use-lifecycle-actions-api"; import { ProjectEnvironmentType, ProjectHistoryEntry, ProjectMessageType } from "../../../type"; diff --git a/web/html/src/manager/content-management/shared/components/panels/filters-project/filters-project-selection.tsx b/web/html/src/manager/content-management/shared/components/panels/filters-project/filters-project-selection.tsx index 7aa83249b0bf..273d750bc725 100644 --- a/web/html/src/manager/content-management/shared/components/panels/filters-project/filters-project-selection.tsx +++ b/web/html/src/manager/content-management/shared/components/panels/filters-project/filters-project-selection.tsx @@ -4,7 +4,7 @@ import { useEffect, useState } from "react"; import _xor from "lodash/xor"; import { LinkButton } from "components/buttons"; -import { Loading } from "components/utils/Loading"; +import { Loading } from "components/utils/loading/Loading"; import useLifecycleActionsApi from "../../../api/use-lifecycle-actions-api"; import { getClmFilterDescription } from "../../../business/filters.enum"; diff --git a/web/html/src/manager/content-management/shared/components/panels/promote/promote.tsx b/web/html/src/manager/content-management/shared/components/panels/promote/promote.tsx index 7d3a0a1f1e68..2c4fed016e02 100644 --- a/web/html/src/manager/content-management/shared/components/panels/promote/promote.tsx +++ b/web/html/src/manager/content-management/shared/components/panels/promote/promote.tsx @@ -8,7 +8,7 @@ import { Button } from "components/buttons"; import { closeDialog, Dialog } from "components/dialog/LegacyDialog"; import { ModalButton } from "components/dialog/ModalButton"; import { showErrorToastr, showSuccessToastr } from "components/toastr/toastr"; -import { Loading } from "components/utils/Loading"; +import { Loading } from "components/utils/loading/Loading"; import useLifecycleActionsApi from "../../../api/use-lifecycle-actions-api"; import { ProjectEnvironmentType, ProjectHistoryEntry } from "../../../type/project.type"; diff --git a/web/html/src/manager/content-management/shared/components/panels/properties/properties-edit.tsx b/web/html/src/manager/content-management/shared/components/panels/properties/properties-edit.tsx index 44297758a16a..d80880739239 100644 --- a/web/html/src/manager/content-management/shared/components/panels/properties/properties-edit.tsx +++ b/web/html/src/manager/content-management/shared/components/panels/properties/properties-edit.tsx @@ -5,7 +5,7 @@ import useRoles from "core/auth/use-roles"; import CreatorPanel from "components/panels/CreatorPanel"; import { showErrorToastr, showSuccessToastr } from "components/toastr"; -import { Loading } from "components/utils/Loading"; +import { Loading } from "components/utils/loading/Loading"; import produce from "utils/produce"; diff --git a/web/html/src/manager/content-management/shared/components/panels/sources/channels/channels-selection.tsx b/web/html/src/manager/content-management/shared/components/panels/sources/channels/channels-selection.tsx index 1737ad731993..3573c141e8b2 100644 --- a/web/html/src/manager/content-management/shared/components/panels/sources/channels/channels-selection.tsx +++ b/web/html/src/manager/content-management/shared/components/panels/sources/channels/channels-selection.tsx @@ -8,8 +8,8 @@ import { ProjectSoftwareSourceType } from "manager/content-management/shared/typ import { BaseChannelType, ChannelTreeType, ChildChannelType, isBaseChannel } from "core/channels/type/channels.type"; -import { Select } from "components/input/Select"; -import { Loading } from "components/utils/Loading"; +import { Select } from "components/input"; +import { Loading } from "components/utils/loading/Loading"; import { VirtualList } from "components/virtual-list"; import BaseChannel from "./base-channel"; diff --git a/web/html/src/manager/groups/config-channels/group-config-channels.tsx b/web/html/src/manager/groups/config-channels/group-config-channels.tsx index 9398d3800067..f0b5c1e5bf04 100644 --- a/web/html/src/manager/groups/config-channels/group-config-channels.tsx +++ b/web/html/src/manager/groups/config-channels/group-config-channels.tsx @@ -3,7 +3,7 @@ import * as React from "react"; import SpaRenderer from "core/spa/spa-renderer"; import { ConfigChannels } from "components/config-channels"; -import { Utils as MessagesUtils } from "components/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; import Network from "utils/network"; diff --git a/web/html/src/manager/images/image-build.tsx b/web/html/src/manager/images/image-build.tsx index e548df5c1963..f792444d3646 100644 --- a/web/html/src/manager/images/image-build.tsx +++ b/web/html/src/manager/images/image-build.tsx @@ -4,13 +4,13 @@ import SpaRenderer from "core/spa/spa-renderer"; import { ActionChain, ActionSchedule } from "components/action-schedule"; import { LinkButton, SubmitButton } from "components/buttons"; -import { Form } from "components/input/Form"; +import { Select } from "components/input"; +import { Form } from "components/input/form/Form"; import { FormGroup } from "components/input/FormGroup"; -import { Select } from "components/input/Select"; -import { Text } from "components/input/Text"; +import { Text } from "components/input/text/Text"; import { ActionChainLink, ActionLink } from "components/links"; -import { Messages } from "components/messages"; -import { Utils as MessagesUtils } from "components/messages"; +import { Messages } from "components/messages/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; import { TopPanel } from "components/panels/TopPanel"; import { localizedMoment } from "utils"; diff --git a/web/html/src/manager/images/image-import.tsx b/web/html/src/manager/images/image-import.tsx index 0dc1404df1f1..d037552d1951 100644 --- a/web/html/src/manager/images/image-import.tsx +++ b/web/html/src/manager/images/image-import.tsx @@ -3,11 +3,11 @@ import * as React from "react"; import SpaRenderer from "core/spa/spa-renderer"; import { Button, SubmitButton } from "components/buttons"; -import { Form } from "components/input/Form"; -import { Select } from "components/input/Select"; -import { Text } from "components/input/Text"; -import { Messages } from "components/messages"; -import { Utils as MessagesUtils } from "components/messages"; +import { Select } from "components/input"; +import { Form } from "components/input/form/Form"; +import { Text } from "components/input/text/Text"; +import { Messages } from "components/messages/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; import { TopPanel } from "components/panels/TopPanel"; import { Utils } from "utils/functions"; diff --git a/web/html/src/manager/images/image-profile-edit.tsx b/web/html/src/manager/images/image-profile-edit.tsx index bd910e91264b..3125aa065e85 100644 --- a/web/html/src/manager/images/image-profile-edit.tsx +++ b/web/html/src/manager/images/image-profile-edit.tsx @@ -5,12 +5,12 @@ import { default as ReactSelect } from "react-select"; import SpaRenderer from "core/spa/spa-renderer"; import { Button, SubmitButton } from "components/buttons"; -import { Form } from "components/input/Form"; +import { Select } from "components/input"; +import { Form } from "components/input/form/Form"; import { FormGroup } from "components/input/FormGroup"; import { Label } from "components/input/Label"; -import { Select } from "components/input/Select"; -import { Text } from "components/input/Text"; -import { Messages } from "components/messages"; +import { Text } from "components/input/text/Text"; +import { Messages } from "components/messages/messages"; import { TopPanel } from "components/panels/TopPanel"; import { Utils } from "utils/functions"; diff --git a/web/html/src/manager/images/image-profiles.tsx b/web/html/src/manager/images/image-profiles.tsx index cf27db9399fa..877a4bb65eba 100644 --- a/web/html/src/manager/images/image-profiles.tsx +++ b/web/html/src/manager/images/image-profiles.tsx @@ -5,7 +5,7 @@ import SpaRenderer from "core/spa/spa-renderer"; import { AsyncButton, LinkButton } from "components/buttons"; import { DeleteDialog } from "components/dialog/DeleteDialog"; import { ModalButton } from "components/dialog/ModalButton"; -import { Messages } from "components/messages"; +import { Messages } from "components/messages/messages"; import { TopPanel } from "components/panels/TopPanel"; import { Column } from "components/table/Column"; import { SearchField } from "components/table/SearchField"; diff --git a/web/html/src/manager/images/image-store-edit.tsx b/web/html/src/manager/images/image-store-edit.tsx index 9b8cbf2ea463..244d59edce76 100644 --- a/web/html/src/manager/images/image-store-edit.tsx +++ b/web/html/src/manager/images/image-store-edit.tsx @@ -3,12 +3,12 @@ import * as React from "react"; import SpaRenderer from "core/spa/spa-renderer"; import { Button, SubmitButton } from "components/buttons"; -import { Check } from "components/input/Check"; -import { Form } from "components/input/Form"; -import { Password } from "components/input/Password"; -import { Select } from "components/input/Select"; -import { Text } from "components/input/Text"; -import { Messages } from "components/messages"; +import { Select } from "components/input"; +import { Check } from "components/input/check/Check"; +import { Form } from "components/input/form/Form"; +import { Password } from "components/input/password/Password"; +import { Text } from "components/input/text/Text"; +import { Messages } from "components/messages/messages"; import { TopPanel } from "components/panels/TopPanel"; import { Utils } from "utils/functions"; diff --git a/web/html/src/manager/images/image-stores.tsx b/web/html/src/manager/images/image-stores.tsx index 1c3424692c13..f7407a822183 100644 --- a/web/html/src/manager/images/image-stores.tsx +++ b/web/html/src/manager/images/image-stores.tsx @@ -5,7 +5,7 @@ import SpaRenderer from "core/spa/spa-renderer"; import { AsyncButton, LinkButton } from "components/buttons"; import { DeleteDialog } from "components/dialog/DeleteDialog"; import { ModalButton } from "components/dialog/ModalButton"; -import { Messages } from "components/messages"; +import { Messages } from "components/messages/messages"; import { TopPanel } from "components/panels/TopPanel"; import { Column } from "components/table/Column"; import { SearchField } from "components/table/SearchField"; diff --git a/web/html/src/manager/images/image-view-overview.tsx b/web/html/src/manager/images/image-view-overview.tsx index 7df00b5c03eb..3b4a0a3a262f 100644 --- a/web/html/src/manager/images/image-view-overview.tsx +++ b/web/html/src/manager/images/image-view-overview.tsx @@ -5,8 +5,8 @@ import { FromNow } from "components/datetime"; import { DeleteDialog } from "components/dialog/DeleteDialog"; import { ModalButton } from "components/dialog/ModalButton"; import { ModalLink } from "components/dialog/ModalLink"; -import { DateTime as InputDateTime } from "components/input/DateTime"; -import { Form } from "components/input/Form"; +import { DateTime as InputDateTime } from "components/input/datetime/DateTime"; +import { Form } from "components/input/form/Form"; import { BootstrapPanel } from "components/panels/BootstrapPanel"; import { PopUp } from "components/popup"; diff --git a/web/html/src/manager/images/image-view.tsx b/web/html/src/manager/images/image-view.tsx index 748924d394c9..eb8e68449c85 100644 --- a/web/html/src/manager/images/image-view.tsx +++ b/web/html/src/manager/images/image-view.tsx @@ -7,8 +7,8 @@ import { FromNow } from "components/datetime"; import { DeleteDialog } from "components/dialog/DeleteDialog"; import { ModalButton } from "components/dialog/ModalButton"; import { ModalLink } from "components/dialog/ModalLink"; -import { Messages } from "components/messages"; -import { Utils as MessagesUtils } from "components/messages"; +import { Messages } from "components/messages/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; import { TopPanel } from "components/panels/TopPanel"; import { PopUp } from "components/popup"; import { TabContainer } from "components/tab-container"; diff --git a/web/html/src/manager/index.ts b/web/html/src/manager/index.ts index ecfbce64573a..840861ccef26 100644 --- a/web/html/src/manager/index.ts +++ b/web/html/src/manager/index.ts @@ -32,19 +32,21 @@ import Salt from "./salt"; import ScheduleOptions from "./schedule-options"; import Shared from "./shared"; import Highstate from "./state"; +import Storybook from "./storybook"; import Systems from "./systems"; import ActivationKeys from "./systems/activation-key"; import Virtualization from "./virtualization"; const pages = { + ...ActivationKeys, ...Admin, + ...Appstreams, ...Audit, ...ContentManagement, ...Errors, ...Groups, ...Header, ...Highstate, - ...RecurringActions, ...Images, ...Login, ...MaintenanceWindows, @@ -53,16 +55,21 @@ const pages = { ...Organizations, ...Packages, ...Proxy, + ...RecurringActions, ...Salt, ...ScheduleOptions, ...Shared, ...Systems, + ...Storybook, ...Virtualization, - ...Appstreams, - ...ActivationKeys, }; window.spaImportReactPage = function spaImportReactPage(pageName) { SpaRenderer.addReactApp(pageName); + + if (!pages[pageName]) { + throw new RangeError(`Found no page with name "${pageName}", did you bind the renderer in \`pages\`?`); + } + return pages[pageName](); }; diff --git a/web/html/src/manager/login/messages.tsx b/web/html/src/manager/login/messages.tsx index e83c261edc79..4456023c2996 100644 --- a/web/html/src/manager/login/messages.tsx +++ b/web/html/src/manager/login/messages.tsx @@ -1,6 +1,6 @@ import * as React from "react"; -import { Messages, MessageType } from "components/messages"; +import { Messages, MessageType } from "components/messages/messages"; export const getGlobalMessages = (validationErrors, schemaUpgradeRequired, diskspaceSeverity, sccForwardWarning) => { let messages: MessageType[] = []; diff --git a/web/html/src/manager/login/susemanager/login.tsx b/web/html/src/manager/login/susemanager/login.tsx index 73b41ddfe552..dc9a77d34640 100644 --- a/web/html/src/manager/login/susemanager/login.tsx +++ b/web/html/src/manager/login/susemanager/login.tsx @@ -5,7 +5,7 @@ import { docsLocale } from "core/user-preferences"; import { SubmitButton } from "components/buttons"; import { useInputValue } from "components/hooks/forms/useInputValue"; -import { Messages } from "components/messages"; +import { Messages } from "components/messages/messages"; import { flatten } from "utils"; diff --git a/web/html/src/manager/login/uyuni/login.tsx b/web/html/src/manager/login/uyuni/login.tsx index aeebf559e0c8..e3761b9c3cca 100644 --- a/web/html/src/manager/login/uyuni/login.tsx +++ b/web/html/src/manager/login/uyuni/login.tsx @@ -3,7 +3,7 @@ import { useState } from "react"; import { SubmitButton } from "components/buttons"; import { useInputValue } from "components/hooks/forms/useInputValue"; -import { Messages } from "components/messages"; +import { Messages } from "components/messages/messages"; import { ThemeProps } from "../login"; import { getFormMessages, getGlobalMessages } from "../messages"; diff --git a/web/html/src/manager/maintenance/calendar/web-calendar.tsx b/web/html/src/manager/maintenance/calendar/web-calendar.tsx index 1bcd72e35580..ddaf17e94778 100644 --- a/web/html/src/manager/maintenance/calendar/web-calendar.tsx +++ b/web/html/src/manager/maintenance/calendar/web-calendar.tsx @@ -14,7 +14,7 @@ import moment from "moment"; import { jsFormatPreferredLocale } from "core/user-preferences"; -import { MessageType, Utils as MessagesUtils } from "components/messages"; +import { MessageType, Utils as MessagesUtils } from "components/messages/messages"; import Network from "utils/network"; diff --git a/web/html/src/manager/maintenance/details/calendar-details.tsx b/web/html/src/manager/maintenance/details/calendar-details.tsx index de1ad93fc1e4..46ff6e0275cf 100644 --- a/web/html/src/manager/maintenance/details/calendar-details.tsx +++ b/web/html/src/manager/maintenance/details/calendar-details.tsx @@ -4,9 +4,9 @@ import { useState } from "react"; import { WebCalendar } from "manager/maintenance/calendar/web-calendar"; import { DeleteDialog } from "components/dialog/DeleteDialog"; -import { Check } from "components/input/Check"; -import { Form } from "components/input/Form"; -import { MessageType } from "components/messages"; +import { Check } from "components/input/check/Check"; +import { Form } from "components/input/form/Form"; +import { MessageType } from "components/messages/messages"; import { BootstrapPanel } from "components/panels/BootstrapPanel"; import { Column } from "components/table/Column"; import { Table } from "components/table/Table"; diff --git a/web/html/src/manager/maintenance/details/maintenance-windows-details.tsx b/web/html/src/manager/maintenance/details/maintenance-windows-details.tsx index 0fb6628e4843..654bf24fb10b 100644 --- a/web/html/src/manager/maintenance/details/maintenance-windows-details.tsx +++ b/web/html/src/manager/maintenance/details/maintenance-windows-details.tsx @@ -3,7 +3,7 @@ import { useState } from "react"; import { Button } from "components/buttons"; import { ModalButton } from "components/dialog/ModalButton"; -import { MessageType } from "components/messages"; +import { MessageType } from "components/messages/messages"; import { TopPanel } from "components/panels/TopPanel"; import MaintenanceCalendarDetails from "./calendar-details"; diff --git a/web/html/src/manager/maintenance/details/schedule-details.tsx b/web/html/src/manager/maintenance/details/schedule-details.tsx index c38e23ae66c3..d2f968f092a8 100644 --- a/web/html/src/manager/maintenance/details/schedule-details.tsx +++ b/web/html/src/manager/maintenance/details/schedule-details.tsx @@ -8,8 +8,8 @@ import { DeleteDialog } from "components/dialog/DeleteDialog"; import { ModalButton } from "components/dialog/ModalButton"; import { IconTag } from "components/icontag"; import { SystemLink } from "components/links"; -import { Utils as MessagesUtils } from "components/messages"; -import { MessageType } from "components/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; +import { MessageType } from "components/messages/messages"; import { BootstrapPanel } from "components/panels/BootstrapPanel"; import { TabLabel } from "components/tab-container"; import { Column } from "components/table/Column"; diff --git a/web/html/src/manager/maintenance/edit/calendar-edit.tsx b/web/html/src/manager/maintenance/edit/calendar-edit.tsx index effac59df0d2..cbf2dd1b80f3 100644 --- a/web/html/src/manager/maintenance/edit/calendar-edit.tsx +++ b/web/html/src/manager/maintenance/edit/calendar-edit.tsx @@ -6,10 +6,10 @@ import validator from "validator"; import { Button } from "components/buttons"; import { DangerDialog } from "components/dialog/LegacyDangerDialog"; import { ModalButton } from "components/dialog/ModalButton"; -import { Check } from "components/input/Check"; -import { Form } from "components/input/Form"; -import { Text } from "components/input/Text"; -import { MessageType, Utils as MessagesUtils } from "components/messages"; +import { Check } from "components/input/check/Check"; +import { Form } from "components/input/form/Form"; +import { Text } from "components/input/text/Text"; +import { MessageType, Utils as MessagesUtils } from "components/messages/messages"; type CalendarEditProps = { messages: (messages: MessageType[]) => any; diff --git a/web/html/src/manager/maintenance/edit/schedule-edit.tsx b/web/html/src/manager/maintenance/edit/schedule-edit.tsx index ec6046c77fc5..0c5876c7b400 100644 --- a/web/html/src/manager/maintenance/edit/schedule-edit.tsx +++ b/web/html/src/manager/maintenance/edit/schedule-edit.tsx @@ -3,10 +3,10 @@ import { forwardRef, useEffect, useImperativeHandle, useState } from "react"; import { Button } from "components/buttons"; import { Combobox } from "components/combobox"; -import { Check } from "components/input/Check"; -import { Form } from "components/input/Form"; -import { Radio } from "components/input/Radio"; -import { Text } from "components/input/Text"; +import { Check } from "components/input/check/Check"; +import { Form } from "components/input/form/Form"; +import { Radio } from "components/input/radio/Radio"; +import { Text } from "components/input/text/Text"; type ScheduleEditProps = { isEdit: boolean; diff --git a/web/html/src/manager/maintenance/list/calendar-list.tsx b/web/html/src/manager/maintenance/list/calendar-list.tsx index 305c62b5a745..9aea0ad64c4f 100644 --- a/web/html/src/manager/maintenance/list/calendar-list.tsx +++ b/web/html/src/manager/maintenance/list/calendar-list.tsx @@ -4,8 +4,8 @@ import { useState } from "react"; import { Button } from "components/buttons"; import { DeleteDialog } from "components/dialog/DeleteDialog"; import { ModalButton } from "components/dialog/ModalButton"; -import { Check } from "components/input/Check"; -import { Form } from "components/input/Form"; +import { Check } from "components/input/check/Check"; +import { Form } from "components/input/form/Form"; import { Column } from "components/table/Column"; import { Table } from "components/table/Table"; diff --git a/web/html/src/manager/maintenance/maintenance-windows.tsx b/web/html/src/manager/maintenance/maintenance-windows.tsx index 9421ecb8d19f..eb7ef54d2dfb 100644 --- a/web/html/src/manager/maintenance/maintenance-windows.tsx +++ b/web/html/src/manager/maintenance/maintenance-windows.tsx @@ -3,8 +3,8 @@ import { useEffect, useState } from "react"; import SpaRenderer from "core/spa/spa-renderer"; -import { Messages } from "components/messages"; -import { Utils as MessagesUtils } from "components/messages"; +import { Messages } from "components/messages/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; import Network from "utils/network"; diff --git a/web/html/src/manager/maintenance/ssm/schedule-picker.tsx b/web/html/src/manager/maintenance/ssm/schedule-picker.tsx index 3f737490962e..4efc5d47944b 100644 --- a/web/html/src/manager/maintenance/ssm/schedule-picker.tsx +++ b/web/html/src/manager/maintenance/ssm/schedule-picker.tsx @@ -3,11 +3,11 @@ import { useContext, useEffect, useState } from "react"; import { AsyncButton } from "components/buttons"; import { ModalButton } from "components/dialog/ModalButton"; -import { Check } from "components/input/Check"; -import { Form, FormContext } from "components/input/Form"; -import { Select } from "components/input/Select"; -import { Utils as MessagesUtils } from "components/messages"; -import { MessageType } from "components/messages"; +import { Select } from "components/input"; +import { Check } from "components/input/check/Check"; +import { Form, FormContext } from "components/input/form/Form"; +import { Utils as MessagesUtils } from "components/messages/messages"; +import { MessageType } from "components/messages/messages"; import Network from "utils/network"; diff --git a/web/html/src/manager/maintenance/ssm/system-assignment.tsx b/web/html/src/manager/maintenance/ssm/system-assignment.tsx index 4a09f0a30fe9..b25796d08861 100644 --- a/web/html/src/manager/maintenance/ssm/system-assignment.tsx +++ b/web/html/src/manager/maintenance/ssm/system-assignment.tsx @@ -3,7 +3,7 @@ import { useState } from "react"; import SpaRenderer from "core/spa/spa-renderer"; -import { Messages, MessageType } from "components/messages"; +import { Messages, MessageType } from "components/messages/messages"; import { BootstrapPanel } from "components/panels/BootstrapPanel"; import { SchedulePickerForm, WithMaintenanceSchedules } from "./schedule-picker"; diff --git a/web/html/src/manager/minion/ansible/accordion-path-content.tsx b/web/html/src/manager/minion/ansible/accordion-path-content.tsx index e712904b94bf..b12f7804ff9c 100644 --- a/web/html/src/manager/minion/ansible/accordion-path-content.tsx +++ b/web/html/src/manager/minion/ansible/accordion-path-content.tsx @@ -2,8 +2,8 @@ import * as React from "react"; import { AceEditor } from "components/ace-editor"; import { Button } from "components/buttons"; -import { Messages, Utils } from "components/messages"; -import { Loading } from "components/utils/Loading"; +import { Messages, Utils } from "components/messages/messages"; +import { Loading } from "components/utils/loading/Loading"; import Network from "utils/network"; diff --git a/web/html/src/manager/minion/ansible/ansible-control-node.tsx b/web/html/src/manager/minion/ansible/ansible-control-node.tsx index 618f33614837..cffd342bbaa5 100644 --- a/web/html/src/manager/minion/ansible/ansible-control-node.tsx +++ b/web/html/src/manager/minion/ansible/ansible-control-node.tsx @@ -2,9 +2,9 @@ import * as React from "react"; import SpaRenderer from "core/spa/spa-renderer"; -import { Messages, Utils } from "components/messages"; +import { Messages, Utils } from "components/messages/messages"; import { Panel } from "components/panels/Panel"; -import { Loading } from "components/utils/Loading"; +import { Loading } from "components/utils/loading/Loading"; import Network from "utils/network"; diff --git a/web/html/src/manager/minion/ansible/ansible-path-content.tsx b/web/html/src/manager/minion/ansible/ansible-path-content.tsx index c7bf9108a3d7..6d54d1409d03 100644 --- a/web/html/src/manager/minion/ansible/ansible-path-content.tsx +++ b/web/html/src/manager/minion/ansible/ansible-path-content.tsx @@ -2,8 +2,8 @@ import * as React from "react"; import SpaRenderer from "core/spa/spa-renderer"; -import { Messages, Utils } from "components/messages"; -import { Loading } from "components/utils/Loading"; +import { Messages, Utils } from "components/messages/messages"; +import { Loading } from "components/utils/loading/Loading"; import Network from "utils/network"; diff --git a/web/html/src/manager/minion/ansible/schedule-playbook.tsx b/web/html/src/manager/minion/ansible/schedule-playbook.tsx index d8644466dc65..5e70a2e4caf6 100644 --- a/web/html/src/manager/minion/ansible/schedule-playbook.tsx +++ b/web/html/src/manager/minion/ansible/schedule-playbook.tsx @@ -7,10 +7,10 @@ import { AsyncButton, Button } from "components/buttons"; import { Combobox, ComboboxItem } from "components/combobox"; import { Check, Form } from "components/input"; import { ActionChainLink, ActionLink } from "components/links"; -import { Messages, MessageType, Utils as MsgUtils } from "components/messages"; +import { Messages, MessageType, Utils as MsgUtils } from "components/messages/messages"; import { InnerPanel } from "components/panels/InnerPanel"; import { Toggler } from "components/toggler"; -import { Loading } from "components/utils/Loading"; +import { Loading } from "components/utils/loading/Loading"; import { localizedMoment } from "utils"; import Network, { JsonResult } from "utils/network"; diff --git a/web/html/src/manager/minion/coco/coco-settings.tsx b/web/html/src/manager/minion/coco/coco-settings.tsx index f519bc0d29bd..b677e03be870 100644 --- a/web/html/src/manager/minion/coco/coco-settings.tsx +++ b/web/html/src/manager/minion/coco/coco-settings.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import CoCoSettingsForm from "components/coco-attestation/CoCoSettingsForm"; import { Settings } from "components/coco-attestation/Utils"; -import { Messages, MessageType, Utils as MessagesUtils } from "components/messages"; +import { Messages, MessageType, Utils as MessagesUtils } from "components/messages/messages"; import { TopPanel } from "components/panels/TopPanel"; import { Loading } from "components/utils"; diff --git a/web/html/src/manager/minion/config-channels/minion-config-channels.tsx b/web/html/src/manager/minion/config-channels/minion-config-channels.tsx index 946ca7b0565a..d4162838ef7e 100644 --- a/web/html/src/manager/minion/config-channels/minion-config-channels.tsx +++ b/web/html/src/manager/minion/config-channels/minion-config-channels.tsx @@ -3,7 +3,7 @@ import * as React from "react"; import SpaRenderer from "core/spa/spa-renderer"; import { ConfigChannels } from "components/config-channels"; -import { Utils as MessagesUtils } from "components/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; import Network from "utils/network"; diff --git a/web/html/src/manager/minion/packages/package-states.tsx b/web/html/src/manager/minion/packages/package-states.tsx index 1f5795be33f8..27e5dd13c224 100644 --- a/web/html/src/manager/minion/packages/package-states.tsx +++ b/web/html/src/manager/minion/packages/package-states.tsx @@ -8,7 +8,7 @@ import { useImmer } from "use-immer"; import { AsyncButton } from "components/buttons"; import { TextField } from "components/fields"; import withPageWrapper from "components/general/with-page-wrapper"; -import { Messages } from "components/messages"; +import { Messages } from "components/messages/messages"; import { InnerPanel } from "components/panels/InnerPanel"; import { showErrorToastr } from "components/toastr/toastr"; diff --git a/web/html/src/manager/minion/packages/use-package-states.api.tsx b/web/html/src/manager/minion/packages/use-package-states.api.tsx index ec1765adf7a4..312db766f69d 100644 --- a/web/html/src/manager/minion/packages/use-package-states.api.tsx +++ b/web/html/src/manager/minion/packages/use-package-states.api.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import { useState } from "react"; -import { MessageType, Utils as MessagesUtils } from "components/messages"; +import { MessageType, Utils as MessagesUtils } from "components/messages/messages"; import Network from "utils/network"; diff --git a/web/html/src/manager/minion/ptf/ptf-overview.renderer.tsx b/web/html/src/manager/minion/ptf/ptf-overview.renderer.tsx index 4605702b9f45..f2ac5a93ca55 100644 --- a/web/html/src/manager/minion/ptf/ptf-overview.renderer.tsx +++ b/web/html/src/manager/minion/ptf/ptf-overview.renderer.tsx @@ -4,7 +4,7 @@ import SpaRenderer from "core/spa/spa-renderer"; import { InnerPanel } from "components/panels/InnerPanel"; import { MessagesContainer } from "components/toastr"; -import { Loading } from "components/utils/Loading"; +import { Loading } from "components/utils/loading/Loading"; import Network from "utils/network"; diff --git a/web/html/src/manager/notifications/notification-messages.tsx b/web/html/src/manager/notifications/notification-messages.tsx index e3dfa51f8a9d..4c7031943fd4 100644 --- a/web/html/src/manager/notifications/notification-messages.tsx +++ b/web/html/src/manager/notifications/notification-messages.tsx @@ -6,7 +6,7 @@ import { AsyncButton } from "components/buttons"; import { Dialog } from "components/dialog/LegacyDialog"; import { showDialog } from "components/dialog/util"; import { Form, Select } from "components/input"; -import { Messages as MessageContainer, Utils as MessagesUtils } from "components/messages"; +import { Messages as MessageContainer, Utils as MessagesUtils } from "components/messages/messages"; import { TopPanel } from "components/panels/TopPanel"; import { SectionToolbar } from "components/section-toolbar/section-toolbar"; import { Column } from "components/table/Column"; diff --git a/web/html/src/manager/organizations/config-channels/org-config-channels.tsx b/web/html/src/manager/organizations/config-channels/org-config-channels.tsx index 3afb71ff2447..5bb0a5445ebf 100644 --- a/web/html/src/manager/organizations/config-channels/org-config-channels.tsx +++ b/web/html/src/manager/organizations/config-channels/org-config-channels.tsx @@ -3,7 +3,7 @@ import * as React from "react"; import SpaRenderer from "core/spa/spa-renderer"; import { ConfigChannels } from "components/config-channels"; -import { Utils as MessagesUtils } from "components/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; import Network from "utils/network"; diff --git a/web/html/src/manager/proxy/container-config-messages.tsx b/web/html/src/manager/proxy/container-config-messages.tsx index 1ab44d559046..5ec47aeda26c 100644 --- a/web/html/src/manager/proxy/container-config-messages.tsx +++ b/web/html/src/manager/proxy/container-config-messages.tsx @@ -1,6 +1,6 @@ import * as React from "react"; -import { Messages } from "components/messages"; +import { Messages } from "components/messages/messages"; type SuccessType = boolean | undefined; diff --git a/web/html/src/manager/proxy/container-config.tsx b/web/html/src/manager/proxy/container-config.tsx index afc38e6f48fc..d0b0ed626a23 100644 --- a/web/html/src/manager/proxy/container-config.tsx +++ b/web/html/src/manager/proxy/container-config.tsx @@ -3,11 +3,11 @@ import { useState } from "react"; import { AsyncButton } from "components/buttons"; import { SubmitButton } from "components/buttons"; -import { Form } from "components/input/Form"; +import { Form } from "components/input/form/Form"; +import { FormMultiInput } from "components/input/form-multi-input/FormMultiInput"; import { unflattenModel } from "components/input/form-utils"; -import { FormMultiInput } from "components/input/FormMultiInput"; -import { Radio } from "components/input/Radio"; -import { Text } from "components/input/Text"; +import { Radio } from "components/input/radio/Radio"; +import { Text } from "components/input/text/Text"; import { Panel } from "components/panels/Panel"; import { TopPanel } from "components/panels/TopPanel"; import Validation from "components/validation"; diff --git a/web/html/src/manager/recurring/recurring-actions-details.tsx b/web/html/src/manager/recurring/recurring-actions-details.tsx index 49cd6b66dbf1..7239496ea68d 100644 --- a/web/html/src/manager/recurring/recurring-actions-details.tsx +++ b/web/html/src/manager/recurring/recurring-actions-details.tsx @@ -5,7 +5,7 @@ import _sortBy from "lodash/sortBy"; import { Button } from "components/buttons"; import { DeleteDialog } from "components/dialog/DeleteDialog"; import { ModalButton } from "components/dialog/ModalButton"; -import { Messages, Utils as MessagesUtils } from "components/messages"; +import { Messages, Utils as MessagesUtils } from "components/messages/messages"; import { BootstrapPanel } from "components/panels/BootstrapPanel"; import { TopPanel } from "components/panels/TopPanel"; import { Column } from "components/table/Column"; diff --git a/web/html/src/manager/recurring/recurring-actions-edit.tsx b/web/html/src/manager/recurring/recurring-actions-edit.tsx index 6cb103028aa7..0461822520f8 100644 --- a/web/html/src/manager/recurring/recurring-actions-edit.tsx +++ b/web/html/src/manager/recurring/recurring-actions-edit.tsx @@ -5,7 +5,7 @@ import _isEqual from "lodash/isEqual"; import { Button } from "components/buttons"; import { AsyncButton } from "components/buttons"; import { Form, Select } from "components/input"; -import { Utils as MessagesUtils } from "components/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; import { InnerPanel } from "components/panels/InnerPanel"; import { RecurringEventPicker } from "components/picker/recurring-event-picker"; import { StatesPicker } from "components/states-picker"; diff --git a/web/html/src/manager/recurring/recurring-actions-list.tsx b/web/html/src/manager/recurring/recurring-actions-list.tsx index e1c6d61413c2..fd696f1df076 100644 --- a/web/html/src/manager/recurring/recurring-actions-list.tsx +++ b/web/html/src/manager/recurring/recurring-actions-list.tsx @@ -6,7 +6,7 @@ import { Button } from "components/buttons"; import { DeleteDialog } from "components/dialog/DeleteDialog"; import { ModalButton } from "components/dialog/ModalButton"; import { IconTag } from "components/icontag"; -import { Utils as MessagesUtils } from "components/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; import { Column } from "components/table/Column"; import { Table } from "components/table/Table"; import { Toggler } from "components/toggler"; diff --git a/web/html/src/manager/recurring/recurring-actions.tsx b/web/html/src/manager/recurring/recurring-actions.tsx index 150634169dec..54a0c8d4d4c6 100644 --- a/web/html/src/manager/recurring/recurring-actions.tsx +++ b/web/html/src/manager/recurring/recurring-actions.tsx @@ -2,8 +2,8 @@ import * as React from "react"; import SpaRenderer from "core/spa/spa-renderer"; -import { Messages } from "components/messages"; -import { Utils as MessagesUtils } from "components/messages"; +import { Messages } from "components/messages/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; import { localizedMoment } from "utils"; import Network from "utils/network"; diff --git a/web/html/src/manager/salt/formula-catalog/org-formula-catalog.renderer.tsx b/web/html/src/manager/salt/formula-catalog/org-formula-catalog.renderer.tsx index 05d7587fb60b..95b282cb7b1b 100644 --- a/web/html/src/manager/salt/formula-catalog/org-formula-catalog.renderer.tsx +++ b/web/html/src/manager/salt/formula-catalog/org-formula-catalog.renderer.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import SpaRenderer from "core/spa/spa-renderer"; -import { ServerMessageType } from "components/messages"; +import { ServerMessageType } from "components/messages/messages"; import FormulaCatalog from "./org-formula-catalog"; diff --git a/web/html/src/manager/salt/formula-catalog/org-formula-catalog.tsx b/web/html/src/manager/salt/formula-catalog/org-formula-catalog.tsx index c08db9285734..fc33066cd471 100644 --- a/web/html/src/manager/salt/formula-catalog/org-formula-catalog.tsx +++ b/web/html/src/manager/salt/formula-catalog/org-formula-catalog.tsx @@ -3,7 +3,7 @@ import { hot } from "react-hot-loader/root"; import * as React from "react"; import withPageWrapper from "components/general/with-page-wrapper"; -import { Messages, MessageType, ServerMessageType } from "components/messages"; +import { Messages, MessageType, ServerMessageType } from "components/messages/messages"; import { TopPanel } from "components/panels/TopPanel"; import { Column } from "components/table/Column"; import { SearchField } from "components/table/SearchField"; diff --git a/web/html/src/manager/state/highstate.tsx b/web/html/src/manager/state/highstate.tsx index 08782a3a883d..2a27a32bfdc4 100644 --- a/web/html/src/manager/state/highstate.tsx +++ b/web/html/src/manager/state/highstate.tsx @@ -6,8 +6,8 @@ import { ActionSchedule } from "components/action-schedule"; import { LinkButton } from "components/buttons"; import { AsyncButton } from "components/buttons"; import { ActionChainLink, ActionLink } from "components/links"; -import { Messages } from "components/messages"; -import { Utils as MessagesUtils } from "components/messages"; +import { Messages } from "components/messages/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; import { InnerPanel } from "components/panels/InnerPanel"; import { Toggler } from "components/toggler"; diff --git a/web/html/src/manager/storybook/index.ts b/web/html/src/manager/storybook/index.ts new file mode 100644 index 000000000000..e6454cf7074d --- /dev/null +++ b/web/html/src/manager/storybook/index.ts @@ -0,0 +1,3 @@ +export default { + storybook: () => import("./storybook.renderer"), +}; diff --git a/web/html/src/manager/storybook/layout.module.less b/web/html/src/manager/storybook/layout.module.less new file mode 100644 index 000000000000..45efd81ba4ad --- /dev/null +++ b/web/html/src/manager/storybook/layout.module.less @@ -0,0 +1,29 @@ +:global(.old-theme), +:global(.new-theme) { + .header { + padding: 8px 16px; + background: #eee; + } + + .section { + display: flex; + flex-direction: column; + gap: 16px; + padding: 16px; + border: 1px solid #eee; + + &:not(:last-child) { + margin-bottom: 16px; + } + } + + .striped { + background: repeating-linear-gradient(-45deg, #fff, #fff 10px, #eee 10px, #eee 12px); + } + + .row { + display: flex; + flex-direction: row; + gap: 16px; + } +} diff --git a/web/html/src/manager/storybook/layout.tsx b/web/html/src/manager/storybook/layout.tsx new file mode 100644 index 000000000000..1f3481c3a800 --- /dev/null +++ b/web/html/src/manager/storybook/layout.tsx @@ -0,0 +1,31 @@ +import React from "react"; + +import styles from "./layout.module.less"; + +type Props = { + children?: React.ReactNode; +}; + +export const StorySection = (props: Props) => { + return ( + <> +
{props.children}
+ + ); +}; + +export const StripedStorySection = (props: Props) => { + return ( + <> +
{props.children}
+ + ); +}; + +type RowProps = { + children?: React.ReactNode; +}; + +export const StoryRow = (props: RowProps) => { + return
{props.children}
; +}; diff --git a/web/html/src/manager/storybook/stories.generated.ts b/web/html/src/manager/storybook/stories.generated.ts new file mode 100644 index 000000000000..bb56637d0967 --- /dev/null +++ b/web/html/src/manager/storybook/stories.generated.ts @@ -0,0 +1,370 @@ +/** + * NB! This is a generated file! + * Any changes you make here will be lost. + * See: web/html/src/build/plugins/generate-stories-plugin.js + */ + +/* eslint-disable */ + +import components_action_ActionStatus_stories_tsx_component from "components/action/ActionStatus.stories.tsx"; +import components_action_ActionStatus_stories_tsx_raw from "components/action/ActionStatus.stories.tsx?raw"; + +export const components_action_ActionStatus_stories_tsx = { + path: "components/action/ActionStatus.stories.tsx", + title: "ActionStatus.stories.tsx", + groupName: "action", + component: components_action_ActionStatus_stories_tsx_component, + raw: components_action_ActionStatus_stories_tsx_raw, +}; + +import components_buttons_stories_tsx_component from "components/buttons.stories.tsx"; +import components_buttons_stories_tsx_raw from "components/buttons.stories.tsx?raw"; + +export const components_buttons_stories_tsx = { + path: "components/buttons.stories.tsx", + title: "buttons.stories.tsx", + groupName: "components", + component: components_buttons_stories_tsx_component, + raw: components_buttons_stories_tsx_raw, +}; + +import components_datetime_DateTimePicker_stories_tsx_component from "components/datetime/DateTimePicker.stories.tsx"; +import components_datetime_DateTimePicker_stories_tsx_raw from "components/datetime/DateTimePicker.stories.tsx?raw"; + +export const components_datetime_DateTimePicker_stories_tsx = { + path: "components/datetime/DateTimePicker.stories.tsx", + title: "DateTimePicker.stories.tsx", + groupName: "datetime", + component: components_datetime_DateTimePicker_stories_tsx_component, + raw: components_datetime_DateTimePicker_stories_tsx_raw, +}; + +import components_datetime_FromNow_stories_tsx_component from "components/datetime/FromNow.stories.tsx"; +import components_datetime_FromNow_stories_tsx_raw from "components/datetime/FromNow.stories.tsx?raw"; + +export const components_datetime_FromNow_stories_tsx = { + path: "components/datetime/FromNow.stories.tsx", + title: "FromNow.stories.tsx", + groupName: "datetime", + component: components_datetime_FromNow_stories_tsx_component, + raw: components_datetime_FromNow_stories_tsx_raw, +}; + +import components_dialog_action_confirm_stories_tsx_component from "components/dialog/action-confirm.stories.tsx"; +import components_dialog_action_confirm_stories_tsx_raw from "components/dialog/action-confirm.stories.tsx?raw"; + +export const components_dialog_action_confirm_stories_tsx = { + path: "components/dialog/action-confirm.stories.tsx", + title: "action-confirm.stories.tsx", + groupName: "dialog", + component: components_dialog_action_confirm_stories_tsx_component, + raw: components_dialog_action_confirm_stories_tsx_raw, +}; + +import components_dialog_delete_stories_tsx_component from "components/dialog/delete.stories.tsx"; +import components_dialog_delete_stories_tsx_raw from "components/dialog/delete.stories.tsx?raw"; + +export const components_dialog_delete_stories_tsx = { + path: "components/dialog/delete.stories.tsx", + title: "delete.stories.tsx", + groupName: "dialog", + component: components_dialog_delete_stories_tsx_component, + raw: components_dialog_delete_stories_tsx_raw, +}; + +import components_input_check_Check_stories_tsx_component from "components/input/check/Check.stories.tsx"; +import components_input_check_Check_stories_tsx_raw from "components/input/check/Check.stories.tsx?raw"; + +export const components_input_check_Check_stories_tsx = { + path: "components/input/check/Check.stories.tsx", + title: "Check.stories.tsx", + groupName: "check", + component: components_input_check_Check_stories_tsx_component, + raw: components_input_check_Check_stories_tsx_raw, +}; + +import components_input_datetime_DateTime_stories_tsx_component from "components/input/datetime/DateTime.stories.tsx"; +import components_input_datetime_DateTime_stories_tsx_raw from "components/input/datetime/DateTime.stories.tsx?raw"; + +export const components_input_datetime_DateTime_stories_tsx = { + path: "components/input/datetime/DateTime.stories.tsx", + title: "DateTime.stories.tsx", + groupName: "datetime", + component: components_input_datetime_DateTime_stories_tsx_component, + raw: components_input_datetime_DateTime_stories_tsx_raw, +}; + +import components_input_form_multi_input_multiple_fields_stories_tsx_component from "components/input/form-multi-input/multiple-fields.stories.tsx"; +import components_input_form_multi_input_multiple_fields_stories_tsx_raw from "components/input/form-multi-input/multiple-fields.stories.tsx?raw"; + +export const components_input_form_multi_input_multiple_fields_stories_tsx = { + path: "components/input/form-multi-input/multiple-fields.stories.tsx", + title: "multiple-fields.stories.tsx", + groupName: "form-multi-input", + component: components_input_form_multi_input_multiple_fields_stories_tsx_component, + raw: components_input_form_multi_input_multiple_fields_stories_tsx_raw, +}; + +import components_input_form_multi_input_single_field_stories_tsx_component from "components/input/form-multi-input/single-field.stories.tsx"; +import components_input_form_multi_input_single_field_stories_tsx_raw from "components/input/form-multi-input/single-field.stories.tsx?raw"; + +export const components_input_form_multi_input_single_field_stories_tsx = { + path: "components/input/form-multi-input/single-field.stories.tsx", + title: "single-field.stories.tsx", + groupName: "form-multi-input", + component: components_input_form_multi_input_single_field_stories_tsx_component, + raw: components_input_form_multi_input_single_field_stories_tsx_raw, +}; + +import components_input_form_multi_input_table_fields_stories_tsx_component from "components/input/form-multi-input/table-fields.stories.tsx"; +import components_input_form_multi_input_table_fields_stories_tsx_raw from "components/input/form-multi-input/table-fields.stories.tsx?raw"; + +export const components_input_form_multi_input_table_fields_stories_tsx = { + path: "components/input/form-multi-input/table-fields.stories.tsx", + title: "table-fields.stories.tsx", + groupName: "form-multi-input", + component: components_input_form_multi_input_table_fields_stories_tsx_component, + raw: components_input_form_multi_input_table_fields_stories_tsx_raw, +}; + +import components_input_form_Form_stories_tsx_component from "components/input/form/Form.stories.tsx"; +import components_input_form_Form_stories_tsx_raw from "components/input/form/Form.stories.tsx?raw"; + +export const components_input_form_Form_stories_tsx = { + path: "components/input/form/Form.stories.tsx", + title: "Form.stories.tsx", + groupName: "form", + component: components_input_form_Form_stories_tsx_component, + raw: components_input_form_Form_stories_tsx_raw, +}; + +import components_input_password_Password_stories_tsx_component from "components/input/password/Password.stories.tsx"; +import components_input_password_Password_stories_tsx_raw from "components/input/password/Password.stories.tsx?raw"; + +export const components_input_password_Password_stories_tsx = { + path: "components/input/password/Password.stories.tsx", + title: "Password.stories.tsx", + groupName: "password", + component: components_input_password_Password_stories_tsx_component, + raw: components_input_password_Password_stories_tsx_raw, +}; + +import components_input_radio_horizontal_open_stories_tsx_component from "components/input/radio/horizontal-open.stories.tsx"; +import components_input_radio_horizontal_open_stories_tsx_raw from "components/input/radio/horizontal-open.stories.tsx?raw"; + +export const components_input_radio_horizontal_open_stories_tsx = { + path: "components/input/radio/horizontal-open.stories.tsx", + title: "horizontal-open.stories.tsx", + groupName: "radio", + component: components_input_radio_horizontal_open_stories_tsx_component, + raw: components_input_radio_horizontal_open_stories_tsx_raw, +}; + +import components_input_radio_horizontal_stories_tsx_component from "components/input/radio/horizontal.stories.tsx"; +import components_input_radio_horizontal_stories_tsx_raw from "components/input/radio/horizontal.stories.tsx?raw"; + +export const components_input_radio_horizontal_stories_tsx = { + path: "components/input/radio/horizontal.stories.tsx", + title: "horizontal.stories.tsx", + groupName: "radio", + component: components_input_radio_horizontal_stories_tsx_component, + raw: components_input_radio_horizontal_stories_tsx_raw, +}; + +import components_input_radio_vertical_open_stories_tsx_component from "components/input/radio/vertical-open.stories.tsx"; +import components_input_radio_vertical_open_stories_tsx_raw from "components/input/radio/vertical-open.stories.tsx?raw"; + +export const components_input_radio_vertical_open_stories_tsx = { + path: "components/input/radio/vertical-open.stories.tsx", + title: "vertical-open.stories.tsx", + groupName: "radio", + component: components_input_radio_vertical_open_stories_tsx_component, + raw: components_input_radio_vertical_open_stories_tsx_raw, +}; + +import components_input_radio_vertical_stories_tsx_component from "components/input/radio/vertical.stories.tsx"; +import components_input_radio_vertical_stories_tsx_raw from "components/input/radio/vertical.stories.tsx?raw"; + +export const components_input_radio_vertical_stories_tsx = { + path: "components/input/radio/vertical.stories.tsx", + title: "vertical.stories.tsx", + groupName: "radio", + component: components_input_radio_vertical_stories_tsx_component, + raw: components_input_radio_vertical_stories_tsx_raw, +}; + +import components_input_range_Range_stories_tsx_component from "components/input/range/Range.stories.tsx"; +import components_input_range_Range_stories_tsx_raw from "components/input/range/Range.stories.tsx?raw"; + +export const components_input_range_Range_stories_tsx = { + path: "components/input/range/Range.stories.tsx", + title: "Range.stories.tsx", + groupName: "range", + component: components_input_range_Range_stories_tsx_component, + raw: components_input_range_Range_stories_tsx_raw, +}; + +import components_input_select_async_stories_tsx_component from "components/input/select/async.stories.tsx"; +import components_input_select_async_stories_tsx_raw from "components/input/select/async.stories.tsx?raw"; + +export const components_input_select_async_stories_tsx = { + path: "components/input/select/async.stories.tsx", + title: "async.stories.tsx", + groupName: "select", + component: components_input_select_async_stories_tsx_component, + raw: components_input_select_async_stories_tsx_raw, +}; + +import components_input_select_custom_stories_tsx_component from "components/input/select/custom.stories.tsx"; +import components_input_select_custom_stories_tsx_raw from "components/input/select/custom.stories.tsx?raw"; + +export const components_input_select_custom_stories_tsx = { + path: "components/input/select/custom.stories.tsx", + title: "custom.stories.tsx", + groupName: "select", + component: components_input_select_custom_stories_tsx_component, + raw: components_input_select_custom_stories_tsx_raw, +}; + +import components_input_select_simple_stories_tsx_component from "components/input/select/simple.stories.tsx"; +import components_input_select_simple_stories_tsx_raw from "components/input/select/simple.stories.tsx?raw"; + +export const components_input_select_simple_stories_tsx = { + path: "components/input/select/simple.stories.tsx", + title: "simple.stories.tsx", + groupName: "select", + component: components_input_select_simple_stories_tsx_component, + raw: components_input_select_simple_stories_tsx_raw, +}; + +import components_input_text_Text_stories_tsx_component from "components/input/text/Text.stories.tsx"; +import components_input_text_Text_stories_tsx_raw from "components/input/text/Text.stories.tsx?raw"; + +export const components_input_text_Text_stories_tsx = { + path: "components/input/text/Text.stories.tsx", + title: "Text.stories.tsx", + groupName: "text", + component: components_input_text_Text_stories_tsx_component, + raw: components_input_text_Text_stories_tsx_raw, +}; + +import components_messages_severities_stories_tsx_component from "components/messages/severities.stories.tsx"; +import components_messages_severities_stories_tsx_raw from "components/messages/severities.stories.tsx?raw"; + +export const components_messages_severities_stories_tsx = { + path: "components/messages/severities.stories.tsx", + title: "severities.stories.tsx", + groupName: "messages", + component: components_messages_severities_stories_tsx_component, + raw: components_messages_severities_stories_tsx_raw, +}; + +import components_messages_utilities_stories_tsx_component from "components/messages/utilities.stories.tsx"; +import components_messages_utilities_stories_tsx_raw from "components/messages/utilities.stories.tsx?raw"; + +export const components_messages_utilities_stories_tsx = { + path: "components/messages/utilities.stories.tsx", + title: "utilities.stories.tsx", + groupName: "messages", + component: components_messages_utilities_stories_tsx_component, + raw: components_messages_utilities_stories_tsx_raw, +}; + +import components_panels_BootstrapPanel_stories_tsx_component from "components/panels/BootstrapPanel.stories.tsx"; +import components_panels_BootstrapPanel_stories_tsx_raw from "components/panels/BootstrapPanel.stories.tsx?raw"; + +export const components_panels_BootstrapPanel_stories_tsx = { + path: "components/panels/BootstrapPanel.stories.tsx", + title: "BootstrapPanel.stories.tsx", + groupName: "panels", + component: components_panels_BootstrapPanel_stories_tsx_component, + raw: components_panels_BootstrapPanel_stories_tsx_raw, +}; + +import components_panels_TopPanel_stories_tsx_component from "components/panels/TopPanel.stories.tsx"; +import components_panels_TopPanel_stories_tsx_raw from "components/panels/TopPanel.stories.tsx?raw"; + +export const components_panels_TopPanel_stories_tsx = { + path: "components/panels/TopPanel.stories.tsx", + title: "TopPanel.stories.tsx", + groupName: "panels", + component: components_panels_TopPanel_stories_tsx_component, + raw: components_panels_TopPanel_stories_tsx_raw, +}; + +import components_toastr_toastr_stories_tsx_component from "components/toastr/toastr.stories.tsx"; +import components_toastr_toastr_stories_tsx_raw from "components/toastr/toastr.stories.tsx?raw"; + +export const components_toastr_toastr_stories_tsx = { + path: "components/toastr/toastr.stories.tsx", + title: "toastr.stories.tsx", + groupName: "toastr", + component: components_toastr_toastr_stories_tsx_component, + raw: components_toastr_toastr_stories_tsx_raw, +}; + +import components_tree_tree_stories_tsx_component from "components/tree/tree.stories.tsx"; +import components_tree_tree_stories_tsx_raw from "components/tree/tree.stories.tsx?raw"; + +export const components_tree_tree_stories_tsx = { + path: "components/tree/tree.stories.tsx", + title: "tree.stories.tsx", + groupName: "tree", + component: components_tree_tree_stories_tsx_component, + raw: components_tree_tree_stories_tsx_raw, +}; + +import components_utils_HelpIcon_stories_tsx_component from "components/utils/HelpIcon.stories.tsx"; +import components_utils_HelpIcon_stories_tsx_raw from "components/utils/HelpIcon.stories.tsx?raw"; + +export const components_utils_HelpIcon_stories_tsx = { + path: "components/utils/HelpIcon.stories.tsx", + title: "HelpIcon.stories.tsx", + groupName: "utils", + component: components_utils_HelpIcon_stories_tsx_component, + raw: components_utils_HelpIcon_stories_tsx_raw, +}; + +import components_utils_HelpLink_stories_tsx_component from "components/utils/HelpLink.stories.tsx"; +import components_utils_HelpLink_stories_tsx_raw from "components/utils/HelpLink.stories.tsx?raw"; + +export const components_utils_HelpLink_stories_tsx = { + path: "components/utils/HelpLink.stories.tsx", + title: "HelpLink.stories.tsx", + groupName: "utils", + component: components_utils_HelpLink_stories_tsx_component, + raw: components_utils_HelpLink_stories_tsx_raw, +}; + +import components_utils_loading_simple_stories_tsx_component from "components/utils/loading/simple.stories.tsx"; +import components_utils_loading_simple_stories_tsx_raw from "components/utils/loading/simple.stories.tsx?raw"; + +export const components_utils_loading_simple_stories_tsx = { + path: "components/utils/loading/simple.stories.tsx", + title: "simple.stories.tsx", + groupName: "loading", + component: components_utils_loading_simple_stories_tsx_component, + raw: components_utils_loading_simple_stories_tsx_raw, +}; + +import components_utils_loading_text_border_stories_tsx_component from "components/utils/loading/text-border.stories.tsx"; +import components_utils_loading_text_border_stories_tsx_raw from "components/utils/loading/text-border.stories.tsx?raw"; + +export const components_utils_loading_text_border_stories_tsx = { + path: "components/utils/loading/text-border.stories.tsx", + title: "text-border.stories.tsx", + groupName: "loading", + component: components_utils_loading_text_border_stories_tsx_component, + raw: components_utils_loading_text_border_stories_tsx_raw, +}; + +import components_utils_loading_text_stories_tsx_component from "components/utils/loading/text.stories.tsx"; +import components_utils_loading_text_stories_tsx_raw from "components/utils/loading/text.stories.tsx?raw"; + +export const components_utils_loading_text_stories_tsx = { + path: "components/utils/loading/text.stories.tsx", + title: "text.stories.tsx", + groupName: "loading", + component: components_utils_loading_text_stories_tsx_component, + raw: components_utils_loading_text_stories_tsx_raw, +}; \ No newline at end of file diff --git a/web/html/src/manager/storybook/stories.ts b/web/html/src/manager/storybook/stories.ts new file mode 100644 index 000000000000..3580ea03c530 --- /dev/null +++ b/web/html/src/manager/storybook/stories.ts @@ -0,0 +1,5 @@ +import * as generatedStories from "./stories.generated"; + +const storyGroups = Object.groupBy(Object.values(generatedStories), (item) => item.groupName); + +export default Object.entries(storyGroups).map(([title, stories]) => ({ title, stories })); diff --git a/web/html/src/manager/storybook/storybook.module.less b/web/html/src/manager/storybook/storybook.module.less new file mode 100644 index 000000000000..da4763d8a6f2 --- /dev/null +++ b/web/html/src/manager/storybook/storybook.module.less @@ -0,0 +1,29 @@ +:global(.old-theme), +:global(.new-theme) { + .header { + // position: sticky; + top: 8px; + padding-bottom: 8px; + background: #fff; + z-index: 1; + } + + .story { + display: flex; + gap: 16px; + + > div { + flex: 1 0 auto; + } + + > pre { + flex: 1 1 auto; + overflow: auto; + max-width: 50%; + + code { + white-space: pre; + } + } + } +} diff --git a/web/html/src/manager/storybook/storybook.renderer.tsx b/web/html/src/manager/storybook/storybook.renderer.tsx new file mode 100644 index 000000000000..b0d3cb350413 --- /dev/null +++ b/web/html/src/manager/storybook/storybook.renderer.tsx @@ -0,0 +1,16 @@ +import * as React from "react"; + +import SpaRenderer from "core/spa/spa-renderer"; + +import { MessagesContainer } from "components/toastr"; + +import { Storybook } from "./storybook"; + +export const renderer = (id: string) => + SpaRenderer.renderNavigationReact( + <> + + + , + document.getElementById(id) + ); diff --git a/web/html/src/manager/storybook/storybook.tsx b/web/html/src/manager/storybook/storybook.tsx new file mode 100644 index 000000000000..434405890504 --- /dev/null +++ b/web/html/src/manager/storybook/storybook.tsx @@ -0,0 +1,113 @@ +import { Fragment, useEffect, useState } from "react"; + +import debugUtils from "core/debugUtils"; + +import { Button } from "components/buttons"; +import { IconTag } from "components/icontag"; + +import { StoryRow } from "./layout"; +import stories from "./stories"; +import styles from "./storybook.module.less"; + +const STORAGE_KEY = "storybook-show-code"; + +export const Storybook = () => { + const [_hash, setHash] = useState(window.location.hash); + const hash = _hash.replace(/^#/, ""); + const normalize = (input: string = "") => input.replaceAll(" ", "-").toLowerCase(); + + const activeTabHash = normalize(hash) || normalize(stories[0]?.title); + + const [, _invalidate] = useState(0); + const invalidate = () => _invalidate((ii) => ii + 1); + + const [showCode, _setShowCode] = useState(!!localStorage.getItem(STORAGE_KEY)); + const setShowCode = (value: boolean) => { + _setShowCode(value); + if (value) { + localStorage.setItem(STORAGE_KEY, "true"); + } else { + localStorage.removeItem(STORAGE_KEY); + } + }; + + useEffect(() => { + const listener = () => setHash(window.location.hash); + window.addEventListener("hashchange", listener); + return () => { + window.removeEventListener("hashchange", listener); + }; + }, []); + + return ( + <> +
+

+ + {t("Development debugging page")} +

+

{t("This is a hidden page used by developers, if you found it by accident, good job!")}

+

+ {document.body.className} +

+ + +
+ +
+
    + {stories + .sort((a, b) => a.title.localeCompare(b.title)) + .map((item) => { + const tabHash = normalize(item.title); + return ( +
  • + {item.title} +
  • + ); + })} +
+
+ + {stories.map((group) => ( +
+ {normalize(group.title) === activeTabHash && + group.stories?.map((item) => ( + +

+ {item.title} +

+
+
{item.component ? : null}
+ {showCode ? ( +
+                      {item.raw}
+                    
+ ) : null} +
+
+
+ ))} +
+ ))} + + ); +}; diff --git a/web/html/src/manager/systems/activation-key/activation-key-channels.tsx b/web/html/src/manager/systems/activation-key/activation-key-channels.tsx index 56384083befa..51d569853f3d 100644 --- a/web/html/src/manager/systems/activation-key/activation-key-channels.tsx +++ b/web/html/src/manager/systems/activation-key/activation-key-channels.tsx @@ -2,9 +2,9 @@ import * as React from "react"; import MandatoryChannelsApi from "core/channels/api/mandatory-channels-api"; -import { Messages } from "components/messages"; -import { Utils as MessagesUtils } from "components/messages"; -import { Loading } from "components/utils/Loading"; +import { Messages } from "components/messages/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; +import { Loading } from "components/utils/loading/Loading"; import ActivationKeyChannelsApi from "./activation-key-channels-api"; import { availableChannelsType, Channel } from "./activation-key-channels-api"; diff --git a/web/html/src/manager/systems/activation-key/activation-keys-appstreams.tsx b/web/html/src/manager/systems/activation-key/activation-keys-appstreams.tsx index baab2a8c7dfa..917cc20fef82 100644 --- a/web/html/src/manager/systems/activation-key/activation-keys-appstreams.tsx +++ b/web/html/src/manager/systems/activation-key/activation-keys-appstreams.tsx @@ -4,7 +4,7 @@ import { AppStreamActions } from "manager/appstreams/actions-appstreams"; import { AppStreamPanel } from "manager/appstreams/panel-appstream"; import { handleModuleEnableDisable, numberOfChanges } from "manager/appstreams/utils"; -import { Messages, MessageType, Utils as MessageUtils } from "components/messages"; +import { Messages, MessageType, Utils as MessageUtils } from "components/messages/messages"; import Network from "utils/network"; diff --git a/web/html/src/manager/systems/activation-key/child-channels.tsx b/web/html/src/manager/systems/activation-key/child-channels.tsx index 815c905a75be..a30365e2700b 100644 --- a/web/html/src/manager/systems/activation-key/child-channels.tsx +++ b/web/html/src/manager/systems/activation-key/child-channels.tsx @@ -4,7 +4,7 @@ import { RequiredChannelsResultType } from "core/channels/api/use-mandatory-chan import { ChannelAnchorLink } from "components/links"; import { Toggler } from "components/toggler"; -import { Loading } from "components/utils/Loading"; +import { Loading } from "components/utils/loading/Loading"; import { Channel } from "./activation-key-channels-api"; diff --git a/web/html/src/manager/systems/bootstrap/bootstrap-minions.tsx b/web/html/src/manager/systems/bootstrap/bootstrap-minions.tsx index a2e5f6817cb6..e2e7b19be4ce 100644 --- a/web/html/src/manager/systems/bootstrap/bootstrap-minions.tsx +++ b/web/html/src/manager/systems/bootstrap/bootstrap-minions.tsx @@ -5,7 +5,7 @@ import SpaRenderer from "core/spa/spa-renderer"; import { AsyncButton, Button } from "components/buttons"; import { Dialog } from "components/dialog/Dialog"; import { ModalLink } from "components/dialog/ModalLink"; -import { Messages, MessageType, Utils as MessagesUtils } from "components/messages"; +import { Messages, MessageType, Utils as MessagesUtils } from "components/messages/messages"; import { TopPanel } from "components/panels/TopPanel"; import Network from "utils/network"; diff --git a/web/html/src/manager/systems/coco/ssm-schedule.tsx b/web/html/src/manager/systems/coco/ssm-schedule.tsx index c7557dd2b492..51ff55764e10 100644 --- a/web/html/src/manager/systems/coco/ssm-schedule.tsx +++ b/web/html/src/manager/systems/coco/ssm-schedule.tsx @@ -3,7 +3,7 @@ import * as React from "react"; import { ActionChain, ActionSchedule } from "components/action-schedule"; import { AsyncButton } from "components/buttons"; import { ActionChainLink, ActionLink } from "components/links"; -import { Messages, MessageType, Utils as MessagesUtils } from "components/messages"; +import { Messages, MessageType, Utils as MessagesUtils } from "components/messages/messages"; import { TopPanel } from "components/panels/TopPanel"; import { SectionToolbar } from "components/section-toolbar/section-toolbar"; import { Column } from "components/table/Column"; diff --git a/web/html/src/manager/systems/coco/ssm-settings.tsx b/web/html/src/manager/systems/coco/ssm-settings.tsx index 5520dbab6fcb..a913a544e092 100644 --- a/web/html/src/manager/systems/coco/ssm-settings.tsx +++ b/web/html/src/manager/systems/coco/ssm-settings.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import CoCoSettingsForm from "components/coco-attestation/CoCoSettingsForm"; import { Settings } from "components/coco-attestation/Utils"; -import { Messages, MessageType, Utils as MessagesUtils } from "components/messages"; +import { Messages, MessageType, Utils as MessagesUtils } from "components/messages/messages"; import { TopPanel } from "components/panels/TopPanel"; import { Column } from "components/table/Column"; import { SystemData, TargetSystems } from "components/target-systems"; diff --git a/web/html/src/manager/systems/delete-system.tsx b/web/html/src/manager/systems/delete-system.tsx index 23d1e75a039b..202022f6c0c4 100644 --- a/web/html/src/manager/systems/delete-system.tsx +++ b/web/html/src/manager/systems/delete-system.tsx @@ -3,8 +3,8 @@ import * as React from "react"; import { AsyncButton, Button } from "components/buttons"; import { Dialog } from "components/dialog/LegacyDialog"; import { showDialog } from "components/dialog/util"; -import { Messages } from "components/messages"; -import { Utils as MessagesUtils } from "components/messages"; +import { Messages } from "components/messages/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; import Network from "utils/network"; diff --git a/web/html/src/manager/systems/details/mgr-server-info.tsx b/web/html/src/manager/systems/details/mgr-server-info.tsx index 5247bf80d9a8..a88dd88eb113 100644 --- a/web/html/src/manager/systems/details/mgr-server-info.tsx +++ b/web/html/src/manager/systems/details/mgr-server-info.tsx @@ -1,8 +1,8 @@ import * as React from "react"; import { AsyncButton } from "components/buttons"; -import { Messages } from "components/messages"; -import { MessageType, Utils as MessagesUtils } from "components/messages"; +import { Messages } from "components/messages/messages"; +import { MessageType, Utils as MessagesUtils } from "components/messages/messages"; import { TopPanel } from "components/panels/TopPanel"; import Network from "utils/network"; diff --git a/web/html/src/manager/systems/proxy.tsx b/web/html/src/manager/systems/proxy.tsx index 17ad394a1c2d..05a2a2df64b8 100644 --- a/web/html/src/manager/systems/proxy.tsx +++ b/web/html/src/manager/systems/proxy.tsx @@ -2,8 +2,8 @@ import * as React from "react"; import { AsyncButton } from "components/buttons"; import { ActionLink } from "components/links"; -import { Messages, MessageType } from "components/messages"; -import { Utils as MessagesUtils } from "components/messages"; +import { Messages, MessageType } from "components/messages/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; import { BootstrapPanel } from "components/panels/BootstrapPanel"; import Network from "utils/network"; diff --git a/web/html/src/manager/systems/ssm/ssm-subscribe-channels.tsx b/web/html/src/manager/systems/ssm/ssm-subscribe-channels.tsx index 48abd7847298..60e99be8317a 100644 --- a/web/html/src/manager/systems/ssm/ssm-subscribe-channels.tsx +++ b/web/html/src/manager/systems/ssm/ssm-subscribe-channels.tsx @@ -7,8 +7,8 @@ import { ActionSchedule } from "components/action-schedule"; import { ActionChain } from "components/action-schedule"; import { AsyncButton, Button } from "components/buttons"; import { ActionChainLink, ActionLink, ChannelLink, SystemLink } from "components/links"; -import { Messages } from "components/messages"; -import { Utils as MessagesUtils } from "components/messages"; +import { Messages } from "components/messages/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; import { BootstrapPanel } from "components/panels/BootstrapPanel"; import { PopUp } from "components/popup"; import { Column } from "components/table/Column"; diff --git a/web/html/src/manager/systems/subscribe-channels/subscribe-channels.tsx b/web/html/src/manager/systems/subscribe-channels/subscribe-channels.tsx index 792aa580453e..472136b6577a 100644 --- a/web/html/src/manager/systems/subscribe-channels/subscribe-channels.tsx +++ b/web/html/src/manager/systems/subscribe-channels/subscribe-channels.tsx @@ -8,8 +8,8 @@ import { ActionSchedule } from "components/action-schedule"; import { ActionChain } from "components/action-schedule"; import { AsyncButton, Button } from "components/buttons"; import { ActionChainLink, ActionLink, ChannelAnchorLink } from "components/links"; -import { Messages } from "components/messages"; -import { Utils as MessagesUtils } from "components/messages"; +import { Messages } from "components/messages/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; import { BootstrapPanel } from "components/panels/BootstrapPanel"; import { Toggler } from "components/toggler"; diff --git a/web/html/src/manager/systems/virtualhostmanager/virtualhostmanager-details.tsx b/web/html/src/manager/systems/virtualhostmanager/virtualhostmanager-details.tsx index 9ace8e9e992b..8eadc6decabf 100644 --- a/web/html/src/manager/systems/virtualhostmanager/virtualhostmanager-details.tsx +++ b/web/html/src/manager/systems/virtualhostmanager/virtualhostmanager-details.tsx @@ -3,8 +3,8 @@ import * as React from "react"; import { Button } from "components/buttons"; import { DeleteDialog } from "components/dialog/DeleteDialog"; import { ModalButton } from "components/dialog/ModalButton"; -import { Messages } from "components/messages"; -import { Utils as MessagesUtils } from "components/messages"; +import { Messages } from "components/messages/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; import { BootstrapPanel } from "components/panels/BootstrapPanel"; import { Column } from "components/table/Column"; import { Table } from "components/table/Table"; diff --git a/web/html/src/manager/systems/virtualhostmanager/virtualhostmanager-edit.tsx b/web/html/src/manager/systems/virtualhostmanager/virtualhostmanager-edit.tsx index c68ebd570d0c..0815482e3432 100644 --- a/web/html/src/manager/systems/virtualhostmanager/virtualhostmanager-edit.tsx +++ b/web/html/src/manager/systems/virtualhostmanager/virtualhostmanager-edit.tsx @@ -1,13 +1,13 @@ import * as React from "react"; import { Button, SubmitButton } from "components/buttons"; -import { Form } from "components/input/Form"; +import { Select } from "components/input"; +import { Form } from "components/input/form/Form"; import { FormGroup } from "components/input/FormGroup"; import { Label } from "components/input/Label"; -import { Password } from "components/input/Password"; -import { Select } from "components/input/Select"; -import { Text } from "components/input/Text"; -import { Messages } from "components/messages"; +import { Password } from "components/input/password/Password"; +import { Text } from "components/input/text/Text"; +import { Messages } from "components/messages/messages"; import { Utils } from "utils/functions"; import Network from "utils/network"; diff --git a/web/html/src/manager/systems/virtualhostmanager/virtualhostmanager.tsx b/web/html/src/manager/systems/virtualhostmanager/virtualhostmanager.tsx index 07dd8b2fe9af..05559cb39703 100644 --- a/web/html/src/manager/systems/virtualhostmanager/virtualhostmanager.tsx +++ b/web/html/src/manager/systems/virtualhostmanager/virtualhostmanager.tsx @@ -3,8 +3,8 @@ import * as React from "react"; import SpaRenderer from "core/spa/spa-renderer"; import { DropdownButton } from "components/buttons"; -import { Messages } from "components/messages"; -import { Utils as MessagesUtils } from "components/messages"; +import { Messages } from "components/messages/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; import { TopPanel } from "components/panels/TopPanel"; import Network from "utils/network"; diff --git a/web/html/src/manager/virtualization/ActionApi.tsx b/web/html/src/manager/virtualization/ActionApi.tsx index 906595f726f4..f3172985b0d3 100644 --- a/web/html/src/manager/virtualization/ActionApi.tsx +++ b/web/html/src/manager/virtualization/ActionApi.tsx @@ -1,7 +1,7 @@ import * as React from "react"; -import { Utils as MessagesUtils } from "components/messages"; -import { MessageType } from "components/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; +import { MessageType } from "components/messages/messages"; import Network from "utils/network"; diff --git a/web/html/src/manager/virtualization/HypervisorCheck.tsx b/web/html/src/manager/virtualization/HypervisorCheck.tsx index d7e21284a7e4..2a63369934dd 100644 --- a/web/html/src/manager/virtualization/HypervisorCheck.tsx +++ b/web/html/src/manager/virtualization/HypervisorCheck.tsx @@ -1,7 +1,7 @@ import * as React from "react"; -import { Messages } from "components/messages"; -import { Utils as MessagesUtils } from "components/messages"; +import { Messages } from "components/messages/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; type Props = { hypervisor: string; diff --git a/web/html/src/manager/virtualization/ListTab.tsx b/web/html/src/manager/virtualization/ListTab.tsx index e570efbc60c2..c0d926de5ad5 100644 --- a/web/html/src/manager/virtualization/ListTab.tsx +++ b/web/html/src/manager/virtualization/ListTab.tsx @@ -4,9 +4,9 @@ import { ActionStatus } from "components/action/ActionStatus"; import { Button } from "components/buttons"; import { LinkButton } from "components/buttons"; import { ActionConfirm } from "components/dialog/ActionConfirm"; -import { Messages } from "components/messages"; -import { Utils as MessagesUtils } from "components/messages"; -import { MessageType } from "components/messages"; +import { Messages } from "components/messages/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; +import { MessageType } from "components/messages/messages"; import { Column } from "components/table/Column"; import { SearchField } from "components/table/SearchField"; import { Table } from "components/table/Table"; diff --git a/web/html/src/manager/virtualization/guests/GuestProperties.tsx b/web/html/src/manager/virtualization/guests/GuestProperties.tsx index 85ebb1437b9c..e92fc83e650f 100644 --- a/web/html/src/manager/virtualization/guests/GuestProperties.tsx +++ b/web/html/src/manager/virtualization/guests/GuestProperties.tsx @@ -1,14 +1,14 @@ import * as React from "react"; import { ActionChain } from "components/action-schedule"; -import { Check } from "components/input/Check"; -import { Select } from "components/input/Select"; -import { Text } from "components/input/Text"; -import { MessageType } from "components/messages"; -import { Messages } from "components/messages"; -import { Utils as MessagesUtils } from "components/messages"; +import { Select } from "components/input"; +import { Check } from "components/input/check/Check"; +import { Text } from "components/input/text/Text"; +import { MessageType } from "components/messages/messages"; +import { Messages } from "components/messages/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; import { Panel } from "components/panels/Panel"; -import { Loading } from "components/utils/Loading"; +import { Loading } from "components/utils/loading/Loading"; import Validation from "components/validation"; import { VirtualizationPoolCapsApi } from "../pools/virtualization-pools-capabilities-api"; diff --git a/web/html/src/manager/virtualization/guests/console/MessagePopUp.tsx b/web/html/src/manager/virtualization/guests/console/MessagePopUp.tsx index f964558a94da..83d6772e75a8 100644 --- a/web/html/src/manager/virtualization/guests/console/MessagePopUp.tsx +++ b/web/html/src/manager/virtualization/guests/console/MessagePopUp.tsx @@ -2,10 +2,10 @@ import * as React from "react"; import { Button } from "components/buttons"; import { hideDialog } from "components/dialog/util"; -import { Form } from "components/input/Form"; -import { Password } from "components/input/Password"; +import { Form } from "components/input/form/Form"; +import { Password } from "components/input/password/Password"; import { PopUp } from "components/popup"; -import { Loading } from "components/utils/Loading"; +import { Loading } from "components/utils/loading/Loading"; export type PopupState = "wait" | "askPassword" | "errors"; diff --git a/web/html/src/manager/virtualization/guests/create/guests-create.tsx b/web/html/src/manager/virtualization/guests/create/guests-create.tsx index bf282b9c4e78..5f39f1264827 100644 --- a/web/html/src/manager/virtualization/guests/create/guests-create.tsx +++ b/web/html/src/manager/virtualization/guests/create/guests-create.tsx @@ -3,8 +3,8 @@ import { hot } from "react-hot-loader/root"; import * as React from "react"; import { ActionChain } from "components/action-schedule"; -import { getOrderedItemsFromModel } from "components/input/FormMultiInput"; -import { Utils as MessagesUtils } from "components/messages"; +import { getOrderedItemsFromModel } from "components/input/form-multi-input/FormMultiInput"; +import { Utils as MessagesUtils } from "components/messages/messages"; import { TopPanel } from "components/panels/TopPanel"; import { SimpleActionApi } from "../../SimpleActionApi"; diff --git a/web/html/src/manager/virtualization/guests/edit/guests-edit.tsx b/web/html/src/manager/virtualization/guests/edit/guests-edit.tsx index 740bf88ca2aa..2066080756ed 100644 --- a/web/html/src/manager/virtualization/guests/edit/guests-edit.tsx +++ b/web/html/src/manager/virtualization/guests/edit/guests-edit.tsx @@ -5,9 +5,9 @@ import * as React from "react"; import _isEqual from "lodash/isEqual"; import { ActionChain } from "components/action-schedule"; -import { getOrderedItemsFromModel } from "components/input/FormMultiInput"; +import { getOrderedItemsFromModel } from "components/input/form-multi-input/FormMultiInput"; import { TopPanel } from "components/panels/TopPanel"; -import { Loading } from "components/utils/Loading"; +import { Loading } from "components/utils/loading/Loading"; import { SimpleActionApi } from "../../SimpleActionApi"; import { GuestProperties } from "../GuestProperties"; diff --git a/web/html/src/manager/virtualization/guests/list/MigrateDialog.tsx b/web/html/src/manager/virtualization/guests/list/MigrateDialog.tsx index b80ac45e74c4..c4d0c5436771 100644 --- a/web/html/src/manager/virtualization/guests/list/MigrateDialog.tsx +++ b/web/html/src/manager/virtualization/guests/list/MigrateDialog.tsx @@ -3,8 +3,8 @@ import * as React from "react"; import _isNil from "lodash/isNil"; import { DangerDialog } from "components/dialog/DangerDialog"; -import { Form } from "components/input/Form"; -import { Select } from "components/input/Select"; +import { Select } from "components/input"; +import { Form } from "components/input/form/Form"; type Props = { /** The modal dialog id */ diff --git a/web/html/src/manager/virtualization/guests/properties/GuestDiskFields.tsx b/web/html/src/manager/virtualization/guests/properties/GuestDiskFields.tsx index b963edc05baa..7eff46d12ba4 100644 --- a/web/html/src/manager/virtualization/guests/properties/GuestDiskFields.tsx +++ b/web/html/src/manager/virtualization/guests/properties/GuestDiskFields.tsx @@ -1,9 +1,9 @@ import * as React from "react"; -import { FormContext } from "components/input/Form"; -import { Select } from "components/input/Select"; -import { Messages } from "components/messages"; -import { Utils as MessagesUtils } from "components/messages"; +import { Select } from "components/input"; +import { FormContext } from "components/input/form/Form"; +import { Messages } from "components/messages/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; import { GuestDiskFileFields } from "./GuestDiskFileFields"; import { GuestDiskVolumeFields } from "./GuestDiskVolumeFields"; diff --git a/web/html/src/manager/virtualization/guests/properties/GuestDiskFileFields.tsx b/web/html/src/manager/virtualization/guests/properties/GuestDiskFileFields.tsx index d9a8a4c3cbb3..8675c7debb4f 100644 --- a/web/html/src/manager/virtualization/guests/properties/GuestDiskFileFields.tsx +++ b/web/html/src/manager/virtualization/guests/properties/GuestDiskFileFields.tsx @@ -1,8 +1,8 @@ import * as React from "react"; -import { FormContext } from "components/input/Form"; -import { Select } from "components/input/Select"; -import { Text } from "components/input/Text"; +import { Select } from "components/input"; +import { FormContext } from "components/input/form/Form"; +import { Text } from "components/input/text/Text"; type Props = { index: number; diff --git a/web/html/src/manager/virtualization/guests/properties/GuestDiskVolumeFields.tsx b/web/html/src/manager/virtualization/guests/properties/GuestDiskVolumeFields.tsx index c350d24341e6..b2626180ea94 100644 --- a/web/html/src/manager/virtualization/guests/properties/GuestDiskVolumeFields.tsx +++ b/web/html/src/manager/virtualization/guests/properties/GuestDiskVolumeFields.tsx @@ -1,8 +1,8 @@ import * as React from "react"; -import { FormContext } from "components/input/Form"; -import { Select } from "components/input/Select"; -import { Text } from "components/input/Text"; +import { Select } from "components/input"; +import { FormContext } from "components/input/form/Form"; +import { Text } from "components/input/text/Text"; type Props = { index: number; diff --git a/web/html/src/manager/virtualization/guests/properties/GuestDisksPanel.tsx b/web/html/src/manager/virtualization/guests/properties/GuestDisksPanel.tsx index 396025e99042..dba929a70c8d 100644 --- a/web/html/src/manager/virtualization/guests/properties/GuestDisksPanel.tsx +++ b/web/html/src/manager/virtualization/guests/properties/GuestDisksPanel.tsx @@ -1,10 +1,10 @@ import * as React from "react"; -import { FormContext } from "components/input/Form"; -import { FormMultiInput } from "components/input/FormMultiInput"; -import { getOrderedItemsFromModel } from "components/input/FormMultiInput"; -import { Messages } from "components/messages"; -import { Utils as MessagesUtils } from "components/messages"; +import { FormContext } from "components/input/form/Form"; +import { FormMultiInput } from "components/input/form-multi-input/FormMultiInput"; +import { getOrderedItemsFromModel } from "components/input/form-multi-input/FormMultiInput"; +import { Messages } from "components/messages/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; import { GuestDiskFields } from "./GuestDiskFields"; diff --git a/web/html/src/manager/virtualization/guests/properties/guest-nics-panel.tsx b/web/html/src/manager/virtualization/guests/properties/guest-nics-panel.tsx index bca4766f0ca5..7c787792607e 100644 --- a/web/html/src/manager/virtualization/guests/properties/guest-nics-panel.tsx +++ b/web/html/src/manager/virtualization/guests/properties/guest-nics-panel.tsx @@ -1,11 +1,11 @@ import * as React from "react"; -import { FormMultiInput } from "components/input/FormMultiInput"; -import { getOrderedItemsFromModel } from "components/input/FormMultiInput"; -import { Select } from "components/input/Select"; -import { Text } from "components/input/Text"; -import { Messages } from "components/messages"; -import { Utils as MessagesUtils } from "components/messages"; +import { Select } from "components/input"; +import { FormMultiInput } from "components/input/form-multi-input/FormMultiInput"; +import { getOrderedItemsFromModel } from "components/input/form-multi-input/FormMultiInput"; +import { Text } from "components/input/text/Text"; +import { Messages } from "components/messages/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; function addNic(index: number, model: any, changeModel: Function, networks: Array) { const first_nic = networks.length > 0 ? networks[0].name : ""; diff --git a/web/html/src/manager/virtualization/guests/properties/guest-properties-form.tsx b/web/html/src/manager/virtualization/guests/properties/guest-properties-form.tsx index 61dc5e63ef92..2398cc14caab 100644 --- a/web/html/src/manager/virtualization/guests/properties/guest-properties-form.tsx +++ b/web/html/src/manager/virtualization/guests/properties/guest-properties-form.tsx @@ -3,9 +3,9 @@ import * as React from "react"; import { ActionChain } from "components/action-schedule"; import { ActionSchedule } from "components/action-schedule"; import { Button, SubmitButton } from "components/buttons"; -import { Form } from "components/input/Form"; -import { MessageType } from "components/messages"; -import { Messages } from "components/messages"; +import { Form } from "components/input/form/Form"; +import { MessageType } from "components/messages/messages"; +import { Messages } from "components/messages/messages"; import { Panel } from "components/panels/Panel"; import { localizedMoment } from "utils"; diff --git a/web/html/src/manager/virtualization/guests/properties/guest-properties-traditional.tsx b/web/html/src/manager/virtualization/guests/properties/guest-properties-traditional.tsx index f6c10d2e8826..e3741a5af6ff 100644 --- a/web/html/src/manager/virtualization/guests/properties/guest-properties-traditional.tsx +++ b/web/html/src/manager/virtualization/guests/properties/guest-properties-traditional.tsx @@ -1,9 +1,9 @@ import * as React from "react"; import { ActionChain } from "components/action-schedule"; -import { Text } from "components/input/Text"; -import { MessageType } from "components/messages"; -import { Utils as MessagesUtils } from "components/messages"; +import { Text } from "components/input/text/Text"; +import { MessageType } from "components/messages/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; import { Panel } from "components/panels/Panel"; import Validation from "components/validation"; diff --git a/web/html/src/manager/virtualization/guests/virtualization-domains-caps-api.ts b/web/html/src/manager/virtualization/guests/virtualization-domains-caps-api.ts index 990a9be14dd6..9b85003aba93 100644 --- a/web/html/src/manager/virtualization/guests/virtualization-domains-caps-api.ts +++ b/web/html/src/manager/virtualization/guests/virtualization-domains-caps-api.ts @@ -1,6 +1,6 @@ import * as React from "react"; -import { Utils as MessagesUtils } from "components/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; import Network from "utils/network"; diff --git a/web/html/src/manager/virtualization/guests/virtualization-guest-definition-api.ts b/web/html/src/manager/virtualization/guests/virtualization-guest-definition-api.ts index 94191232ddd1..bc915e07b715 100644 --- a/web/html/src/manager/virtualization/guests/virtualization-guest-definition-api.ts +++ b/web/html/src/manager/virtualization/guests/virtualization-guest-definition-api.ts @@ -1,6 +1,6 @@ import * as React from "react"; -import { Utils as MessagesUtils } from "components/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; import Network from "utils/network"; diff --git a/web/html/src/manager/virtualization/nets/edit/nets-edit.tsx b/web/html/src/manager/virtualization/nets/edit/nets-edit.tsx index 364d0c20ece2..e2ada05310f8 100644 --- a/web/html/src/manager/virtualization/nets/edit/nets-edit.tsx +++ b/web/html/src/manager/virtualization/nets/edit/nets-edit.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import { ActionChain } from "components/action-schedule"; import { TopPanel } from "components/panels/TopPanel"; -import { Loading } from "components/utils/Loading"; +import { Loading } from "components/utils/loading/Loading"; import { SimpleActionApi } from "../../SimpleActionApi"; import { NetworkProperties } from "../network-properties"; diff --git a/web/html/src/manager/virtualization/nets/list/nets-list.tsx b/web/html/src/manager/virtualization/nets/list/nets-list.tsx index a75f0e81f384..b5dc01283492 100644 --- a/web/html/src/manager/virtualization/nets/list/nets-list.tsx +++ b/web/html/src/manager/virtualization/nets/list/nets-list.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import { AsyncButton, LinkButton } from "components/buttons"; -import { Utils as MessagesUtils } from "components/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; import { Column } from "components/table/Column"; import { Utils } from "utils/functions"; diff --git a/web/html/src/manager/virtualization/nets/network-properties.tsx b/web/html/src/manager/virtualization/nets/network-properties.tsx index d54f1ef42e09..b2b1861707b1 100644 --- a/web/html/src/manager/virtualization/nets/network-properties.tsx +++ b/web/html/src/manager/virtualization/nets/network-properties.tsx @@ -5,17 +5,17 @@ import _isNil from "lodash/isNil"; import { ActionChain } from "components/action-schedule"; import { ActionSchedule } from "components/action-schedule"; import { Button, SubmitButton } from "components/buttons"; -import { Check } from "components/input/Check"; -import { Form } from "components/input/Form"; +import { Select } from "components/input"; +import { Check } from "components/input/check/Check"; +import { Form } from "components/input/form/Form"; import { convertNumbers, flattenModel, stripBlankValues, unflattenModel } from "components/input/form-utils"; -import { Radio } from "components/input/Radio"; -import { Range } from "components/input/Range"; -import { Select } from "components/input/Select"; -import { Text } from "components/input/Text"; -import { Messages } from "components/messages"; -import { MessageType } from "components/messages"; +import { Radio } from "components/input/radio/Radio"; +import { Range } from "components/input/range/Range"; +import { Text } from "components/input/text/Text"; +import { Messages } from "components/messages/messages"; +import { MessageType } from "components/messages/messages"; import { Panel } from "components/panels/Panel"; -import { Loading } from "components/utils/Loading"; +import { Loading } from "components/utils/loading/Loading"; import Validation from "components/validation"; import { localizedMoment } from "utils"; diff --git a/web/html/src/manager/virtualization/nets/properties/DnsConfig.tsx b/web/html/src/manager/virtualization/nets/properties/DnsConfig.tsx index 88c7cf9359ee..db0ebec342c6 100644 --- a/web/html/src/manager/virtualization/nets/properties/DnsConfig.tsx +++ b/web/html/src/manager/virtualization/nets/properties/DnsConfig.tsx @@ -1,9 +1,9 @@ import * as React from "react"; -import { FormContext } from "components/input/Form"; -import { FormMultiInput } from "components/input/FormMultiInput"; -import { Select } from "components/input/Select"; -import { Text } from "components/input/Text"; +import { Select } from "components/input"; +import { FormContext } from "components/input/form/Form"; +import { FormMultiInput } from "components/input/form-multi-input/FormMultiInput"; +import { Text } from "components/input/text/Text"; import { Panel } from "components/panels/Panel"; import Validation from "components/validation"; diff --git a/web/html/src/manager/virtualization/nets/properties/IpConfig.tsx b/web/html/src/manager/virtualization/nets/properties/IpConfig.tsx index 4cd57bf1bec3..573e27c211bc 100644 --- a/web/html/src/manager/virtualization/nets/properties/IpConfig.tsx +++ b/web/html/src/manager/virtualization/nets/properties/IpConfig.tsx @@ -2,10 +2,10 @@ import * as React from "react"; import _isNil from "lodash/isNil"; -import { FormContext } from "components/input/Form"; -import { FormMultiInput } from "components/input/FormMultiInput"; -import { Range } from "components/input/Range"; -import { Text } from "components/input/Text"; +import { FormContext } from "components/input/form/Form"; +import { FormMultiInput } from "components/input/form-multi-input/FormMultiInput"; +import { Range } from "components/input/range/Range"; +import { Text } from "components/input/text/Text"; import { Panel } from "components/panels/Panel"; import Validation from "components/validation"; diff --git a/web/html/src/manager/virtualization/nets/properties/NetworkAddress.tsx b/web/html/src/manager/virtualization/nets/properties/NetworkAddress.tsx index 3dbb3769c201..f8f4c29697e4 100644 --- a/web/html/src/manager/virtualization/nets/properties/NetworkAddress.tsx +++ b/web/html/src/manager/virtualization/nets/properties/NetworkAddress.tsx @@ -1,6 +1,6 @@ import * as React from "react"; -import { FormContext } from "components/input/Form"; +import { FormContext } from "components/input/form/Form"; import { InputBase } from "components/input/InputBase"; import Validation from "components/validation"; diff --git a/web/html/src/manager/virtualization/nets/properties/VirtualPortFields.tsx b/web/html/src/manager/virtualization/nets/properties/VirtualPortFields.tsx index 321ca5efae6d..8dc310f3042d 100644 --- a/web/html/src/manager/virtualization/nets/properties/VirtualPortFields.tsx +++ b/web/html/src/manager/virtualization/nets/properties/VirtualPortFields.tsx @@ -1,8 +1,8 @@ import * as React from "react"; -import { FormContext } from "components/input/Form"; -import { Radio } from "components/input/Radio"; -import { Text } from "components/input/Text"; +import { FormContext } from "components/input/form/Form"; +import { Radio } from "components/input/radio/Radio"; +import { Text } from "components/input/text/Text"; import Validation from "components/validation"; import * as utils from "./utils"; diff --git a/web/html/src/manager/virtualization/nets/properties/Vlans.tsx b/web/html/src/manager/virtualization/nets/properties/Vlans.tsx index 04ff0c399809..9f561bed3a56 100644 --- a/web/html/src/manager/virtualization/nets/properties/Vlans.tsx +++ b/web/html/src/manager/virtualization/nets/properties/Vlans.tsx @@ -1,9 +1,9 @@ import * as React from "react"; -import { FormContext } from "components/input/Form"; -import { FormMultiInput } from "components/input/FormMultiInput"; -import { Select } from "components/input/Select"; -import { Text } from "components/input/Text"; +import { Select } from "components/input"; +import { FormContext } from "components/input/form/Form"; +import { FormMultiInput } from "components/input/form-multi-input/FormMultiInput"; +import { Text } from "components/input/text/Text"; import Validation from "components/validation"; type Props = {}; diff --git a/web/html/src/manager/virtualization/nets/virtualization-network-definition-api.tsx b/web/html/src/manager/virtualization/nets/virtualization-network-definition-api.tsx index 4505a5542c8a..aa237d328dda 100644 --- a/web/html/src/manager/virtualization/nets/virtualization-network-definition-api.tsx +++ b/web/html/src/manager/virtualization/nets/virtualization-network-definition-api.tsx @@ -1,7 +1,7 @@ import * as React from "react"; -import * as Messages from "components/messages"; -import { MessageType } from "components/messages"; +import * as Messages from "components/messages/messages"; +import { MessageType } from "components/messages/messages"; import Network from "utils/network"; diff --git a/web/html/src/manager/virtualization/nets/virtualization-network-devs-api.ts b/web/html/src/manager/virtualization/nets/virtualization-network-devs-api.ts index a9f3a42e18f9..33446df623ed 100644 --- a/web/html/src/manager/virtualization/nets/virtualization-network-devs-api.ts +++ b/web/html/src/manager/virtualization/nets/virtualization-network-devs-api.ts @@ -1,6 +1,6 @@ import * as React from "react"; -import * as Messages from "components/messages"; +import * as Messages from "components/messages/messages"; import Network from "utils/network"; diff --git a/web/html/src/manager/virtualization/pools/edit/pools-edit.tsx b/web/html/src/manager/virtualization/pools/edit/pools-edit.tsx index e2c7a8ab4017..1d352a7e948a 100644 --- a/web/html/src/manager/virtualization/pools/edit/pools-edit.tsx +++ b/web/html/src/manager/virtualization/pools/edit/pools-edit.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import { ActionChain } from "components/action-schedule"; import { TopPanel } from "components/panels/TopPanel"; -import { Loading } from "components/utils/Loading"; +import { Loading } from "components/utils/loading/Loading"; import { PoolProperties } from "../pool-properties"; import { VirtualizationPoolDefinitionApi } from "../virtualization-pool-definition-api"; diff --git a/web/html/src/manager/virtualization/pools/list/pools-list.tsx b/web/html/src/manager/virtualization/pools/list/pools-list.tsx index 72e6ff5ec0f0..bf9ecdd8b432 100644 --- a/web/html/src/manager/virtualization/pools/list/pools-list.tsx +++ b/web/html/src/manager/virtualization/pools/list/pools-list.tsx @@ -6,9 +6,9 @@ import { Button } from "components/buttons"; import { AsyncButton } from "components/buttons"; import { CustomDiv } from "components/custom-objects"; import { ActionConfirm } from "components/dialog/ActionConfirm"; -import { Messages } from "components/messages"; -import { Utils as MessagesUtils } from "components/messages"; -import { MessageType } from "components/messages"; +import { Messages } from "components/messages/messages"; +import { Utils as MessagesUtils } from "components/messages/messages"; +import { MessageType } from "components/messages/messages"; import { ProgressBar } from "components/progressbar"; import { CustomDataHandler } from "components/table/CustomDataHandler"; import { SearchField } from "components/table/SearchField"; diff --git a/web/html/src/manager/virtualization/pools/pool-properties.tsx b/web/html/src/manager/virtualization/pools/pool-properties.tsx index bb61f3106fb0..7d5384930947 100644 --- a/web/html/src/manager/virtualization/pools/pool-properties.tsx +++ b/web/html/src/manager/virtualization/pools/pool-properties.tsx @@ -3,18 +3,18 @@ import * as React from "react"; import { ActionChain } from "components/action-schedule"; import { ActionSchedule } from "components/action-schedule"; import { Button, SubmitButton } from "components/buttons"; -import { Check } from "components/input/Check"; -import { Form } from "components/input/Form"; +import { Select } from "components/input"; +import { Check } from "components/input/check/Check"; +import { Form } from "components/input/form/Form"; +import { FormMultiInput } from "components/input/form-multi-input/FormMultiInput"; import { flattenModel, unflattenModel } from "components/input/form-utils"; -import { FormMultiInput } from "components/input/FormMultiInput"; -import { Password } from "components/input/Password"; -import { Select } from "components/input/Select"; -import { Text } from "components/input/Text"; -import { Messages } from "components/messages"; -import { MessageType } from "components/messages"; +import { Password } from "components/input/password/Password"; +import { Text } from "components/input/text/Text"; +import { Messages } from "components/messages/messages"; +import { MessageType } from "components/messages/messages"; import { Panel } from "components/panels/Panel"; import { PanelRow } from "components/panels/PanelRow"; -import { Loading } from "components/utils/Loading"; +import { Loading } from "components/utils/loading/Loading"; import Validation from "components/validation"; import { localizedMoment } from "utils"; diff --git a/web/html/src/manager/virtualization/pools/virtualization-pool-definition-api.tsx b/web/html/src/manager/virtualization/pools/virtualization-pool-definition-api.tsx index 3359cb38af82..cd38447fd8bd 100644 --- a/web/html/src/manager/virtualization/pools/virtualization-pool-definition-api.tsx +++ b/web/html/src/manager/virtualization/pools/virtualization-pool-definition-api.tsx @@ -1,7 +1,7 @@ import * as React from "react"; -import * as Messages from "components/messages"; -import { MessageType } from "components/messages"; +import * as Messages from "components/messages/messages"; +import { MessageType } from "components/messages/messages"; import Network from "utils/network"; diff --git a/web/html/src/manager/virtualization/pools/virtualization-pools-action-api.tsx b/web/html/src/manager/virtualization/pools/virtualization-pools-action-api.tsx index 71929f9f900c..7a72d207b3d9 100644 --- a/web/html/src/manager/virtualization/pools/virtualization-pools-action-api.tsx +++ b/web/html/src/manager/virtualization/pools/virtualization-pools-action-api.tsx @@ -1,6 +1,6 @@ import * as React from "react"; -import { MessageType } from "components/messages"; +import { MessageType } from "components/messages/messages"; import { ActionApi } from "../ActionApi"; diff --git a/web/html/src/manager/virtualization/pools/virtualization-pools-capabilities-api.ts b/web/html/src/manager/virtualization/pools/virtualization-pools-capabilities-api.ts index d443729f0b62..5bef6070b6a1 100644 --- a/web/html/src/manager/virtualization/pools/virtualization-pools-capabilities-api.ts +++ b/web/html/src/manager/virtualization/pools/virtualization-pools-capabilities-api.ts @@ -1,6 +1,6 @@ import * as React from "react"; -import * as Messages from "components/messages"; +import * as Messages from "components/messages/messages"; import Network from "utils/network"; diff --git a/web/html/src/object.d.ts b/web/html/src/object.d.ts new file mode 100644 index 000000000000..1608d5518e1f --- /dev/null +++ b/web/html/src/object.d.ts @@ -0,0 +1,21 @@ +// See https://stackoverflow.com/a/77724124/1470607 +interface ObjectConstructor { + /** + * Groups members of an iterable according to the return value of the passed callback. + * @param items An iterable. + * @param keySelector A callback which will be invoked for each item in items. + */ + groupBy( + items: Iterable, + keySelector: (item: T, index: number) => K + ): Partial>; +} + +interface MapConstructor { + /** + * Groups members of an iterable according to the return value of the passed callback. + * @param items An iterable. + * @param keySelector A callback which will be invoked for each item in items. + */ + groupBy(items: Iterable, keySelector: (item: T, index: number) => K): Map; +} diff --git a/web/html/src/tsconfig.json b/web/html/src/tsconfig.json index f233022cf417..3f0be650db25 100644 --- a/web/html/src/tsconfig.json +++ b/web/html/src/tsconfig.json @@ -10,7 +10,8 @@ "utils/**/*.tsx", "global.d.ts", "imports.d.ts", - "lib.es5.d.ts" + "lib.es5.d.ts", + "object.d.ts" ], "exclude": ["**/node_modules", "**/\\.*/"], "compilerOptions": { diff --git a/web/html/src/utils/network.ts b/web/html/src/utils/network.ts index 5a9904ce67d3..aba2a5975ee9 100644 --- a/web/html/src/utils/network.ts +++ b/web/html/src/utils/network.ts @@ -1,4 +1,4 @@ -import { MessageType, Utils as MessagesUtils } from "components/messages"; +import { MessageType, Utils as MessagesUtils } from "components/messages/messages"; import { showErrorToastr } from "components/toastr"; import { Utils } from "utils/functions"; diff --git a/web/spacewalk-web.changes.eth.ui-debug b/web/spacewalk-web.changes.eth.ui-debug new file mode 100644 index 000000000000..d03887491585 --- /dev/null +++ b/web/spacewalk-web.changes.eth.ui-debug @@ -0,0 +1 @@ +- Integrate ui debugging stories