Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
6a2e01e
feat: basic fields for service
ElderMatt Feb 25, 2025
751cc49
feat: first run
ElderMatt Feb 28, 2025
25e855f
feat: some fields are now loading data
ElderMatt Mar 3, 2025
e5e78a0
feat: all fields working
ElderMatt Mar 5, 2025
0a2641e
feat: number field with custom end andorment
dennisvankekem Mar 6, 2025
85b02ab
fix: validation message now visible
ElderMatt Mar 10, 2025
6edc8a7
feat: fix custom errors
ElderMatt Mar 10, 2025
25b8d35
fix: knative error
ElderMatt Mar 10, 2025
3c98580
fix: remove demo data
ElderMatt Mar 10, 2025
a4cebdd
fix: find services and secrets
ElderMatt Mar 10, 2025
a80ed6d
fix: find service
ElderMatt Mar 10, 2025
d356a19
fix: find secrets
ElderMatt Mar 10, 2025
efdb878
fix: subdomain
ElderMatt Mar 11, 2025
124d1cd
fix: remove cname and headers if empty
ElderMatt Mar 11, 2025
baf6d5e
fix: styling subdomain and paths
ElderMatt Mar 11, 2025
9a38294
fix: remove demo values
ElderMatt Mar 11, 2025
0d7753e
fix: styling and refresh page empty values
ElderMatt Mar 12, 2025
eac9924
fix: removed logs
ElderMatt Mar 12, 2025
08fca90
Merge branch 'main' into APL-537
dennisvankekem Mar 12, 2025
fbfee66
fix: urls empty and namespace required
ElderMatt Mar 13, 2025
4806690
feat: added linkednumber validation and url helper
ElderMatt Mar 13, 2025
e3fc1e3
fix: doc change console log removed and comment fixed
ElderMatt Mar 14, 2025
c478ace
Merge branch 'main' into APL-537
ElderMatt Mar 17, 2025
118824f
feat: ports is select and filter services
ElderMatt Mar 17, 2025
df5a135
Merge branch 'main' into APL-537
ElderMatt Mar 19, 2025
bbeca4f
fix: serviceid to servicename
ElderMatt Mar 19, 2025
72e6ae3
fix: put back smtp in team component
ElderMatt Mar 19, 2025
9dde7c2
Update Team.tsx
ElderMatt Mar 19, 2025
cf18d7d
feat: added keys and changed texts
ElderMatt Mar 20, 2025
7a58715
fix: url being empty
ElderMatt Mar 20, 2025
9465d15
fix: set url
ElderMatt Mar 20, 2025
61032d6
fix: fetching check
ElderMatt Mar 20, 2025
684a2a3
fix: set service and filtered services
ElderMatt Mar 20, 2025
a5c9fdd
feat: platform ingress classnames now fetched
ElderMatt Mar 31, 2025
372a8cf
feat: use advancedsettings component from APL-540
dennisvankekem Mar 14, 2025
1cf514c
fix: rerender issues
ElderMatt Apr 1, 2025
87f3029
Merge branch 'main' into APL-537
ElderMatt Apr 4, 2025
6736a82
Merge branch 'main' into APL-537
ElderMatt Apr 11, 2025
43a6eb5
feat: use api v2
ElderMatt Apr 11, 2025
e09338c
feat: merge branch main into apl-537 and fix checkboxes
ElderMatt Apr 14, 2025
5d7de7f
Merge branch 'main' into APL-537
ElderMatt Apr 15, 2025
ae3e4d7
fix: empty fields and double slash in overview
ElderMatt Apr 15, 2025
956d1fc
fix: teams being undefined
ElderMatt Apr 15, 2025
77fe0e5
fix: empty teams
ElderMatt Apr 15, 2025
d4e06d4
fix: undefined paths
ElderMatt Apr 15, 2025
3a79170
fix: trafficmanagement and dropdowns
ElderMatt Apr 16, 2025
4b0d29c
fix: default value in linkednumber component
ElderMatt Apr 16, 2025
38c8799
fix: add default ingressclassname platform
ElderMatt Apr 16, 2025
7cf9973
feat: added adjustable width to autocomplete
ElderMatt Apr 16, 2025
f2f1021
feat: cname domainsuffix validation
ElderMatt Apr 16, 2025
681fc30
fix: light mode cname text
ElderMatt Apr 16, 2025
d959b33
Merge branch 'main' into APL-537
dennisvankekem Apr 17, 2025
9568088
fix: clamped values
dennisvankekem Apr 17, 2025
02d8c8b
fix: comment from ux findings
ElderMatt Apr 17, 2025
3b8957e
fix: pathing and forward slash
ElderMatt Apr 17, 2025
afb3419
fix: uxfindings
ElderMatt Apr 23, 2025
63c0313
fix: save changes instead of edit service
ElderMatt Apr 23, 2025
33e3054
fix: cname styling
ElderMatt Apr 23, 2025
965a5c7
fix: add buttons in keyvalue
ElderMatt Apr 23, 2025
4543723
fix: removed tsnocheck
ElderMatt Apr 23, 2025
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
28 changes: 28 additions & 0 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
"@types/js-yaml": "^4.0.9",
"@types/json-schema": "^7.0.15",
"@types/lodash": "^4.17.15",
"@types/ramda": "^0.30.2",
"@types/react": "18.3.18",
"@types/react-dom": "18.3.5",
"@types/react-helmet": "5.0.20",
Expand Down
4 changes: 4 additions & 0 deletions public/assets/number_icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ import Catalog from 'pages/Catalog'
import Error from 'pages/Error'
import SealedSecret from 'pages/SealedSecret'
import SealedSecrets from 'pages/SealedSecrets'
import Service from 'pages/Service'
import Services from 'pages/Services'
import Setting from 'pages/Setting'
import SettingsOverview from 'pages/SettingsOverview'
import Team from 'pages/teams/create-edit'
Expand Down Expand Up @@ -51,6 +49,8 @@ import Policy from 'pages/Policy'
import Maintenance from 'pages/Maintenance'
import PrivateRoute from 'components/AuthzRoute'
import Logout from 'pages/Logout'
import Service from 'pages/services/create-edit'
import Services from 'pages/services/overview'
import CodeRepository from 'pages/code-repositories/create-edit'
import CodeRepositories from 'pages/code-repositories/overview'
import { HttpErrorBadRequest } from './utils/error'
Expand Down
5 changes: 3 additions & 2 deletions src/components/AdvancedSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,19 @@ interface Props {
title?: string
children?: React.ReactNode
noPaddingTop?: boolean
closed?: boolean
}

export default function AdvancedSettings(props: Props) {
const { title = 'Advanced Settings', description, children, noPaddingTop } = props
const { title = 'Advanced Settings', description, children, noPaddingTop, closed = false } = props
const [expanded, setExpanded] = useState(true)

const handleAccordionChange = () => {
setExpanded((prev) => !prev)
}

return (
<StyledAccordion disableGutters expanded={expanded} onChange={handleAccordionChange}>
<StyledAccordion defaultExpanded={!closed} disableGutters onChange={handleAccordionChange}>
<StyledAccordionSummary
expandIcon={<KeyboardArrowRight />}
sx={{
Expand Down
4 changes: 2 additions & 2 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,11 @@ export default function Header({ onOpenSidebar, isCollapse = false, verticalLayo
<Select
size='small'
color='secondary'
value={(teams.length && oboTeamId) || ''}
value={(teams?.length && oboTeamId) || ''}
onChange={handleChangeTeam}
data-cy='select-oboteam'
>
{teams.map((teamName) => (
{teams?.map((teamName) => (
<MenuItem key={teamName} value={teamName} data-cy={`select-oboteam-${teamName}`}>
{teamName}
</MenuItem>
Expand Down
8 changes: 4 additions & 4 deletions src/components/Service.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ export const addDomainEnumField = (
formData: GetServiceApiResponse,
): void => {
const { cluster, dns } = settings
if (['cluster', 'tlsPass'].includes(formData?.ingress?.type)) return
// if (['cluster', 'tlsPass'].includes(formData?.ingress?.type)) return
const ing = formData?.ingress as any
const idx = idxMap[formData?.ingress?.type]
// const idx = idxMap[formData?.ingress?.type]
if (!formData || isEmpty(ing)) return
const ingressSchemaPath = getIngressSchemaPath(idx)
const ingressSchemaPath = getIngressSchemaPath(1)
const ingressSchema = getStrict(schema, ingressSchemaPath)
const zones = [cluster.domainSuffix, ...(dns?.zones || [])]
if (!ingressSchema) return
Expand Down Expand Up @@ -85,7 +85,7 @@ export const getServiceSchema = (
if (teamId !== 'admin') addServiceNameEnumField(schema, k8sServices, formData)
addDomainEnumField(schema, settings, formData)
const ing = formData?.ingress as Record<string, any>
const idx = idxMap[formData?.ingress?.type]
const idx = 1
set(schema, 'properties.ingress.oneOf[1].allOf[0].properties.ingressClassName.enum', [
'platform',
...settings.ingressClassNames,
Expand Down
1 change: 1 addition & 0 deletions src/components/Services.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const renderHost = ({ ingress, teamId, name }): React.ReactElement | string => {
if (!ingress) return ''
if (ingress.type === 'cluster') return `${name}.team-${teamId}`
const { subdomain, domain, paths } = ingress
// TODO: Replace functionality in apl-core so that / is not needed on path or domain
const url = `${subdomain ? `${subdomain}.` : ''}${domain}${paths?.[0] || ''}`
return (
<MuiLink href={`https://${url}`} target='_blank' rel='noopener'>
Expand Down
4 changes: 3 additions & 1 deletion src/components/forms/Autocomplete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export interface EnhancedAutocompleteProps<
/** Label for the "select all" option. */
selectAllLabel?: string
textFieldProps?: Partial<TextFieldProps>
width?: 'small' | 'medium' | 'large'
}

/**
Expand Down Expand Up @@ -70,6 +71,7 @@ export function Autocomplete<
textFieldProps,
value,
onChange,
width = 'medium',
...rest
} = props
const [inPlaceholder, setInPlaceholder] = useState('')
Expand All @@ -82,7 +84,7 @@ export function Autocomplete<
((params) => (
<TextField
label={label}
width='medium'
width={width}
loading={loading}
placeholder={inPlaceholder || (placeholder ?? 'Select an option')}
{...params}
Expand Down
2 changes: 1 addition & 1 deletion src/components/forms/FormRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default function FormRow(props: FormRowProps) {
<Box
display='flex'
flexDirection='row'
alignItems='flex-end'
alignItems='baseline'
sx={{
'& > *:not(:last-child)': {
marginRight: `${spacing}px`,
Expand Down
7 changes: 6 additions & 1 deletion src/components/forms/KeyValue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,12 @@ export default function KeyValue(props: KeyValueProps) {
))}
{addLabel && (
<Button
sx={{ fontSize: '10px', color: `${error ? 'red' : ''}` }}
sx={{
paddingLeft: 'inherit',
fontSize: '10px',
color: `${error ? 'red' : ''}`,
':hover': { backgroundColor: 'transparent' },
}}
className={classes.addItemButton}
onClick={handleAddItem}
>
Expand Down
88 changes: 88 additions & 0 deletions src/components/forms/KeyValueSingle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import React, { useState } from 'react'
import { Box } from '@mui/material'
import { TextField } from 'components/forms/TextField'
import { makeStyles } from '@mui/styles'
import { Typography } from 'components/Typography'
import { InputLabel } from 'components/InputLabel'
import { useFieldArray, useFormContext } from 'react-hook-form'
import FormRow from './FormRow'

const useStyles = makeStyles({
container: {
padding: '16px',
backgroundColor: '#424242',
borderRadius: '8px',
},
itemRow: {
marginBottom: '20px',
display: 'flex',
alignItems: 'center',
},
addItemButton: {
marginLeft: '-10px',
display: 'flex',
alignItems: 'center',
textTransform: 'none',
},
})

interface registers {
registerA: any
registerB: any
}

interface KeyValueProps {
title: string
subTitle?: string
keyLabel: string
keyValue?: string
keyDisabled?: boolean
showLabel?: boolean
valueLabel: string
valueDisabled?: boolean
name: string
registers?: registers
}

export default function KeyValue(props: KeyValueProps) {
const classes = useStyles()
const { control, register } = useFormContext()

const {
title,
subTitle,
keyLabel,
valueLabel,
name,
keyValue,
keyDisabled = false,
showLabel = true,
valueDisabled = false,
registers,
} = props

const [items, setItems] = useState([{ [keyLabel.toLowerCase()]: '', [valueLabel.toLowerCase()]: '' }])

const { fields, append, remove } = useFieldArray({
control,
name,
})

return (
<Box>
<InputLabel sx={{ fontWeight: 'bold', fontSize: '14px' }}>{title}</InputLabel>
{subTitle && <Typography sx={{ color: '#ABABAB' }}>{subTitle}</Typography>}

<FormRow spacing={10}>
<TextField
sx={{ color: '#B5B5BC' }}
disabled={keyDisabled}
value={keyValue}
label={showLabel ? keyLabel : ''}
{...registers.registerA}
/>
<TextField disabled={valueDisabled} label={showLabel ? valueLabel : ''} {...registers.registerB} />
</FormRow>
</Box>
)
}
93 changes: 93 additions & 0 deletions src/components/forms/LinkedNumberField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { Box, FormHelperText } from '@mui/material'
import { TextField } from './TextField'
import FormRow from './FormRow'

interface Registers {
registerA: any
registerB: any
setValue: (name: string, value: any) => void
watch: (name: string) => any
}

interface LinkedNumberFieldProps {
labelA: string
labelB: string
valueMax: number
disabled: boolean
registers: Registers
helperText?: string
error?: boolean
}

export default function LinkedNumberField({
labelA,
labelB,
valueMax,
disabled,
registers,
error,
helperText,
}: LinkedNumberFieldProps) {
const { setValue, watch } = registers
const defaultValue = valueMax / 2
const rawA = watch(registers.registerA.name)
const rawB = watch(registers.registerB.name)

const valueA: number = Math.min(Math.max(rawA ?? defaultValue, 0), valueMax)
const valueB: number = Math.min(Math.max(rawB ?? defaultValue, 0), valueMax)

function calculateValues(updatedValue: number, isValueA: boolean) {
const clamped = Math.min(Math.max(updatedValue, 0), valueMax)
const complementary = valueMax - clamped

if (isValueA) {
setValue(registers.registerA.name, clamped)
setValue(registers.registerB.name, complementary)
} else {
setValue(registers.registerA.name, complementary)
setValue(registers.registerB.name, clamped)
}
}

// Increment/Decrement helpers
const incrementA = () => calculateValues(valueA + 1, true)
const decrementA = () => calculateValues(valueA - 1, true)
const incrementB = () => calculateValues(valueB + 1, false)
const decrementB = () => calculateValues(valueB - 1, false)

return (
<Box>
<FormRow spacing={10}>
<TextField
{...registers.registerA}
width='small'
label={labelA}
value={valueA}
type='number'
inputProps={{ min: 0, max: valueMax }}
onChange={(e) => calculateValues(Number(e.target.value), true)}
onIncrement={incrementA}
onDecrement={decrementA}
suffixSymbol='%'
disabled={disabled}
error={error}
/>
<TextField
{...registers.registerB}
width='small'
label={labelB}
value={valueB}
type='number'
inputProps={{ min: 0, max: valueMax }}
onChange={(e) => calculateValues(Number(e.target.value), false)}
onIncrement={incrementB}
onDecrement={decrementB}
suffixSymbol='%'
disabled={disabled}
error={error}
/>
</FormRow>
{helperText && <FormHelperText data-qa-textfield-helper-text>{helperText}</FormHelperText>}
</Box>
)
}
Loading