@flightctl/ui-components 1.1.0-rc1 → 1.1.0-rc3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/components/Repository/CreateRepository/CreateRepositoryForm.css +5 -1
- package/dist/types/imagebuilder/index.d.ts +2 -0
- package/dist/types/imagebuilder/index.d.ts.map +1 -1
- package/dist/types/imagebuilder/index.js +3 -1
- package/dist/types/imagebuilder/index.js.map +1 -1
- package/dist/types/imagebuilder/models/ApiVersion.d.ts +8 -0
- package/dist/types/imagebuilder/models/ApiVersion.d.ts.map +1 -0
- package/dist/types/imagebuilder/models/ApiVersion.js +16 -0
- package/dist/types/imagebuilder/models/ApiVersion.js.map +1 -0
- package/dist/types/imagebuilder/models/ImageBuild.d.ts +2 -4
- package/dist/types/imagebuilder/models/ImageBuild.d.ts.map +1 -1
- package/dist/types/imagebuilder/models/ImageBuildList.d.ts +2 -4
- package/dist/types/imagebuilder/models/ImageBuildList.d.ts.map +1 -1
- package/dist/types/imagebuilder/models/ImageExport.d.ts +2 -4
- package/dist/types/imagebuilder/models/ImageExport.d.ts.map +1 -1
- package/dist/types/imagebuilder/models/ImageExportList.d.ts +2 -4
- package/dist/types/imagebuilder/models/ImageExportList.d.ts.map +1 -1
- package/dist/types/imagebuilder/models/Status.d.ts +28 -0
- package/dist/types/imagebuilder/models/Status.d.ts.map +1 -0
- package/dist/types/imagebuilder/models/Status.js +3 -0
- package/dist/types/imagebuilder/models/Status.js.map +1 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +3 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/models/ApiVersion.d.ts +9 -0
- package/dist/types/models/ApiVersion.d.ts.map +1 -0
- package/dist/types/models/ApiVersion.js +17 -0
- package/dist/types/models/ApiVersion.js.map +1 -0
- package/dist/types/models/ApplicationProviderBase.d.ts +12 -0
- package/dist/types/models/ApplicationProviderBase.d.ts.map +1 -0
- package/dist/types/models/ApplicationProviderBase.js +3 -0
- package/dist/types/models/ApplicationProviderBase.js.map +1 -0
- package/dist/types/models/ApplicationProviderSpec.d.ts +5 -15
- package/dist/types/models/ApplicationProviderSpec.d.ts.map +1 -1
- package/dist/types/models/ApplicationUser.d.ts +7 -0
- package/dist/types/models/ApplicationUser.d.ts.map +1 -0
- package/dist/types/models/ApplicationUser.js +3 -0
- package/dist/types/models/ApplicationUser.js.map +1 -0
- package/dist/types/models/AuthConfig.d.ts +2 -4
- package/dist/types/models/AuthConfig.d.ts.map +1 -1
- package/dist/types/models/AuthProvider.d.ts +2 -4
- package/dist/types/models/AuthProvider.d.ts.map +1 -1
- package/dist/types/models/AuthProviderList.d.ts +2 -4
- package/dist/types/models/AuthProviderList.d.ts.map +1 -1
- package/dist/types/models/CertificateSigningRequest.d.ts +2 -4
- package/dist/types/models/CertificateSigningRequest.d.ts.map +1 -1
- package/dist/types/models/CertificateSigningRequestList.d.ts +2 -4
- package/dist/types/models/CertificateSigningRequestList.d.ts.map +1 -1
- package/dist/types/models/ComposeApplication.d.ts +7 -0
- package/dist/types/models/ComposeApplication.d.ts.map +1 -0
- package/dist/types/models/ComposeApplication.js +3 -0
- package/dist/types/models/ComposeApplication.js.map +1 -0
- package/dist/types/models/ContainerApplication.d.ts +18 -0
- package/dist/types/models/ContainerApplication.d.ts.map +1 -0
- package/dist/types/models/ContainerApplication.js +3 -0
- package/dist/types/models/ContainerApplication.js.map +1 -0
- package/dist/types/models/ContainerApplicationProperties.d.ts +13 -0
- package/dist/types/models/ContainerApplicationProperties.d.ts.map +1 -0
- package/dist/types/models/ContainerApplicationProperties.js +3 -0
- package/dist/types/models/ContainerApplicationProperties.js.map +1 -0
- package/dist/types/models/Device.d.ts +2 -4
- package/dist/types/models/Device.d.ts.map +1 -1
- package/dist/types/models/DeviceList.d.ts +2 -4
- package/dist/types/models/DeviceList.d.ts.map +1 -1
- package/dist/types/models/EnrollmentRequest.d.ts +2 -4
- package/dist/types/models/EnrollmentRequest.d.ts.map +1 -1
- package/dist/types/models/EnrollmentRequestList.d.ts +2 -4
- package/dist/types/models/EnrollmentRequestList.d.ts.map +1 -1
- package/dist/types/models/Event.d.ts +2 -4
- package/dist/types/models/Event.d.ts.map +1 -1
- package/dist/types/models/Event.js.map +1 -1
- package/dist/types/models/EventList.d.ts +2 -4
- package/dist/types/models/EventList.d.ts.map +1 -1
- package/dist/types/models/Fleet.d.ts +2 -4
- package/dist/types/models/Fleet.d.ts.map +1 -1
- package/dist/types/models/FleetList.d.ts +2 -4
- package/dist/types/models/FleetList.d.ts.map +1 -1
- package/dist/types/models/HelmApplication.d.ts +20 -0
- package/dist/types/models/HelmApplication.d.ts.map +1 -0
- package/dist/types/models/HelmApplication.js +3 -0
- package/dist/types/models/HelmApplication.js.map +1 -0
- package/dist/types/models/ImageApplicationProviderSpec.d.ts +2 -22
- package/dist/types/models/ImageApplicationProviderSpec.d.ts.map +1 -1
- package/dist/types/models/InlineApplicationProviderSpec.d.ts +2 -3
- package/dist/types/models/InlineApplicationProviderSpec.d.ts.map +1 -1
- package/dist/types/models/Organization.d.ts +2 -4
- package/dist/types/models/Organization.d.ts.map +1 -1
- package/dist/types/models/OrganizationList.d.ts +2 -4
- package/dist/types/models/OrganizationList.d.ts.map +1 -1
- package/dist/types/models/QuadletApplication.d.ts +8 -0
- package/dist/types/models/QuadletApplication.d.ts.map +1 -0
- package/dist/types/models/QuadletApplication.js +3 -0
- package/dist/types/models/QuadletApplication.js.map +1 -0
- package/dist/types/models/Repository.d.ts +2 -4
- package/dist/types/models/Repository.d.ts.map +1 -1
- package/dist/types/models/RepositoryList.d.ts +2 -4
- package/dist/types/models/RepositoryList.d.ts.map +1 -1
- package/dist/types/models/ResourceSync.d.ts +2 -4
- package/dist/types/models/ResourceSync.d.ts.map +1 -1
- package/dist/types/models/ResourceSyncList.d.ts +2 -4
- package/dist/types/models/ResourceSyncList.d.ts.map +1 -1
- package/dist/types/models/Status.d.ts +2 -4
- package/dist/types/models/Status.d.ts.map +1 -1
- package/dist/types/models/TemplateVersion.d.ts +2 -4
- package/dist/types/models/TemplateVersion.d.ts.map +1 -1
- package/dist/types/models/TemplateVersionList.d.ts +2 -4
- package/dist/types/models/TemplateVersionList.d.ts.map +1 -1
- package/dist/ui-components/src/components/AuthProvider/CreateAuthProvider/utils.d.ts.map +1 -1
- package/dist/ui-components/src/components/AuthProvider/CreateAuthProvider/utils.js +51 -51
- package/dist/ui-components/src/components/AuthProvider/CreateAuthProvider/utils.js.map +1 -1
- package/dist/ui-components/src/components/DetailsPage/Tables/ApplicationsTable.js +1 -1
- package/dist/ui-components/src/components/DetailsPage/Tables/ApplicationsTable.js.map +1 -1
- package/dist/ui-components/src/components/Device/DeviceDetails/DeviceDetailsPage.d.ts.map +1 -1
- package/dist/ui-components/src/components/Device/DeviceDetails/DeviceDetailsPage.js +5 -4
- package/dist/ui-components/src/components/Device/DeviceDetails/DeviceDetailsPage.js.map +1 -1
- package/dist/ui-components/src/components/Device/DeviceDetails/TerminalTab.d.ts.map +1 -1
- package/dist/ui-components/src/components/Device/DeviceDetails/TerminalTab.js +5 -1
- package/dist/ui-components/src/components/Device/DeviceDetails/TerminalTab.js.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/deviceSpecUtils.d.ts +3 -3
- package/dist/ui-components/src/components/Device/EditDeviceWizard/deviceSpecUtils.d.ts.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/deviceSpecUtils.js +310 -363
- package/dist/ui-components/src/components/Device/EditDeviceWizard/deviceSpecUtils.js.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationContainerForm.d.ts +1 -3
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationContainerForm.d.ts.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationContainerForm.js +18 -19
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationContainerForm.js.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationHelmForm.d.ts +1 -3
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationHelmForm.d.ts.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationHelmForm.js +5 -4
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationHelmForm.js.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationImageForm.d.ts +1 -3
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationImageForm.d.ts.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationImageForm.js +2 -2
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationImageForm.js.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationInlineForm.d.ts +3 -3
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationInlineForm.d.ts.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationInlineForm.js +20 -23
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationInlineForm.js.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationIntegritySettings.js +3 -3
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationIntegritySettings.js.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationTemplates.d.ts.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationTemplates.js +25 -45
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationTemplates.js.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVariablesForm.d.ts +8 -0
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVariablesForm.d.ts.map +1 -0
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVariablesForm.js +37 -0
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVariablesForm.js.map +1 -0
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVolumeForm.d.ts +1 -3
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVolumeForm.d.ts.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVolumeForm.js +5 -8
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVolumeForm.js.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/utils.d.ts +18 -18
- package/dist/ui-components/src/components/ErrorAlert/ErrorAlert.d.ts +4 -2
- package/dist/ui-components/src/components/ErrorAlert/ErrorAlert.d.ts.map +1 -1
- package/dist/ui-components/src/components/ErrorAlert/ErrorAlert.js +2 -2
- package/dist/ui-components/src/components/ErrorAlert/ErrorAlert.js.map +1 -1
- package/dist/ui-components/src/components/Fleet/CreateFleet/utils.d.ts +1 -1
- package/dist/ui-components/src/components/Fleet/CreateFleet/utils.d.ts.map +1 -1
- package/dist/ui-components/src/components/Fleet/CreateFleet/utils.js +3 -3
- package/dist/ui-components/src/components/Fleet/CreateFleet/utils.js.map +1 -1
- package/dist/ui-components/src/components/Fleet/ImportFleetWizard/steps/RepositoryStep.d.ts.map +1 -1
- package/dist/ui-components/src/components/Fleet/ImportFleetWizard/steps/RepositoryStep.js +3 -1
- package/dist/ui-components/src/components/Fleet/ImportFleetWizard/steps/RepositoryStep.js.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/CancelImageBuildModal/CancelImageBuildModal.d.ts +7 -0
- package/dist/ui-components/src/components/ImageBuilds/CancelImageBuildModal/CancelImageBuildModal.d.ts.map +1 -0
- package/dist/ui-components/src/components/ImageBuilds/CancelImageBuildModal/CancelImageBuildModal.js +40 -0
- package/dist/ui-components/src/components/ImageBuilds/CancelImageBuildModal/CancelImageBuildModal.js.map +1 -0
- package/dist/ui-components/src/components/ImageBuilds/ConfirmImageExportModal/ConfirmImageExportModal.d.ts +8 -0
- package/dist/ui-components/src/components/ImageBuilds/ConfirmImageExportModal/ConfirmImageExportModal.d.ts.map +1 -0
- package/dist/ui-components/src/components/ImageBuilds/ConfirmImageExportModal/ConfirmImageExportModal.js +37 -0
- package/dist/ui-components/src/components/ImageBuilds/ConfirmImageExportModal/ConfirmImageExportModal.js.map +1 -0
- package/dist/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/CreateImageBuildWizard.d.ts.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/CreateImageBuildWizard.js +4 -3
- package/dist/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/CreateImageBuildWizard.js.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/steps/OutputImageStep.js +1 -1
- package/dist/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/steps/OutputImageStep.js.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/steps/RegistrationStep.d.ts.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/steps/RegistrationStep.js +13 -10
- package/dist/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/steps/RegistrationStep.js.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/steps/ReviewStep.d.ts.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/steps/ReviewStep.js +4 -2
- package/dist/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/steps/ReviewStep.js.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/steps/SourceImageStep.d.ts.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/steps/SourceImageStep.js +7 -1
- package/dist/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/steps/SourceImageStep.js.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/types.d.ts +3 -5
- package/dist/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/types.d.ts.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/utils.d.ts +3 -2
- package/dist/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/utils.d.ts.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/utils.js +139 -34
- package/dist/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/utils.js.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildDetails/ImageBuildDetailsPage.d.ts.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildDetails/ImageBuildDetailsPage.js +23 -12
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildDetails/ImageBuildDetailsPage.js.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildDetails/ImageBuildExportsGallery.d.ts.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildDetails/ImageBuildExportsGallery.js +115 -39
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildDetails/ImageBuildExportsGallery.js.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildDetails/ImageBuildLogsTab.d.ts +1 -0
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildDetails/ImageBuildLogsTab.d.ts.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildDetails/ImageBuildLogsTab.js +17 -18
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildDetails/ImageBuildLogsTab.js.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildRow.d.ts +5 -2
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildRow.d.ts.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildRow.js +22 -12
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildRow.js.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildsPage.d.ts.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildsPage.js +17 -8
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildsPage.js.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageExportCards.d.ts +10 -9
- package/dist/ui-components/src/components/ImageBuilds/ImageExportCards.d.ts.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageExportCards.js +122 -26
- package/dist/ui-components/src/components/ImageBuilds/ImageExportCards.js.map +1 -1
- package/dist/ui-components/src/components/Repository/CreateRepository/CreateRepositoryForm.d.ts +2 -1
- package/dist/ui-components/src/components/Repository/CreateRepository/CreateRepositoryForm.d.ts.map +1 -1
- package/dist/ui-components/src/components/Repository/CreateRepository/CreateRepositoryForm.js +10 -4
- package/dist/ui-components/src/components/Repository/CreateRepository/CreateRepositoryForm.js.map +1 -1
- package/dist/ui-components/src/components/Repository/CreateRepository/utils.d.ts.map +1 -1
- package/dist/ui-components/src/components/Repository/CreateRepository/utils.js +3 -4
- package/dist/ui-components/src/components/Repository/CreateRepository/utils.js.map +1 -1
- package/dist/ui-components/src/components/form/RepositorySelect.d.ts.map +1 -1
- package/dist/ui-components/src/components/form/RepositorySelect.js +1 -1
- package/dist/ui-components/src/components/form/RepositorySelect.js.map +1 -1
- package/dist/ui-components/src/components/form/UploadField.d.ts.map +1 -1
- package/dist/ui-components/src/components/form/UploadField.js +25 -16
- package/dist/ui-components/src/components/form/UploadField.js.map +1 -1
- package/dist/ui-components/src/components/form/validations.d.ts +25 -18
- package/dist/ui-components/src/components/form/validations.d.ts.map +1 -1
- package/dist/ui-components/src/components/form/validations.js +79 -33
- package/dist/ui-components/src/components/form/validations.js.map +1 -1
- package/dist/ui-components/src/components/modals/CreateRepositoryModal/CreateRepositoryModal.d.ts +2 -1
- package/dist/ui-components/src/components/modals/CreateRepositoryModal/CreateRepositoryModal.d.ts.map +1 -1
- package/dist/ui-components/src/components/modals/CreateRepositoryModal/CreateRepositoryModal.js +2 -2
- package/dist/ui-components/src/components/modals/CreateRepositoryModal/CreateRepositoryModal.js.map +1 -1
- package/dist/ui-components/src/constants.d.ts +5 -6
- package/dist/ui-components/src/constants.d.ts.map +1 -1
- package/dist/ui-components/src/constants.js +19 -11
- package/dist/ui-components/src/constants.js.map +1 -1
- package/dist/ui-components/src/hooks/useWebSocket.d.ts.map +1 -1
- package/dist/ui-components/src/hooks/useWebSocket.js +25 -4
- package/dist/ui-components/src/hooks/useWebSocket.js.map +1 -1
- package/dist/ui-components/src/types/deviceSpec.d.ts +44 -76
- package/dist/ui-components/src/types/deviceSpec.d.ts.map +1 -1
- package/dist/ui-components/src/types/deviceSpec.js +13 -26
- package/dist/ui-components/src/types/deviceSpec.js.map +1 -1
- package/dist/ui-components/src/types/extraTypes.d.ts +1 -7
- package/dist/ui-components/src/types/extraTypes.d.ts.map +1 -1
- package/dist/ui-components/src/types/extraTypes.js.map +1 -1
- package/dist/ui-components/src/types/rbac.d.ts +7 -1
- package/dist/ui-components/src/types/rbac.d.ts.map +1 -1
- package/dist/ui-components/src/types/rbac.js +6 -0
- package/dist/ui-components/src/types/rbac.js.map +1 -1
- package/dist/ui-components/src/utils/imageBuilds.d.ts +1 -0
- package/dist/ui-components/src/utils/imageBuilds.d.ts.map +1 -1
- package/dist/ui-components/src/utils/imageBuilds.js +20 -29
- package/dist/ui-components/src/utils/imageBuilds.js.map +1 -1
- package/dist/ui-components/src/utils/search.d.ts +2 -1
- package/dist/ui-components/src/utils/search.d.ts.map +1 -1
- package/dist/ui-components/src/utils/search.js +2 -2
- package/dist/ui-components/src/utils/search.js.map +1 -1
- package/package.json +2 -2
- package/src/components/AuthProvider/CreateAuthProvider/utils.ts +2 -2
- package/src/components/DetailsPage/Tables/ApplicationsTable.tsx +2 -2
- package/src/components/Device/DeviceDetails/DeviceDetailsPage.tsx +10 -4
- package/src/components/Device/DeviceDetails/TerminalTab.tsx +9 -1
- package/src/components/Device/EditDeviceWizard/deviceSpecUtils.ts +361 -425
- package/src/components/Device/EditDeviceWizard/steps/ApplicationContainerForm.tsx +19 -29
- package/src/components/Device/EditDeviceWizard/steps/ApplicationHelmForm.tsx +5 -13
- package/src/components/Device/EditDeviceWizard/steps/ApplicationImageForm.tsx +2 -16
- package/src/components/Device/EditDeviceWizard/steps/ApplicationInlineForm.tsx +8 -7
- package/src/components/Device/EditDeviceWizard/steps/ApplicationIntegritySettings.tsx +5 -5
- package/src/components/Device/EditDeviceWizard/steps/ApplicationTemplates.tsx +29 -101
- package/src/components/Device/EditDeviceWizard/steps/ApplicationVariablesForm.tsx +87 -0
- package/src/components/Device/EditDeviceWizard/steps/ApplicationVolumeForm.tsx +5 -10
- package/src/components/ErrorAlert/ErrorAlert.tsx +13 -3
- package/src/components/Fleet/CreateFleet/utils.ts +4 -5
- package/src/components/Fleet/ImportFleetWizard/steps/RepositoryStep.tsx +11 -8
- package/src/components/ImageBuilds/CancelImageBuildModal/CancelImageBuildModal.tsx +81 -0
- package/src/components/ImageBuilds/ConfirmImageExportModal/ConfirmImageExportModal.tsx +61 -0
- package/src/components/ImageBuilds/CreateImageBuildWizard/CreateImageBuildWizard.tsx +8 -3
- package/src/components/ImageBuilds/CreateImageBuildWizard/steps/OutputImageStep.tsx +1 -1
- package/src/components/ImageBuilds/CreateImageBuildWizard/steps/RegistrationStep.tsx +18 -10
- package/src/components/ImageBuilds/CreateImageBuildWizard/steps/ReviewStep.tsx +5 -1
- package/src/components/ImageBuilds/CreateImageBuildWizard/steps/SourceImageStep.tsx +13 -1
- package/src/components/ImageBuilds/CreateImageBuildWizard/types.ts +3 -6
- package/src/components/ImageBuilds/CreateImageBuildWizard/utils.ts +161 -37
- package/src/components/ImageBuilds/ImageBuildDetails/ImageBuildDetailsPage.tsx +36 -17
- package/src/components/ImageBuilds/ImageBuildDetails/ImageBuildExportsGallery.tsx +131 -44
- package/src/components/ImageBuilds/ImageBuildDetails/ImageBuildLogsTab.tsx +22 -26
- package/src/components/ImageBuilds/ImageBuildRow.tsx +41 -20
- package/src/components/ImageBuilds/ImageBuildsPage.tsx +34 -15
- package/src/components/ImageBuilds/ImageExportCards.tsx +198 -80
- package/src/components/Repository/CreateRepository/CreateRepositoryForm.css +5 -1
- package/src/components/Repository/CreateRepository/CreateRepositoryForm.tsx +14 -4
- package/src/components/Repository/CreateRepository/utils.ts +4 -4
- package/src/components/form/RepositorySelect.tsx +1 -0
- package/src/components/form/UploadField.tsx +29 -30
- package/src/components/form/validations.ts +156 -106
- package/src/components/modals/CreateRepositoryModal/CreateRepositoryModal.tsx +3 -1
- package/src/constants.ts +19 -6
- package/src/hooks/useWebSocket.ts +25 -3
- package/src/types/deviceSpec.ts +68 -108
- package/src/types/extraTypes.ts +2 -12
- package/src/types/rbac.ts +6 -0
- package/src/utils/imageBuilds.ts +22 -32
- package/src/utils/search.ts +2 -2
|
@@ -10,31 +10,25 @@ import {
|
|
|
10
10
|
AppSpecType,
|
|
11
11
|
BatchForm,
|
|
12
12
|
BatchLimitType,
|
|
13
|
-
|
|
14
|
-
ComposeInlineAppForm,
|
|
13
|
+
ComposeAppForm,
|
|
15
14
|
DisruptionBudgetForm,
|
|
16
15
|
GitConfigTemplate,
|
|
17
|
-
|
|
16
|
+
HelmAppForm,
|
|
18
17
|
HttpConfigTemplate,
|
|
19
18
|
InlineConfigTemplate,
|
|
19
|
+
InlineFileForm,
|
|
20
20
|
KubeSecretTemplate,
|
|
21
21
|
PortMapping,
|
|
22
|
-
|
|
23
|
-
QuadletInlineAppForm,
|
|
22
|
+
QuadletAppForm,
|
|
24
23
|
RolloutPolicyForm,
|
|
25
24
|
SpecConfigTemplate,
|
|
26
25
|
SystemdUnitFormValue,
|
|
27
26
|
UpdatePolicyForm,
|
|
28
27
|
getAppIdentifier,
|
|
29
|
-
isComposeImageAppForm,
|
|
30
28
|
isGitConfigTemplate,
|
|
31
|
-
isHelmImageAppForm,
|
|
32
29
|
isHttpConfigTemplate,
|
|
33
30
|
isInlineConfigTemplate,
|
|
34
31
|
isKubeSecretTemplate,
|
|
35
|
-
isQuadletImageAppForm,
|
|
36
|
-
isQuadletInlineAppForm,
|
|
37
|
-
isSingleContainerAppForm,
|
|
38
32
|
} from '../../types/deviceSpec';
|
|
39
33
|
import { labelToString } from '../../utils/labels';
|
|
40
34
|
import { UpdateScheduleMode } from '../../utils/time';
|
|
@@ -53,9 +47,9 @@ const K8S_DNS_SUBDOMAIN_START_END = /^[a-z0-9](.*[a-z0-9])?$/;
|
|
|
53
47
|
const K8S_DNS_SUBDOMAIN_ALLOWED_CHARACTERS = /^[a-z0-9.-]*$/;
|
|
54
48
|
const K8S_DNS_SUBDOMAIN_VALUE_MAX_LENGTH = 253;
|
|
55
49
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const
|
|
50
|
+
const OCI_IMAGE_FULL_REGEXP = /^(?![./_])[a-zA-Z0-9.\-\/:@_+]*$/;
|
|
51
|
+
// Accepts all characters from the above regex, but it rejects leading dot, slash, or underscore
|
|
52
|
+
const OCI_IMAGE_ALLOWED_CHARS_REGEXP = /^[a-zA-Z0-9.\-\/:@_+]*$/;
|
|
59
53
|
const APPLICATION_NAME_REGEXP = /^[a-z0-9]([-a-z0-9]*[a-z0-9])?$/;
|
|
60
54
|
const APPLICATION_VAR_NAME_REGEXP = /^[a-zA-Z_]+[a-zA-Z0-9_]*$/;
|
|
61
55
|
|
|
@@ -74,6 +68,9 @@ const relativePathRegex = /^(?!\.\.\/|\.\.\$|\.\/)(\.\/)*[\w.-]+(?:\/[\w.-]+)*\/
|
|
|
74
68
|
export const MAX_TARGET_REVISION_LENGTH = 244;
|
|
75
69
|
const MAX_FILE_PATH_LENGTH = 253;
|
|
76
70
|
|
|
71
|
+
const HELM_NAMESPACE_MAX_LENGTH = 63;
|
|
72
|
+
const HELM_VALUES_FILE_EXT_REGEXP = /\.(yaml|yml)$/i;
|
|
73
|
+
|
|
77
74
|
const isInteger = (val: number | undefined) => val === undefined || Number.isInteger(val);
|
|
78
75
|
|
|
79
76
|
const validComposeFileNames = [
|
|
@@ -233,6 +230,23 @@ export const validApplicationAndVolumeName = (t: TFunction) =>
|
|
|
233
230
|
t('Use lowercase alphanumeric characters, or dash (-). Must start and end with an alphanumeric character.'),
|
|
234
231
|
);
|
|
235
232
|
|
|
233
|
+
export const getBuildNameValidations = (t: TFunction) => [
|
|
234
|
+
{
|
|
235
|
+
key: 'imageBuildName',
|
|
236
|
+
message: t(
|
|
237
|
+
'Use lowercase alphanumeric characters, or dash (-). Must start and end with an alphanumeric character.',
|
|
238
|
+
),
|
|
239
|
+
},
|
|
240
|
+
];
|
|
241
|
+
|
|
242
|
+
export const validImageBuildName = (t: TFunction) =>
|
|
243
|
+
Yup.string()
|
|
244
|
+
.required(t('Build name is required'))
|
|
245
|
+
.test('imageBuildName', function (value: string | undefined) {
|
|
246
|
+
if (!value) return true;
|
|
247
|
+
return APPLICATION_NAME_REGEXP.test(value) || this.createError({ message: { imageBuildName: 'failed' } });
|
|
248
|
+
});
|
|
249
|
+
|
|
236
250
|
export const maxLengthString = (t: TFunction, props: { maxLength: number; fieldName: string }) =>
|
|
237
251
|
Yup.string().max(props.maxLength, t('{{ fieldName }} must not exceed {{ maxLength }} characters', props));
|
|
238
252
|
|
|
@@ -261,10 +275,52 @@ export const validOsImage = (t: TFunction, { isFleet }: { isFleet: boolean }) =>
|
|
|
261
275
|
}
|
|
262
276
|
}
|
|
263
277
|
|
|
264
|
-
return
|
|
278
|
+
return OCI_IMAGE_FULL_REGEXP.test(validateOsImage);
|
|
265
279
|
},
|
|
266
280
|
);
|
|
267
281
|
|
|
282
|
+
export const validHelmNamespace = (t: TFunction) =>
|
|
283
|
+
Yup.string()
|
|
284
|
+
.max(
|
|
285
|
+
HELM_NAMESPACE_MAX_LENGTH,
|
|
286
|
+
t('Namespace must not exceed {{ max }} characters.', { max: HELM_NAMESPACE_MAX_LENGTH }),
|
|
287
|
+
)
|
|
288
|
+
.test(
|
|
289
|
+
'helm-namespace-format',
|
|
290
|
+
t(
|
|
291
|
+
'Namespace must only include lowercase letters, numbers, and hyphens. It must start and end with a letter or number.',
|
|
292
|
+
),
|
|
293
|
+
(value) => {
|
|
294
|
+
return !value || APPLICATION_NAME_REGEXP.test(value);
|
|
295
|
+
},
|
|
296
|
+
);
|
|
297
|
+
|
|
298
|
+
export const validHelmValuesFile = (t: TFunction) =>
|
|
299
|
+
Yup.string().test('helm-values-file', function (filename) {
|
|
300
|
+
if (!filename) {
|
|
301
|
+
return true;
|
|
302
|
+
}
|
|
303
|
+
if (filename.length > MAX_FILE_PATH_LENGTH) {
|
|
304
|
+
return this.createError({
|
|
305
|
+
message: t('Values file path must not exceed {{ max }} characters.', {
|
|
306
|
+
max: MAX_FILE_PATH_LENGTH,
|
|
307
|
+
}),
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
if (filename.startsWith('/') || filename.includes('..')) {
|
|
311
|
+
return this.createError({
|
|
312
|
+
message: t('Values file path must be relative and cannot contain parent directory references (..).'),
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
if (!HELM_VALUES_FILE_EXT_REGEXP.test(filename)) {
|
|
317
|
+
return this.createError({
|
|
318
|
+
message: t('Values file must have .yaml or .yml extension.'),
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
return true;
|
|
322
|
+
});
|
|
323
|
+
|
|
268
324
|
export const validLabelsSchema = (t: TFunction, forbiddenLabels?: string[]) =>
|
|
269
325
|
Yup.array()
|
|
270
326
|
.of(
|
|
@@ -370,11 +426,7 @@ const inlineAppFileSchema = (t: TFunction) =>
|
|
|
370
426
|
|
|
371
427
|
// Common test for unique file paths in inline applications
|
|
372
428
|
const uniqueFilePathsTest =
|
|
373
|
-
(t: TFunction) =>
|
|
374
|
-
(
|
|
375
|
-
files: (QuadletInlineAppForm | ComposeInlineAppForm)['files'] | undefined,
|
|
376
|
-
testContext: Yup.TestContext<Yup.AnyObject>,
|
|
377
|
-
) => {
|
|
429
|
+
(t: TFunction) => (files: InlineFileForm[] | undefined, testContext: Yup.TestContext<Yup.AnyObject>) => {
|
|
378
430
|
if (!files || files.length === 0) {
|
|
379
431
|
return true;
|
|
380
432
|
}
|
|
@@ -412,34 +464,33 @@ const uniqueFilePathsTest =
|
|
|
412
464
|
});
|
|
413
465
|
};
|
|
414
466
|
|
|
415
|
-
const composeFileName =
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
if (!file.path) {
|
|
420
|
-
return null;
|
|
421
|
-
}
|
|
422
|
-
// Extract filename from relative path (get last part after slash, or use whole path if no slash)
|
|
423
|
-
const fileName = file.path.includes('/') ? file.path.split('/').pop() || file.path : file.path;
|
|
424
|
-
if (!validComposeFileNames.includes(fileName)) {
|
|
425
|
-
return index;
|
|
426
|
-
}
|
|
467
|
+
const composeFileName = (t: TFunction) => (files: InlineFileForm[], testContext: Yup.TestContext<Yup.AnyObject>) => {
|
|
468
|
+
const invalidFiles = files
|
|
469
|
+
.map((file, index) => {
|
|
470
|
+
if (!file.path) {
|
|
427
471
|
return null;
|
|
428
|
-
}
|
|
429
|
-
|
|
472
|
+
}
|
|
473
|
+
// Extract filename from relative path (get last part after slash, or use whole path if no slash)
|
|
474
|
+
const fileName = file.path.includes('/') ? file.path.split('/').pop() || file.path : file.path;
|
|
475
|
+
if (!validComposeFileNames.includes(fileName)) {
|
|
476
|
+
return index;
|
|
477
|
+
}
|
|
478
|
+
return null;
|
|
479
|
+
})
|
|
480
|
+
.filter((index): index is number => index !== null);
|
|
430
481
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
482
|
+
if (invalidFiles.length > 0) {
|
|
483
|
+
const firstInvalidIndex = invalidFiles[0];
|
|
484
|
+
return testContext.createError({
|
|
485
|
+
path: `${testContext.path}[${firstInvalidIndex}].path`,
|
|
486
|
+
message: () =>
|
|
487
|
+
t('File name must be one of: {{ allowedFileNames }}', {
|
|
488
|
+
allowedFileNames: validComposeFileNameDisplay,
|
|
489
|
+
}),
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
return true;
|
|
493
|
+
};
|
|
443
494
|
|
|
444
495
|
// Helper to extract file extension from a path
|
|
445
496
|
const getFileExtension = (path: string): string => {
|
|
@@ -454,7 +505,7 @@ const isAtRoot = (path: string): boolean => {
|
|
|
454
505
|
|
|
455
506
|
// Validation for quadlet applications: checks for unsupported types first, then requires at least one supported type
|
|
456
507
|
const quadletFileTypesValidation =
|
|
457
|
-
(t: TFunction) => (files:
|
|
508
|
+
(t: TFunction) => (files: InlineFileForm[], testContext: Yup.TestContext<Yup.AnyObject>) => {
|
|
458
509
|
if (!files || files.length === 0) {
|
|
459
510
|
return true; // This is handled by the min(1) requirement
|
|
460
511
|
}
|
|
@@ -512,36 +563,35 @@ const quadletFileTypesValidation =
|
|
|
512
563
|
};
|
|
513
564
|
|
|
514
565
|
// Validation for quadlet applications: quadlet files must be at root level
|
|
515
|
-
const quadletFilesAtRoot =
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
}
|
|
566
|
+
const quadletFilesAtRoot = (t: TFunction) => (files: InlineFileForm[], testContext: Yup.TestContext<Yup.AnyObject>) => {
|
|
567
|
+
if (!files || files.length === 0) {
|
|
568
|
+
return true;
|
|
569
|
+
}
|
|
520
570
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
return null;
|
|
525
|
-
}
|
|
526
|
-
const ext = getFileExtension(file.path);
|
|
527
|
-
// Only check files with supported quadlet extensions
|
|
528
|
-
if (supportedQuadletExtensions.includes(ext) && !isAtRoot(file.path)) {
|
|
529
|
-
return index;
|
|
530
|
-
}
|
|
571
|
+
const invalidFiles = files
|
|
572
|
+
.map((file, index) => {
|
|
573
|
+
if (!file.path) {
|
|
531
574
|
return null;
|
|
532
|
-
}
|
|
533
|
-
|
|
575
|
+
}
|
|
576
|
+
const ext = getFileExtension(file.path);
|
|
577
|
+
// Only check files with supported quadlet extensions
|
|
578
|
+
if (supportedQuadletExtensions.includes(ext) && !isAtRoot(file.path)) {
|
|
579
|
+
return index;
|
|
580
|
+
}
|
|
581
|
+
return null;
|
|
582
|
+
})
|
|
583
|
+
.filter((index): index is number => index !== null);
|
|
534
584
|
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
585
|
+
if (invalidFiles.length > 0) {
|
|
586
|
+
const firstInvalidIndex = invalidFiles[0];
|
|
587
|
+
return testContext.createError({
|
|
588
|
+
path: `${testContext.path}[${firstInvalidIndex}].path`,
|
|
589
|
+
message: () => t('Quadlet files must be at root level (no subdirectories)'),
|
|
590
|
+
});
|
|
591
|
+
}
|
|
542
592
|
|
|
543
|
-
|
|
544
|
-
|
|
593
|
+
return true;
|
|
594
|
+
};
|
|
545
595
|
|
|
546
596
|
const PORT_NUMBER_REGEXP = /^\d+$/;
|
|
547
597
|
const MAX_PORT = 65535;
|
|
@@ -621,17 +671,27 @@ export const validateMemoryLimit = (memory: string | undefined): boolean => {
|
|
|
621
671
|
return true;
|
|
622
672
|
};
|
|
623
673
|
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
674
|
+
const ociImageSchema = (t: TFunction) =>
|
|
675
|
+
Yup.string().test('oci-image-format', (value, testContext) => {
|
|
676
|
+
if (!value) return true;
|
|
677
|
+
if (!OCI_IMAGE_ALLOWED_CHARS_REGEXP.test(value)) {
|
|
678
|
+
return testContext.createError({
|
|
679
|
+
message: t('Image includes invalid characters.'),
|
|
680
|
+
});
|
|
681
|
+
}
|
|
682
|
+
if (!OCI_IMAGE_FULL_REGEXP.test(value)) {
|
|
683
|
+
return testContext.createError({
|
|
684
|
+
message: t('Image must not start with a dot (.), slash (/), or underscore (_).'),
|
|
685
|
+
});
|
|
631
686
|
}
|
|
632
|
-
return
|
|
687
|
+
return true;
|
|
633
688
|
});
|
|
634
689
|
|
|
690
|
+
const requiredOciImageSchema = (t: TFunction, requiredMessage?: string) =>
|
|
691
|
+
ociImageSchema(t).required(requiredMessage || t('Image is required.'));
|
|
692
|
+
|
|
693
|
+
const volumeNameSchema = (t: TFunction) => validApplicationAndVolumeName(t).required(t('Volume name is required'));
|
|
694
|
+
|
|
635
695
|
const imagePullPolicySchema = (t: TFunction) =>
|
|
636
696
|
Yup.string()
|
|
637
697
|
.oneOf(
|
|
@@ -645,12 +705,11 @@ const mountPathSchema = (t: TFunction, isRequired: boolean = true) => {
|
|
|
645
705
|
return isRequired ? schema.required(t('Mount path is required for this volume type')) : schema;
|
|
646
706
|
};
|
|
647
707
|
|
|
648
|
-
// Volume validation schemas
|
|
649
708
|
const singleContainerVolumesSchema = (t: TFunction) =>
|
|
650
709
|
Yup.array().of(
|
|
651
710
|
Yup.object().shape({
|
|
652
711
|
name: volumeNameSchema(t),
|
|
653
|
-
imageRef:
|
|
712
|
+
imageRef: ociImageSchema(t),
|
|
654
713
|
imagePullPolicy: Yup.string(),
|
|
655
714
|
mountPath: mountPathSchema(t, true),
|
|
656
715
|
}),
|
|
@@ -660,7 +719,7 @@ const composeQuadletVolumesSchema = (t: TFunction) =>
|
|
|
660
719
|
Yup.array().of(
|
|
661
720
|
Yup.object().shape({
|
|
662
721
|
name: volumeNameSchema(t),
|
|
663
|
-
imageRef:
|
|
722
|
+
imageRef: requiredOciImageSchema(t, t('Image reference is required for this volume type')),
|
|
664
723
|
imagePullPolicy: imagePullPolicySchema(t),
|
|
665
724
|
}),
|
|
666
725
|
);
|
|
@@ -670,16 +729,14 @@ export const validApplicationsSchema = (t: TFunction) => {
|
|
|
670
729
|
.of(
|
|
671
730
|
Yup.lazy((value: AppForm) => {
|
|
672
731
|
// Container applications (image-based with ports and resources)
|
|
673
|
-
if (
|
|
732
|
+
if (value.appType === AppType.AppTypeContainer) {
|
|
674
733
|
return Yup.object().shape({
|
|
675
734
|
specType: Yup.string()
|
|
676
735
|
.oneOf([AppSpecType.OCI_IMAGE])
|
|
677
736
|
.required(t('Definition source must be image for this type of applications')),
|
|
678
737
|
appType: Yup.string().oneOf([AppType.AppTypeContainer]).required(t('Application type is required')),
|
|
679
|
-
name: validApplicationAndVolumeName(t)
|
|
680
|
-
image:
|
|
681
|
-
.required(t('Image is required.'))
|
|
682
|
-
.matches(APPLICATION_IMAGE_REGEXP, t('Application image includes invalid characters.')),
|
|
738
|
+
name: validApplicationAndVolumeName(t),
|
|
739
|
+
image: requiredOciImageSchema(t),
|
|
683
740
|
ports: Yup.array().of(
|
|
684
741
|
Yup.object()
|
|
685
742
|
.shape({
|
|
@@ -709,17 +766,15 @@ export const validApplicationsSchema = (t: TFunction) => {
|
|
|
709
766
|
}
|
|
710
767
|
|
|
711
768
|
// Helm applications
|
|
712
|
-
if (
|
|
713
|
-
return Yup.object<
|
|
769
|
+
if (value.appType === AppType.AppTypeHelm) {
|
|
770
|
+
return Yup.object<HelmAppForm>().shape({
|
|
714
771
|
specType: Yup.string()
|
|
715
772
|
.oneOf([AppSpecType.OCI_IMAGE])
|
|
716
773
|
.required(t('Definition source must be image for this type of applications')),
|
|
717
774
|
appType: Yup.string().oneOf([AppType.AppTypeHelm]).required(t('Application type is required')),
|
|
718
775
|
name: validApplicationAndVolumeName(t),
|
|
719
|
-
image:
|
|
720
|
-
|
|
721
|
-
.matches(APPLICATION_IMAGE_REGEXP, t('Application image includes invalid characters.')),
|
|
722
|
-
namespace: Yup.string(),
|
|
776
|
+
image: requiredOciImageSchema(t),
|
|
777
|
+
namespace: validHelmNamespace(t),
|
|
723
778
|
valuesYaml: Yup.string().test('valid-yaml', t('YAML content is invalid.'), (value) => {
|
|
724
779
|
if (!value || value.trim() === '') {
|
|
725
780
|
return true;
|
|
@@ -731,16 +786,13 @@ export const validApplicationsSchema = (t: TFunction) => {
|
|
|
731
786
|
}
|
|
732
787
|
return true;
|
|
733
788
|
}),
|
|
734
|
-
|
|
735
|
-
// Since the UX design has the first field added by default, we will ignore all empty values files.
|
|
736
|
-
// The user can't add more values files if any is empty (though they can clear existing ones).
|
|
737
|
-
valuesFiles: Yup.array().of(Yup.string()),
|
|
789
|
+
valuesFiles: Yup.array().of(validHelmValuesFile(t)),
|
|
738
790
|
});
|
|
739
791
|
}
|
|
740
792
|
|
|
741
793
|
// Image applications (Quadlet or Compose)
|
|
742
|
-
if (
|
|
743
|
-
return Yup.object<
|
|
794
|
+
if (value.specType === AppSpecType.OCI_IMAGE) {
|
|
795
|
+
return Yup.object<QuadletAppForm | ComposeAppForm>().shape({
|
|
744
796
|
specType: Yup.string()
|
|
745
797
|
.oneOf([AppSpecType.OCI_IMAGE])
|
|
746
798
|
.required(t('Definition source must be image for this type of applications')),
|
|
@@ -748,17 +800,15 @@ export const validApplicationsSchema = (t: TFunction) => {
|
|
|
748
800
|
.oneOf([AppType.AppTypeCompose, AppType.AppTypeQuadlet])
|
|
749
801
|
.required(t('Application type is required')),
|
|
750
802
|
name: validApplicationAndVolumeName(t),
|
|
751
|
-
image:
|
|
752
|
-
.required(t('Image is required.'))
|
|
753
|
-
.matches(APPLICATION_IMAGE_REGEXP, t('Application image includes invalid characters.')),
|
|
803
|
+
image: requiredOciImageSchema(t),
|
|
754
804
|
volumes: composeQuadletVolumesSchema(t),
|
|
755
805
|
variables: appVariablesSchema(t),
|
|
756
806
|
});
|
|
757
807
|
}
|
|
758
808
|
|
|
759
809
|
// Inline quadlet applications
|
|
760
|
-
if (
|
|
761
|
-
return Yup.object<
|
|
810
|
+
if (value.appType === AppType.AppTypeQuadlet && value.specType === AppSpecType.INLINE) {
|
|
811
|
+
return Yup.object<QuadletAppForm>().shape({
|
|
762
812
|
specType: appSpecTypeSchema(t),
|
|
763
813
|
appType: Yup.string().oneOf([AppType.AppTypeQuadlet]).required(t('Application type is required')),
|
|
764
814
|
name: validApplicationAndVolumeName(t).required(t('Name is required for quadlet applications.')),
|
|
@@ -772,7 +822,7 @@ export const validApplicationsSchema = (t: TFunction) => {
|
|
|
772
822
|
}
|
|
773
823
|
|
|
774
824
|
// Inline compose applications
|
|
775
|
-
return Yup.object<
|
|
825
|
+
return Yup.object<ComposeAppForm>().shape({
|
|
776
826
|
specType: appSpecTypeSchema(t),
|
|
777
827
|
appType: Yup.string().oneOf([AppType.AppTypeCompose]).required(t('Application type is required')),
|
|
778
828
|
name: validApplicationAndVolumeName(t).required(t('Name is required for compose applications.')),
|
|
@@ -9,9 +9,10 @@ type CreateRepositoryModalProps = {
|
|
|
9
9
|
type: RepoSpecType;
|
|
10
10
|
onClose: VoidFunction;
|
|
11
11
|
onSuccess: (repository: Repository) => void;
|
|
12
|
+
validateBeforeCreate?: (repo: Repository) => string | undefined;
|
|
12
13
|
};
|
|
13
14
|
|
|
14
|
-
const CreateRepositoryModal = ({ type, onClose, onSuccess }: CreateRepositoryModalProps) => {
|
|
15
|
+
const CreateRepositoryModal = ({ type, onClose, onSuccess, validateBeforeCreate }: CreateRepositoryModalProps) => {
|
|
15
16
|
const { t } = useTranslation();
|
|
16
17
|
return (
|
|
17
18
|
<Modal variant="medium" isOpen>
|
|
@@ -20,6 +21,7 @@ const CreateRepositoryModal = ({ type, onClose, onSuccess }: CreateRepositoryMod
|
|
|
20
21
|
<CreateRepositoryForm
|
|
21
22
|
onClose={onClose}
|
|
22
23
|
onSuccess={onSuccess}
|
|
24
|
+
validateBefore={validateBeforeCreate}
|
|
23
25
|
options={{
|
|
24
26
|
canUseResourceSyncs: false,
|
|
25
27
|
allowedRepoTypes: [type],
|
package/src/constants.ts
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const PAGE_SIZE = 15;
|
|
4
|
-
const EVENT_PAGE_SIZE = 200; // It's 500 in OCP console
|
|
5
|
-
const CERTIFICATE_VALIDITY_IN_YEARS = 1;
|
|
1
|
+
import { ApiVersion } from '@flightctl/types';
|
|
2
|
+
import { ApiVersion as ImageBuilderApiVersion } from '@flightctl/types/imagebuilder';
|
|
6
3
|
|
|
7
|
-
export
|
|
4
|
+
export const APP_TITLE = 'Edge Manager';
|
|
5
|
+
export const PAGE_SIZE = 15;
|
|
6
|
+
export const EVENT_PAGE_SIZE = 200; // It's 500 in OCP console
|
|
7
|
+
|
|
8
|
+
export const CERTIFICATE_VALIDITY_IN_YEARS = 1;
|
|
9
|
+
|
|
10
|
+
export const getApiVersion = (api: 'flightctl' | 'imagebuilder' | 'alerts'): string | undefined => {
|
|
11
|
+
switch (api) {
|
|
12
|
+
case 'flightctl':
|
|
13
|
+
return ApiVersion.ApiVersionV1beta1;
|
|
14
|
+
case 'imagebuilder':
|
|
15
|
+
return ImageBuilderApiVersion.ApiVersionV1alpha1;
|
|
16
|
+
case 'alerts':
|
|
17
|
+
default:
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
@@ -11,6 +11,8 @@ const msgToBytes = (msg: string, resize?: boolean) => {
|
|
|
11
11
|
return result;
|
|
12
12
|
};
|
|
13
13
|
|
|
14
|
+
const isErrorCloseEvent = (evt: CloseEvent) => evt.code !== 1000 && evt.code !== 1001;
|
|
15
|
+
|
|
14
16
|
export type WsMetadata = {
|
|
15
17
|
tty: boolean;
|
|
16
18
|
term: string;
|
|
@@ -34,13 +36,17 @@ export const useWebSocket = <T>(
|
|
|
34
36
|
const { t } = useTranslation();
|
|
35
37
|
const wsRef = React.useRef<WebSocket>();
|
|
36
38
|
const isMountedRef = React.useRef(true);
|
|
39
|
+
const hasReceivedMessageRef = React.useRef(false);
|
|
37
40
|
const [isConnecting, setIsConnecting] = React.useState(true);
|
|
38
41
|
const [isClosed, setIsClosed] = React.useState(false);
|
|
39
42
|
const [error, setError] = React.useState<unknown>();
|
|
40
43
|
const [reset, setReset] = React.useState<number>(0);
|
|
41
44
|
|
|
42
45
|
const sendMessage = React.useCallback((data: string, resize?: boolean) => {
|
|
43
|
-
wsRef.current
|
|
46
|
+
const ws = wsRef.current;
|
|
47
|
+
if (ws?.readyState === WebSocket.OPEN) {
|
|
48
|
+
ws.send(msgToBytes(data, resize));
|
|
49
|
+
}
|
|
44
50
|
}, []);
|
|
45
51
|
|
|
46
52
|
React.useEffect(() => {
|
|
@@ -54,6 +60,8 @@ export const useWebSocket = <T>(
|
|
|
54
60
|
try {
|
|
55
61
|
setIsConnecting(true);
|
|
56
62
|
setIsClosed(false);
|
|
63
|
+
setError(undefined);
|
|
64
|
+
hasReceivedMessageRef.current = false;
|
|
57
65
|
const wsEndpoint = getWsEndpoint(deviceId);
|
|
58
66
|
const wsMeta = JSON.stringify(wsMetadata);
|
|
59
67
|
const params = new URLSearchParams({
|
|
@@ -73,9 +81,16 @@ export const useWebSocket = <T>(
|
|
|
73
81
|
}
|
|
74
82
|
};
|
|
75
83
|
|
|
76
|
-
const handleClose = () => {
|
|
84
|
+
const handleClose = (evt: CloseEvent) => {
|
|
77
85
|
if (isMountedRef.current) {
|
|
86
|
+
setIsConnecting(false);
|
|
78
87
|
setIsClosed(true);
|
|
88
|
+
// If we never received any data from the backend, treat an error close as a failure
|
|
89
|
+
// Otherwise it may be a normal session close, and we'll show the "Reconnect" banner.
|
|
90
|
+
if (isErrorCloseEvent(evt) && !hasReceivedMessageRef.current) {
|
|
91
|
+
const reason = evt.reason || t('Unknown error');
|
|
92
|
+
setError(t('Failed to connect to device terminal: {{reason}}', { reason }));
|
|
93
|
+
}
|
|
79
94
|
}
|
|
80
95
|
wsRef.current = undefined;
|
|
81
96
|
};
|
|
@@ -84,7 +99,13 @@ export const useWebSocket = <T>(
|
|
|
84
99
|
// eslint-disable-next-line no-console
|
|
85
100
|
console.error('Error creating websocket:', evt);
|
|
86
101
|
if (isMountedRef.current) {
|
|
87
|
-
|
|
102
|
+
setIsConnecting(false);
|
|
103
|
+
if (!hasReceivedMessageRef.current) {
|
|
104
|
+
setError(t('Failed to connect to device terminal'));
|
|
105
|
+
} else {
|
|
106
|
+
// User may have closed the session, so we'll show the "Reconnect" banner.
|
|
107
|
+
setIsClosed(true);
|
|
108
|
+
}
|
|
88
109
|
}
|
|
89
110
|
};
|
|
90
111
|
|
|
@@ -120,6 +141,7 @@ export const useWebSocket = <T>(
|
|
|
120
141
|
React.useEffect(() => {
|
|
121
142
|
const listener = (evt: MessageEvent<T>) => {
|
|
122
143
|
if (isMountedRef.current) {
|
|
144
|
+
hasReceivedMessageRef.current = true;
|
|
123
145
|
onMsgReceived(evt.data);
|
|
124
146
|
}
|
|
125
147
|
};
|