+ );
+};
diff --git a/plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/CapacityEditor/index.ts b/plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/CapacityEditor/index.ts
new file mode 100644
index 00000000..6be676e5
--- /dev/null
+++ b/plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/CapacityEditor/index.ts
@@ -0,0 +1,17 @@
+/**
+ * Copyright 2024 The Nephio Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export { CapacityEditor } from './CapacityEditor';
diff --git a/plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/Controls/ValueListEditorAccordion.tsx b/plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/Controls/ValueListEditorAccordion.tsx
new file mode 100644
index 00000000..466da73e
--- /dev/null
+++ b/plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/Controls/ValueListEditorAccordion.tsx
@@ -0,0 +1,102 @@
+/**
+ * Copyright 2024 The Nephio Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { Button, TextField } from '@material-ui/core';
+import AddIcon from '@material-ui/icons/Add';
+import DeleteIcon from '@material-ui/icons/Delete';
+import React, { Fragment, useRef } from 'react';
+import { KubernetesValueList } from '../../../../../types/KubernetesResource';
+import { toLowerCase } from '../../../../../utils/string';
+import { IconButton } from '../../../../Controls';
+import { useEditorStyles } from '../styles';
+import { AccordionState, EditorAccordion } from './EditorAccordion';
+
+type ValueListEditorProps = {
+ id: string;
+ title: string;
+ state: AccordionState;
+ valueList: KubernetesValueList;
+ onUpdatedValueList: (valueList: KubernetesValueList) => void;
+};
+
+export const ValueListEditorAccordion = ({
+ id,
+ title,
+ state,
+ valueList,
+ onUpdatedValueList,
+}: ValueListEditorProps) => {
+ const refViewModel = useRef<{ value: string }[]>(
+ valueList.map(value => ({ value })),
+ );
+
+ const classes = useEditorStyles();
+
+ const valueUpdated = (): void => {
+ onUpdatedValueList(
+ refViewModel.current.map(valueHolder => valueHolder.value),
+ );
+ };
+
+ const addRow = () => {
+ refViewModel.current.push({ value: '' });
+ valueUpdated();
+ };
+
+ const description = `${refViewModel.current.length} ${toLowerCase(title)}`;
+
+ return (
+
+
+ {refViewModel.current.map((valueHolder, index) => (
+
+ );
+};
diff --git a/plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/NephioTokenEditor/index.ts b/plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/NephioTokenEditor/index.ts
new file mode 100644
index 00000000..d00009fb
--- /dev/null
+++ b/plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/NephioTokenEditor/index.ts
@@ -0,0 +1,17 @@
+/**
+ * Copyright 2024 The Nephio Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export { NephioTokenEditor } from './NephioTokenEditor';
diff --git a/plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/WorkloadClusterEditor/WorkloadClusterEditor.tsx b/plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/WorkloadClusterEditor/WorkloadClusterEditor.tsx
new file mode 100644
index 00000000..2ebe35e9
--- /dev/null
+++ b/plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/WorkloadClusterEditor/WorkloadClusterEditor.tsx
@@ -0,0 +1,135 @@
+/**
+ * Copyright 2024 The Nephio Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { TextField } from '@material-ui/core';
+import { useSetStateAndCall } from '../../../../../hooks/useSetStateAndCall';
+import { dumpYaml, loadYaml } from '../../../../../utils/yaml';
+import {
+ WorkloadCluster,
+ WorkloadClusterMetadata,
+ WorkloadClusterSpec,
+} from '../../../../../types/WorkloadCluster';
+import React, { Fragment, useState } from 'react';
+import {
+ EditorAccordion,
+ ResourceMetadataAccordion,
+ ValueListEditorAccordion,
+} from '../Controls';
+import { useEditorStyles } from '../styles';
+
+type OnUpdatedYamlFn = (yaml: string) => void;
+
+type ResourceEditorProps = {
+ yaml: string;
+ onUpdatedYaml: OnUpdatedYamlFn;
+};
+
+type State = {
+ metadata: WorkloadClusterMetadata;
+ spec: WorkloadClusterSpec;
+};
+
+const getWorkloadClusterConfigurationDescription = (
+ spec: WorkloadClusterSpec,
+) =>
+ [
+ `Name: ${spec.clusterName}`,
+ spec.masterInterface ? `master interface: ${spec.masterInterface}` : null,
+ ]
+ .filter(Boolean)
+ .join(', ');
+
+export const WorkloadClusterEditor = ({
+ yaml,
+ onUpdatedYaml,
+}: ResourceEditorProps) => {
+ const classes = useEditorStyles();
+ const resourceYaml = loadYaml(yaml) as WorkloadCluster;
+
+ const createResourceState = (): State => ({
+ metadata: resourceYaml.metadata,
+ spec: resourceYaml.spec,
+ });
+
+ const [state, setState] = useState(createResourceState());
+ const [expanded, setExpanded] = useState();
+
+ const setStateAndCall = useSetStateAndCall([state, setState], newState => {
+ onUpdatedYaml(dumpYaml({ ...resourceYaml, ...newState }));
+ });
+
+ return (
+
+ );
+};
diff --git a/plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/WorkloadClusterEditor/index.ts b/plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/WorkloadClusterEditor/index.ts
new file mode 100644
index 00000000..6b341dc7
--- /dev/null
+++ b/plugins/cad/src/components/ResourceEditorDialog/components/FirstClassEditors/WorkloadClusterEditor/index.ts
@@ -0,0 +1,17 @@
+/**
+ * Copyright 2024 The Nephio Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export { WorkloadClusterEditor } from './WorkloadClusterEditor';
diff --git a/plugins/cad/src/hooks/useSetStateAndCall.ts b/plugins/cad/src/hooks/useSetStateAndCall.ts
new file mode 100644
index 00000000..c8e3600e
--- /dev/null
+++ b/plugins/cad/src/hooks/useSetStateAndCall.ts
@@ -0,0 +1,16 @@
+import { Dispatch, SetStateAction, useCallback } from 'react';
+
+type SetStateAndCallFn = (createNewState: (currentState: S) => S) => void;
+
+export const useSetStateAndCall = (
+ [state, setState]: [S, Dispatch>],
+ callback: (newState: S) => void,
+): SetStateAndCallFn =>
+ useCallback(
+ createNewState => {
+ const newState = createNewState(state);
+ setState(newState);
+ callback(newState);
+ },
+ [state, setState, callback],
+ );
diff --git a/plugins/cad/src/types/Capacity.ts b/plugins/cad/src/types/Capacity.ts
new file mode 100644
index 00000000..15f8bbe4
--- /dev/null
+++ b/plugins/cad/src/types/Capacity.ts
@@ -0,0 +1,38 @@
+/**
+ * Copyright 2024 The Nephio Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { KubernetesKeyValueObject } from './KubernetesResource';
+
+export type Capacity = {
+ readonly apiVersion: string;
+ readonly kind: string;
+ readonly metadata: CapacityMetadata;
+ readonly spec: CapacitySpec;
+};
+
+export type CapacityMetadata = {
+ readonly name: string;
+ readonly namespace?: string;
+ readonly labels?: KubernetesKeyValueObject;
+ readonly annotations?: KubernetesKeyValueObject;
+};
+
+export type CapacitySpec = {
+ readonly maxDownlinkThroughput?: string;
+ readonly maxUplinkThroughput?: string;
+ readonly maxNFConnections?: number;
+ readonly maxSessions?: number;
+ readonly maxSubscribers?: number;
+};
diff --git a/plugins/cad/src/types/Deployment.ts b/plugins/cad/src/types/Deployment.ts
index c152b6d7..79c7fce5 100644
--- a/plugins/cad/src/types/Deployment.ts
+++ b/plugins/cad/src/types/Deployment.ts
@@ -16,6 +16,7 @@
import { KubernetesKeyValueObject } from './KubernetesResource';
import { PodTemplateSpec } from './Pod';
+import { LabelSelector } from './Selectors';
export type Deployment = {
apiVersion: string;
@@ -41,10 +42,6 @@ export type DeploymentSpec = {
revisionHistoryLimit?: number;
};
-export type LabelSelector = {
- matchLabels: KubernetesKeyValueObject;
-};
-
export type DeploymentStrategy = {
type?: string;
rollingUpdate?: RollingUpdateDeployment;
diff --git a/plugins/cad/src/types/KubernetesResource.ts b/plugins/cad/src/types/KubernetesResource.ts
index df9c1cb1..69df4e2e 100644
--- a/plugins/cad/src/types/KubernetesResource.ts
+++ b/plugins/cad/src/types/KubernetesResource.ts
@@ -30,3 +30,5 @@ export type KubernetesResourceMetadata = {
export type KubernetesKeyValueObject = {
[key: string]: string;
};
+
+export type KubernetesValueList = readonly string[];
diff --git a/plugins/cad/src/types/Selectors.ts b/plugins/cad/src/types/Selectors.ts
new file mode 100644
index 00000000..f33bb919
--- /dev/null
+++ b/plugins/cad/src/types/Selectors.ts
@@ -0,0 +1,39 @@
+/**
+ * Copyright 2024 The Nephio Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { KubernetesKeyValueObject } from './KubernetesResource';
+
+export type LabelSelector = {
+ matchLabels: KubernetesKeyValueObject;
+};
+
+export type LabelAndExpressionSelector = {
+ readonly matchLabels: KubernetesKeyValueObject;
+ readonly matchExpressions: readonly KubernetesLabelSelectorRequirement[];
+};
+
+export type KubernetesLabelSelectorRequirement = {
+ readonly key: string;
+ readonly operator: KubernetesLabelSelectorOperator;
+ readonly values?: readonly string[];
+};
+
+export enum KubernetesLabelSelectorOperator {
+ In = 'In',
+ NotIn = 'NotIn',
+ Exists = 'Exists',
+ DoesNotExist = 'DoesNotExist',
+}
diff --git a/plugins/cad/src/types/StatefulSet.ts b/plugins/cad/src/types/StatefulSet.ts
index a75979e9..4d80e288 100644
--- a/plugins/cad/src/types/StatefulSet.ts
+++ b/plugins/cad/src/types/StatefulSet.ts
@@ -17,6 +17,7 @@
import { KubernetesKeyValueObject } from './KubernetesResource';
import { PersistentVolumeClaim } from './PersistentVolumeClaim';
import { PodTemplateSpec } from './Pod';
+import { LabelSelector } from './Selectors';
export type StatefulSet = {
apiVersion: string;
@@ -44,10 +45,6 @@ export type StatefulSetSpec = {
volumeClaimTemplates?: PersistentVolumeClaim[];
};
-export type LabelSelector = {
- matchLabels: KubernetesKeyValueObject;
-};
-
export type StatefulSetUpdateStrategy = {
type?: string;
rollingUpdate?: RollingUpdateStatefulSetStrategy;
diff --git a/plugins/cad/src/types/Token.ts b/plugins/cad/src/types/Token.ts
new file mode 100644
index 00000000..3b029758
--- /dev/null
+++ b/plugins/cad/src/types/Token.ts
@@ -0,0 +1,36 @@
+/**
+ * Copyright 2024 The Nephio Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { KubernetesKeyValueObject } from './KubernetesResource';
+
+export type NephioToken = {
+ readonly apiVersion: string;
+ readonly kind: string;
+ readonly metadata: NephioTokenMetadata;
+ readonly spec: NephioTokenSpec;
+};
+
+export type NephioTokenMetadata = {
+ readonly name: string;
+ readonly namespace?: string;
+ readonly labels?: KubernetesKeyValueObject;
+ readonly annotations?: KubernetesKeyValueObject;
+};
+
+export type NephioTokenSpec = {
+ readonly lifecycle?: {
+ readonly deletionPolicy?: string;
+ };
+};
diff --git a/plugins/cad/src/types/WorkloadCluster.ts b/plugins/cad/src/types/WorkloadCluster.ts
new file mode 100644
index 00000000..4b9ddd51
--- /dev/null
+++ b/plugins/cad/src/types/WorkloadCluster.ts
@@ -0,0 +1,40 @@
+/**
+ * Copyright 2024 The Nephio Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { KubernetesKeyValueObject } from './KubernetesResource';
+
+/*
+ * TODO Similar type definitions are heavily duplicated across types directory.
+ * Introduce generic types which can be used instead.
+ */
+export type WorkloadCluster = {
+ readonly apiVersion: string;
+ readonly kind: string;
+ readonly metadata: WorkloadClusterMetadata;
+ readonly spec: WorkloadClusterSpec;
+};
+
+export type WorkloadClusterMetadata = {
+ readonly name: string;
+ readonly namespace?: string;
+ readonly labels?: KubernetesKeyValueObject;
+ readonly annotations?: KubernetesKeyValueObject;
+};
+
+export type WorkloadClusterSpec = {
+ readonly clusterName: string;
+ readonly cnis?: readonly string[];
+ readonly masterInterface?: string;
+};