Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/product_builder.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
config-preset: conventionalcommits
config-version: 7.0.2
- name: Run title validation
# if it's not a PR we skip
if: ${{ github.event_name == 'pull_request' }}
Expand Down
1 change: 1 addition & 0 deletions web/crux-ui/i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"/[teamSlug]/deployments/[deploymentId]/instances/[instanceId]": ["images", "deployments", "container"],
"/status": ["status"],
"/templates": ["templates", "projects"],
"/composer": ["compose", "versions", "container"],
"/[teamSlug]/dashboard": ["dashboard"],
"/[teamSlug]/storages": ["storages"],
"/[teamSlug]/storages/[storageId]": ["storages"],
Expand Down
2 changes: 2 additions & 0 deletions web/crux-ui/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"address": "Address",
"actions": "Actions",
"note": "Note",
"containers": "Containers",

"editName": "Edit {{name}}",
"add": "Add",
Expand Down Expand Up @@ -89,6 +90,7 @@
"profile": "Profile",
"tokens": "Tokens",
"templates": "Templates",
"composer": "Composer",
"pipelines": "Pipelines",
"storages": "Storages",
"configBundles": "Config bundles",
Expand Down
24 changes: 24 additions & 0 deletions web/crux-ui/locales/en/compose.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"compose": "Compose",
"composeFile": "Compose file",
"dotEnvFile": ".env file",
"errors": {
"failedToParseFile": "Failed to parse the {{file}}"
},
"registryFound": "Registry found",
"missingRegistry": "Missing registry",
"entrypoint": "Entrypoint",
"pasteYourCompose": "Paste your compose file",
"defaultDotEnv": "Default .env",
"addDotEnv": "Add .env",
"generate": "Generate",
"generateVersion": "Generate version",
"target": "Target",
"targetType": {
"new-project": "New project",
"existing-project": "Existing project"
},
"versionName": "Version name",
"versionType": "Version type",
"projectName": "Project name"
}
1 change: 0 additions & 1 deletion web/crux-ui/locales/en/nodes.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"nodesName": "Nodes - {{name}}",

"containers": "Containers",
"logs": "Logs",
"inspect": "Inspect",

Expand Down
22 changes: 16 additions & 6 deletions web/crux-ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions web/crux-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"@ory/kratos-client": "^1.1.0",
"clsx": "^2.0.0",
"formik": "^2.4.3",
"js-yaml": "^4.1.0",
"next": "^14.1.1",
"next-translate": "^2.6.2",
"openpgp": "^5.10.1",
Expand All @@ -54,6 +55,7 @@
"@playwright/test": "^1.42.0",
"@types/google-protobuf": "^3.15.6",
"@types/jest": "^29.5.3",
"@types/js-yaml": "^4.0.9",
"@types/jsoneditor": "^9.9.0",
"@types/node": "20.11.25",
"@types/openpgp": "^4.4.18",
Expand Down
1 change: 1 addition & 0 deletions web/crux-ui/public/composer.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
45 changes: 45 additions & 0 deletions web/crux-ui/src/components/composer/compose-environment.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import DyoWrap from '@app/elements/dyo-wrap'
import useTranslation from 'next-translate/useTranslation'
import DotEnvFileCard from './dot-env-file-card'
import {
ComposerDispatch,
ComposerState,
changeEnvFileName,
convertEnvFile,
removeEnvFile,
selectDefaultEnvironment,
} from './use-composer-state'

type ComposeEnvironmentProps = {
className?: string
state: ComposerState
dispatch: ComposerDispatch
}

const ComposeEnvironment = (props: ComposeEnvironmentProps) => {
const { className, state, dispatch } = props

const { t } = useTranslation('compose')

const onEnvFileChange = (name: string, text: string) => dispatch(convertEnvFile(t, name, text))
const onEnvNameChange = (from: string, to: string) => dispatch(changeEnvFileName(from, to))
const onRemoveDotEnv = (name: string) => dispatch(removeEnvFile(name))

const defaultDotEnv = selectDefaultEnvironment(state)

return (
<DyoWrap className={className}>
{state.environment.map((it, index) => (
<DotEnvFileCard
key={`dot-env-${index}`}
dotEnv={it}
onEnvChange={text => onEnvFileChange(it.name, text)}
onNameChange={it !== defaultDotEnv ? name => onEnvNameChange(it.name, name) : null}
onRemove={it !== defaultDotEnv ? () => onRemoveDotEnv(it.name) : null}
/>
))}
</DyoWrap>
)
}

export default ComposeEnvironment
35 changes: 35 additions & 0 deletions web/crux-ui/src/components/composer/compose-file-card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { DyoCard } from '@app/elements/dyo-card'
import { DyoHeading } from '@app/elements/dyo-heading'
import DyoMessage from '@app/elements/dyo-message'
import clsx from 'clsx'
import useTranslation from 'next-translate/useTranslation'
import YamlEditor from '../shared/yaml-editor-dynamic-module'

type ComposeFileCardProps = {
className?: string
errorMessage?: string
initialText: string
onChange: (text: string) => void
}

const ComposeFileCard = (props: ComposeFileCardProps) => {
const { className, errorMessage, initialText, onChange } = props

const { t } = useTranslation('compose')

return (
<DyoCard className={clsx('flex flex-col h-128 w-full', className ?? 'p-6')}>
<DyoHeading element="h4" className="text-lg text-bright mb-2">
{t('composeFile')}
</DyoHeading>

{errorMessage ? (
<DyoMessage message={errorMessage} className="text-xs italic w-full" messageType="error" />
) : null}

<YamlEditor className="h-full overflow-y-scroll" initialValue={initialText} onChange={onChange} />
</DyoCard>
)
}

export default ComposeFileCard
60 changes: 60 additions & 0 deletions web/crux-ui/src/components/composer/converted-container.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { DyoCard } from '@app/elements/dyo-card'
import { DyoHeading } from '@app/elements/dyo-heading'
import DyoIcon from '@app/elements/dyo-icon'
import DyoIndicator from '@app/elements/dyo-indicator'
import { ConvertedContainer, imageConfigToJsonContainerConfig } from '@app/models'
import { writeToClipboard } from '@app/utils'
import clsx from 'clsx'
import useTranslation from 'next-translate/useTranslation'
import { OFFLINE_EDITOR_STATE } from '../editor/use-item-editor-state'
import EditImageJson from '../projects/versions/images/edit-image-json'

type ConvertedContainerCardProps = {
className?: string
container: ConvertedContainer
hasRegistry?: boolean
}

const ConvertedContainerCard = (props: ConvertedContainerCardProps) => {
const { className, container, hasRegistry } = props

const { t } = useTranslation('compose')

const onCopy = () => writeToClipboard(t, JSON.stringify(container.config, undefined, 2))

return (
<DyoCard className={clsx('flex flex-col w-full', className ?? 'p-6')}>
<div className="flex flex-row items-center justify-between">
<DyoHeading element="h4" className="text-bright text-lg">{`${t('common:container')}: ${
container.config.name
}`}</DyoHeading>

<DyoIcon size="md" src="/copy-alt.svg" alt={t('common:copy')} onClick={onCopy} />
</div>

<div className="flex flex-row items-center gap-2">
<DyoIndicator
color={hasRegistry ? 'bg-dyo-green' : 'bg-error-red'}
title={t(hasRegistry ? 'registryFound' : 'missingRegistry')}
/>

<span className="text-bright">{`${t('common:image')}: ${container.image}`}</span>
</div>

{!hasRegistry && <span className="text-error-red text-sm">{t('missingRegistry')}</span>}

<div className="flex flex-col pt-2 mt-auto h-128">
<EditImageJson
disabled
config={container.config}
editorOptions={OFFLINE_EDITOR_STATE}
onPatch={() => {}}
onParseError={() => {}}
convertConfigToJson={imageConfigToJsonContainerConfig}
/>
</div>
</DyoCard>
)
}

export default ConvertedContainerCard
62 changes: 62 additions & 0 deletions web/crux-ui/src/components/composer/dot-env-file-card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { DyoCard } from '@app/elements/dyo-card'
import { DyoHeading } from '@app/elements/dyo-heading'
import DyoImgButton from '@app/elements/dyo-img-button'
import { DyoInput } from '@app/elements/dyo-input'
import DyoMessage from '@app/elements/dyo-message'
import { DotEnvironment } from '@app/models'
import clsx from 'clsx'
import useTranslation from 'next-translate/useTranslation'
import ShEditor from '../shared/sh-editor-dynamic-module'

type DotEnvFileCardProps = {
className?: string
dotEnv: DotEnvironment
onNameChange?: (name: string) => void
onEnvChange: (text: string) => void
onRemove?: VoidFunction
}

const DotEnvFileCard = (props: DotEnvFileCardProps) => {
const { className, dotEnv, onEnvChange: onChange, onNameChange, onRemove } = props

const initialValue: string = Object.entries(dotEnv?.environment ?? {})
.map(entry => {
const [key, val] = entry

return `${key}=${val}`
})
.join('\n')

const { t } = useTranslation('compose')

return (
<DyoCard className={clsx('flex flex-col gap-2 w-full', className ?? 'h-128 p-6')}>
<div className="flex flex-row justify-between items-center gap-2">
<DyoHeading element="h4" className="text-lg text-bright whitespace-nowrap">
{t('dotEnvFile')}
</DyoHeading>

<DyoInput
containerClassName="mb-1"
labelClassName="mr-2 my-auto"
disabled={!onNameChange}
grow
inline
label={t('common:name')}
value={dotEnv.name}
onChange={onNameChange ? ev => onNameChange(ev.target.value) : null}
/>

{onRemove && <DyoImgButton onClick={onRemove} src="/trash-can.svg" alt={t('common:delete')} />}
</div>

{dotEnv.errorMessage ? (
<DyoMessage message={dotEnv.errorMessage} className="text-xs italic w-full" messageType="error" />
) : null}

<ShEditor className="h-full overflow-y-scroll" initialValue={initialValue} onChange={onChange} />
</DyoCard>
)
}

export default DotEnvFileCard
Loading