@dovetail-v2/refine 0.3.13-alpha.0 → 0.3.14-alpha.0

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.
@@ -38,6 +38,7 @@ export type InternalTableProps<Data extends {
38
38
  showMenuColumn?: boolean;
39
39
  hideNamespacesFilter?: boolean;
40
40
  customNamespaceFilter?: React.ReactNode;
41
+ onClearSearchKeyword?: () => void;
41
42
  };
42
43
  declare function Table<Data extends {
43
44
  id: string;
@@ -7,3 +7,4 @@ export * from './useEdit';
7
7
  export * from './useGlobalStore';
8
8
  export * from './useOpenForm';
9
9
  export { default as useNamespaceRefineFilter } from './useNamespaceRefineFilter';
10
+ export * from './useRefineFilters';
@@ -0,0 +1,9 @@
1
+ export declare const NAME_KEYWORD_PARAM = "name_keyword";
2
+ interface UseRefineFiltersOptions {
3
+ disableNamespaceFilter?: boolean;
4
+ disableNameKeywordFilter?: boolean;
5
+ }
6
+ export declare function useRefineFilters(options?: UseRefineFiltersOptions): {
7
+ permanent: import("@refinedev/core").CrudFilter[];
8
+ };
9
+ export {};
package/dist/i18n.d.ts CHANGED
@@ -524,6 +524,8 @@ export declare const resources: {
524
524
  target_service: string;
525
525
  target_service_port: string;
526
526
  select_workload: string;
527
+ no_search_result: string;
528
+ clear_search_condition: string;
527
529
  };
528
530
  };
529
531
  };
@@ -268,6 +268,8 @@ declare const _default: {
268
268
  target_service: string;
269
269
  target_service_port: string;
270
270
  select_workload: string;
271
+ no_search_result: string;
272
+ clear_search_condition: string;
271
273
  };
272
274
  };
273
275
  export default _default;
@@ -0,0 +1,10 @@
1
+ import { GlobalStore, Unstructured } from 'k8s-api-provider';
2
+ import { ControllerRevision } from 'kubernetes-types/apps/v1';
3
+ import { ResourceModel } from './resource-model';
4
+ type RequiredControllerRevision = Required<ControllerRevision> & Unstructured;
5
+ export declare class ControllerRevisionModel extends ResourceModel<RequiredControllerRevision> {
6
+ _rawYaml: RequiredControllerRevision;
7
+ constructor(_rawYaml: RequiredControllerRevision, _globalStore: GlobalStore);
8
+ get revision(): number;
9
+ }
10
+ export {};
@@ -1,6 +1,7 @@
1
1
  import { GlobalStore, Unstructured } from 'k8s-api-provider';
2
2
  import { DaemonSet } from 'kubernetes-types/apps/v1';
3
3
  import { ResourceState } from '../constants';
4
+ import { ControllerRevisionModel } from './controller-revison-model';
4
5
  import { WorkloadModel } from './workload-model';
5
6
  type RequiredDaemonSet = Required<DaemonSet> & Unstructured;
6
7
  export declare class DaemonSetModel extends WorkloadModel {
@@ -8,6 +9,8 @@ export declare class DaemonSetModel extends WorkloadModel {
8
9
  spec?: RequiredDaemonSet['spec'];
9
10
  status?: RequiredDaemonSet['status'];
10
11
  constructor(_rawYaml: RequiredDaemonSet, _globalStore: GlobalStore);
12
+ getControllerRevisions(controllerVisions: ControllerRevisionModel[]): ControllerRevisionModel[];
13
+ getRevision(controllerVisions: ControllerRevisionModel[]): number;
11
14
  get stateDisplay(): ResourceState.UPDATING | ResourceState.READY;
12
15
  get replicas(): number;
13
16
  get readyReplicas(): number;
@@ -8,12 +8,11 @@ export declare class DeploymentModel extends WorkloadModel {
8
8
  _rawYaml: RequiredDeployment;
9
9
  spec?: RequiredDeployment['spec'];
10
10
  status?: RequiredDeployment['status'];
11
- replicaSets: ReplicaSetModel[];
12
11
  constructor(_rawYaml: RequiredDeployment, _globalStore: GlobalStore);
13
12
  init(): Promise<void>;
14
- private getReplicaSets;
13
+ getReplicaSets(replicaSets: ReplicaSetModel[]): ReplicaSetModel[];
15
14
  get stateDisplay(): ResourceState.UPDATING | ResourceState.READY | ResourceState.STOPPED;
16
15
  get revision(): string | undefined;
17
- get currentReplicaSet(): ReplicaSetModel | undefined;
16
+ getCurrentReplicaSet(replicaSets: ReplicaSetModel[]): ReplicaSetModel | undefined;
18
17
  }
19
18
  export {};
@@ -17,3 +17,5 @@ export * from './node-model';
17
17
  export * from './storage-class';
18
18
  export * from './persistent-volume';
19
19
  export * from './persistent-volume-claim';
20
+ export * from './controller-revison-model';
21
+ export * from './ingress-class-model';
@@ -0,0 +1,12 @@
1
+ import { GlobalStore, Unstructured } from 'k8s-api-provider';
2
+ import { IngressClass } from 'kubernetes-types/networking/v1';
3
+ import { ResourceModel } from './resource-model';
4
+ type RequiredIngressClass = Required<IngressClass> & Unstructured;
5
+ export declare class IngressClassModel extends ResourceModel<RequiredIngressClass> {
6
+ _rawYaml: RequiredIngressClass;
7
+ spec?: RequiredIngressClass['spec'];
8
+ constructor(_rawYaml: RequiredIngressClass, _globalStore: GlobalStore);
9
+ get isDefault(): boolean;
10
+ get controller(): string | undefined;
11
+ }
12
+ export {};
@@ -1,6 +1,7 @@
1
1
  import { GlobalStore, Unstructured } from 'k8s-api-provider';
2
2
  import type { Pod } from 'kubernetes-types/core/v1';
3
3
  import { DeploymentModel } from './deployment-model';
4
+ import { ReplicaSetModel } from './replicaset-model';
4
5
  import { ResourceQuantity } from './types/metric';
5
6
  import { WorkloadBaseModel } from './workload-base-model';
6
7
  type RequiredPod = Required<Pod> & Unstructured;
@@ -11,7 +12,7 @@ export declare class PodModel extends WorkloadBaseModel {
11
12
  spec?: RequiredPod['spec'];
12
13
  status?: RequiredPod['status'];
13
14
  constructor(_rawYaml: RequiredPod, _globalStore: GlobalStore);
14
- getBelongToDeployment(deployments: DeploymentModel[]): DeploymentModel | undefined;
15
+ getBelongToDeployment(deployments: DeploymentModel[], replicaSets: ReplicaSetModel[]): DeploymentModel | undefined;
15
16
  get imageNames(): string[];
16
17
  get restarts(): number;
17
18
  get readyDisplay(): string;
@@ -1,6 +1,7 @@
1
1
  import { GlobalStore, Unstructured } from 'k8s-api-provider';
2
2
  import { StatefulSet } from 'kubernetes-types/apps/v1';
3
3
  import { ResourceState } from '../constants';
4
+ import { ControllerRevisionModel } from './controller-revison-model';
4
5
  import { WorkloadModel } from './workload-model';
5
6
  type RequiredStatefulSet = Required<StatefulSet> & Unstructured;
6
7
  export declare class StatefulSetModel extends WorkloadModel {
@@ -8,6 +9,8 @@ export declare class StatefulSetModel extends WorkloadModel {
8
9
  spec?: RequiredStatefulSet['spec'];
9
10
  status?: RequiredStatefulSet['status'];
10
11
  constructor(_rawYaml: RequiredStatefulSet, _globalStore: GlobalStore);
12
+ getControllerRevisions(controllerVisions: ControllerRevisionModel[]): ControllerRevisionModel[];
13
+ getRevision(controllerVisions: ControllerRevisionModel[]): number;
11
14
  get stateDisplay(): ResourceState.UPDATING | ResourceState.READY | ResourceState.STOPPED;
12
15
  }
13
16
  export {};
package/dist/refine.cjs CHANGED
@@ -1225,6 +1225,8 @@ const label_annotations = "标签与注解";
1225
1225
  const target_service = "目标服务";
1226
1226
  const target_service_port = "目标服务端口";
1227
1227
  const select_workload = "选择工作负载";
1228
+ const no_search_result = "无搜索结果";
1229
+ const clear_search_condition = "清空搜索条件";
1228
1230
  const dovetail = {
1229
1231
  copy,
1230
1232
  reset_arguments,
@@ -1493,7 +1495,9 @@ const dovetail = {
1493
1495
  label_annotations,
1494
1496
  target_service,
1495
1497
  target_service_port,
1496
- select_workload
1498
+ select_workload,
1499
+ no_search_result,
1500
+ clear_search_condition
1497
1501
  };
1498
1502
  const ZH = {
1499
1503
  dovetail
@@ -7995,7 +7999,7 @@ const WidgetErrorContent = (props) => {
7995
7999
  children: [/* @__PURE__ */ common.jsxRuntimeExports.jsx("p", {
7996
8000
  className: common.cx_default(fontMap[type2], "title", `${type2}-title`),
7997
8001
  children: errorText || t2("dovetail.obtain_data_error")
7998
- }), !refetch ? null : /* @__PURE__ */ common.jsxRuntimeExports.jsx(kit.button, {
8002
+ }), props.children, !refetch ? null : /* @__PURE__ */ common.jsxRuntimeExports.jsx(kit.button, {
7999
8003
  size: type2 === "list" ? "middle" : "small",
8000
8004
  type: "ordinary",
8001
8005
  onClick: (e2) => {
@@ -9620,9 +9624,9 @@ class PodModel extends WorkloadBaseModel {
9620
9624
  }
9621
9625
  };
9622
9626
  }
9623
- getBelongToDeployment(deployments) {
9627
+ getBelongToDeployment(deployments, replicaSets) {
9624
9628
  return deployments.find((deployment) => {
9625
- return deployment.replicaSets.find((replicaSet) => {
9629
+ return deployment.getReplicaSets(replicaSets).find((replicaSet) => {
9626
9630
  return replicaSet.pods.find((pod2) => pod2.metadata.uid === this.metadata.uid);
9627
9631
  });
9628
9632
  });
@@ -9808,26 +9812,19 @@ class EventModel extends ResourceModel {
9808
9812
  class DeploymentModel extends WorkloadModel {
9809
9813
  constructor(_rawYaml, _globalStore) {
9810
9814
  super(_rawYaml, _globalStore);
9811
- __publicField(this, "replicaSets", []);
9812
9815
  this._rawYaml = _rawYaml;
9813
9816
  }
9814
9817
  async init() {
9815
9818
  await super.init();
9816
- await this.getReplicaSets();
9817
9819
  }
9818
- async getReplicaSets() {
9819
- const replicaSets = await this._globalStore.get("replicasets", {
9820
- resourceBasePath: "/apis/apps/v1",
9821
- kind: "ReplicaSet"
9822
- });
9823
- const myReplicaSets = replicaSets.items.filter((rs) => {
9820
+ getReplicaSets(replicaSets) {
9821
+ return replicaSets.filter((rs) => {
9824
9822
  var _a, _b, _c;
9825
9823
  const ownerRef = (_b = (_a = rs.metadata) == null ? void 0 : _a.ownerReferences) == null ? void 0 : _b.find(
9826
9824
  (ref) => ref.kind === "Deployment" && ref.apiVersion === "apps/v1" && ref.name === this.name && ref.uid === this.metadata.uid
9827
9825
  );
9828
9826
  return !!ownerRef && ((_c = rs.metadata) == null ? void 0 : _c.namespace) === this.metadata.namespace;
9829
9827
  });
9830
- this.replicaSets = myReplicaSets;
9831
9828
  }
9832
9829
  get stateDisplay() {
9833
9830
  var _a, _b, _c;
@@ -9842,8 +9839,9 @@ class DeploymentModel extends WorkloadModel {
9842
9839
  var _a, _b;
9843
9840
  return (_b = (_a = this.metadata) == null ? void 0 : _a.annotations) == null ? void 0 : _b["deployment.kubernetes.io/revision"];
9844
9841
  }
9845
- get currentReplicaSet() {
9846
- return this.replicaSets.find((rs) => rs.revision === this.revision);
9842
+ getCurrentReplicaSet(replicaSets) {
9843
+ const myReplicaSets = this.getReplicaSets(replicaSets);
9844
+ return myReplicaSets.find((rs) => rs.revision === this.revision);
9847
9845
  }
9848
9846
  }
9849
9847
  class DaemonSetModel extends WorkloadModel {
@@ -9851,6 +9849,22 @@ class DaemonSetModel extends WorkloadModel {
9851
9849
  super(_rawYaml, _globalStore);
9852
9850
  this._rawYaml = _rawYaml;
9853
9851
  }
9852
+ getControllerRevisions(controllerVisions) {
9853
+ return controllerVisions.filter(
9854
+ (controllerRevision) => {
9855
+ var _a, _b;
9856
+ return (_b = (_a = controllerRevision.metadata) == null ? void 0 : _a.ownerReferences) == null ? void 0 : _b.some(
9857
+ (ownerReference) => ownerReference.kind === "DaemonSet" && ownerReference.uid === this.metadata.uid
9858
+ );
9859
+ }
9860
+ );
9861
+ }
9862
+ getRevision(controllerVisions) {
9863
+ const myControllerVisions = this.getControllerRevisions(controllerVisions);
9864
+ return myControllerVisions.reduce((result, controllerRevision) => {
9865
+ return Math.max(result, Number(controllerRevision.revision || 0));
9866
+ }, 0);
9867
+ }
9854
9868
  get stateDisplay() {
9855
9869
  var _a, _b;
9856
9870
  if (((_a = this.status) == null ? void 0 : _a.desiredNumberScheduled) !== ((_b = this.status) == null ? void 0 : _b.numberReady)) {
@@ -9870,6 +9884,22 @@ class StatefulSetModel extends WorkloadModel {
9870
9884
  super(_rawYaml, _globalStore);
9871
9885
  this._rawYaml = _rawYaml;
9872
9886
  }
9887
+ getControllerRevisions(controllerVisions) {
9888
+ return controllerVisions.filter(
9889
+ (controllerRevision) => {
9890
+ var _a, _b;
9891
+ return (_b = (_a = controllerRevision.metadata) == null ? void 0 : _a.ownerReferences) == null ? void 0 : _b.some(
9892
+ (ownerReference) => ownerReference.kind === "DaemonSet" && ownerReference.uid === this.metadata.uid
9893
+ );
9894
+ }
9895
+ );
9896
+ }
9897
+ getRevision(controllerVisions) {
9898
+ const myControllerVisions = this.getControllerRevisions(controllerVisions);
9899
+ return myControllerVisions.reduce((result, controllerRevision) => {
9900
+ return Math.max(result, Number(controllerRevision.revision || 0));
9901
+ }, 0);
9902
+ }
9873
9903
  get stateDisplay() {
9874
9904
  var _a, _b, _c;
9875
9905
  if (((_a = this.spec) == null ? void 0 : _a.replicas) === 0) {
@@ -10072,6 +10102,29 @@ class PersistentVolumeClaimModel extends ResourceModel {
10072
10102
  return lodashEs.set(yaml2, "spec.resources.requests.storage", `${distributeStorage}Gi`);
10073
10103
  }
10074
10104
  }
10105
+ class ControllerRevisionModel extends ResourceModel {
10106
+ constructor(_rawYaml, _globalStore) {
10107
+ super(_rawYaml, _globalStore);
10108
+ this._rawYaml = _rawYaml;
10109
+ }
10110
+ get revision() {
10111
+ return this._rawYaml.revision;
10112
+ }
10113
+ }
10114
+ class IngressClassModel extends ResourceModel {
10115
+ constructor(_rawYaml, _globalStore) {
10116
+ super(_rawYaml, _globalStore);
10117
+ this._rawYaml = _rawYaml;
10118
+ }
10119
+ get isDefault() {
10120
+ var _a, _b;
10121
+ return ((_b = (_a = this._rawYaml.metadata) == null ? void 0 : _a.annotations) == null ? void 0 : _b["ingressclass.kubernetes.io/is-default-class"]) === "true";
10122
+ }
10123
+ get controller() {
10124
+ var _a;
10125
+ return (_a = this.spec) == null ? void 0 : _a.controller;
10126
+ }
10127
+ }
10075
10128
  const index_1r58r8x = "";
10076
10129
  const ServiceInClusterAccessComponent = ({
10077
10130
  service
@@ -10659,6 +10712,9 @@ function validateLabelKey(key2) {
10659
10712
  if (prefix2 && prefix2.length > 253) {
10660
10713
  return { isValid: false };
10661
10714
  }
10715
+ if (!labelRegex.test(name2)) {
10716
+ return { isValid: false };
10717
+ }
10662
10718
  if (name2 && name2.length > 63) {
10663
10719
  return { isValid: false };
10664
10720
  }
@@ -10977,7 +11033,6 @@ const TableToolBar = ({
10977
11033
  selectedKeys,
10978
11034
  hideCreate
10979
11035
  }) => {
10980
- var _a;
10981
11036
  const {
10982
11037
  resource
10983
11038
  } = core.useResource();
@@ -10987,7 +11042,7 @@ const TableToolBar = ({
10987
11042
  className: ToolbarStyle$1,
10988
11043
  children: [/* @__PURE__ */ common.jsxRuntimeExports.jsx("span", {
10989
11044
  className: common.cx_default(eagle.Typo.Display.d2_regular_title, TitleStyle$2),
10990
- children: title || ((_a = resource == null ? void 0 : resource.meta) == null ? void 0 : _a.kind)
11045
+ children: title
10991
11046
  }), /* @__PURE__ */ common.jsxRuntimeExports.jsxs(eagle.Space, {
10992
11047
  children: [selectedKeys.length > 0 ? /* @__PURE__ */ common.jsxRuntimeExports.jsx(DeleteManyButton, {
10993
11048
  ids: selectedKeys
@@ -12071,9 +12126,18 @@ function Table(props) {
12071
12126
  const { tableProps, displayName, errorContentProps } = props;
12072
12127
  const { Table: TableComponent } = React.useContext(ComponentContext);
12073
12128
  const Table2 = TableComponent || Table$1;
12129
+ const { params } = core.useParsed();
12074
12130
  const { i18n: i18n2 } = common.useTranslation();
12075
12131
  const resourceType = transformResourceKindInSentence(displayName, i18n2.language);
12076
12132
  if (!((_a = tableProps.data) == null ? void 0 : _a.length) && !tableProps.loading) {
12133
+ const nameKeyword = (params == null ? void 0 : params[NAME_KEYWORD_PARAM]) || "";
12134
+ if (nameKeyword) {
12135
+ const onClear = () => {
12136
+ var _a2;
12137
+ (_a2 = tableProps.onClearSearchKeyword) == null ? void 0 : _a2.call(tableProps);
12138
+ };
12139
+ return /* @__PURE__ */ common.jsxRuntimeExports.jsx(WidgetErrorContent, { errorText: i18n2.t("dovetail.no_search_result"), children: /* @__PURE__ */ common.jsxRuntimeExports.jsx(eagle.Button, { onClick: onClear, type: "ordinary", children: i18n2.t("dovetail.clear_search_condition") }) });
12140
+ }
12077
12141
  return /* @__PURE__ */ common.jsxRuntimeExports.jsx(
12078
12142
  WidgetErrorContent,
12079
12143
  {
@@ -14427,30 +14491,6 @@ const NamespacesFilter = ({
14427
14491
  })
14428
14492
  });
14429
14493
  };
14430
- function useNamespaceRefineFilter() {
14431
- const { value: nsFilters = [] } = useNamespacesFilter();
14432
- const filters = React.useMemo(() => {
14433
- const filters2 = nsFilters.filter((filter) => filter !== ALL_NS);
14434
- if (filters2.length === 0) {
14435
- return {
14436
- permanent: []
14437
- };
14438
- }
14439
- return {
14440
- permanent: [
14441
- {
14442
- operator: "or",
14443
- value: filters2.map((filter) => ({
14444
- field: "metadata.namespace",
14445
- operator: "eq",
14446
- value: filter
14447
- }))
14448
- }
14449
- ]
14450
- };
14451
- }, [nsFilters]);
14452
- return filters;
14453
- }
14454
14494
  const index_1l2xllo = "";
14455
14495
  const ListPageStyle = "laykzsq";
14456
14496
  const ListContentStyle = "l1ng0psc";
@@ -14473,7 +14513,7 @@ function ListPage(props) {
14473
14513
  children: [!config.hideListToolBar ? /* @__PURE__ */ common.jsxRuntimeExports.jsxs(common.jsxRuntimeExports.Fragment, {
14474
14514
  children: [/* @__PURE__ */ common.jsxRuntimeExports.jsx(TableToolBar, {
14475
14515
  selectedKeys,
14476
- title: config == null ? void 0 : config.displayName,
14516
+ title: (config == null ? void 0 : config.customListTitle) || (config == null ? void 0 : config.displayName) || config.kind,
14477
14517
  description: config == null ? void 0 : config.description,
14478
14518
  hideCreate: config == null ? void 0 : config.hideCreate
14479
14519
  }), belowToolBarContent, /* @__PURE__ */ common.jsxRuntimeExports.jsx(eagle.Divider, {
@@ -14510,7 +14550,7 @@ function ResourceList(props) {
14510
14550
  const { formatter, columns, Dropdown, noShow } = props.config;
14511
14551
  const { i18n: i18n2 } = common.useTranslation();
14512
14552
  const nameRenderer = noShow ? PlainTextNameColumnRenderer(i18n2) : NameColumnRenderer(i18n2);
14513
- const filters = useNamespaceRefineFilter();
14553
+ const filters = useRefineFilters();
14514
14554
  const { tableProps, selectedKeys } = useEagleTable({
14515
14555
  useTableParams: {
14516
14556
  filters
@@ -18987,7 +19027,7 @@ const AgeColumnRenderer = (i18n2, config, {
18987
19027
  dataIndex,
18988
19028
  title: i18n2.t("dovetail.created_time"),
18989
19029
  width: 120,
18990
- sorter: true,
19030
+ sorter: CommonSorter(dataIndex),
18991
19031
  render: (value2) => {
18992
19032
  return isRelativeTime ? /* @__PURE__ */ common.jsxRuntimeExports.jsx(Time, {
18993
19033
  date: new Date(value2)
@@ -19537,6 +19577,78 @@ const SCAllowExpandColumnRenderer = (i18n2) => {
19537
19577
  }
19538
19578
  };
19539
19579
  };
19580
+ function useNamespaceRefineFilter() {
19581
+ const { value: nsFilters = [] } = useNamespacesFilter();
19582
+ const filters = React.useMemo(() => {
19583
+ const filters2 = nsFilters.filter((filter) => filter !== ALL_NS);
19584
+ if (filters2.length === 0) {
19585
+ return {
19586
+ permanent: []
19587
+ };
19588
+ }
19589
+ return {
19590
+ permanent: [
19591
+ {
19592
+ operator: "or",
19593
+ value: filters2.map((filter) => ({
19594
+ field: "metadata.namespace",
19595
+ operator: "eq",
19596
+ value: filter
19597
+ }))
19598
+ }
19599
+ ]
19600
+ };
19601
+ }, [nsFilters]);
19602
+ return filters;
19603
+ }
19604
+ const NAME_KEYWORD_PARAM = "name_keyword";
19605
+ function useRefineFilters(options = {}) {
19606
+ const {
19607
+ disableNamespaceFilter = false,
19608
+ disableNameKeywordFilter = false
19609
+ } = options;
19610
+ const { value: nsFilters = [] } = useNamespacesFilter();
19611
+ const namespaceFilters = React.useMemo(() => {
19612
+ if (disableNamespaceFilter) {
19613
+ return [];
19614
+ }
19615
+ const filters2 = nsFilters.filter((filter) => filter !== ALL_NS);
19616
+ if (filters2.length === 0) {
19617
+ return [];
19618
+ }
19619
+ return [
19620
+ {
19621
+ operator: "or",
19622
+ value: filters2.map((filter) => ({
19623
+ field: "metadata.namespace",
19624
+ operator: "eq",
19625
+ value: filter
19626
+ }))
19627
+ }
19628
+ ];
19629
+ }, [nsFilters, disableNamespaceFilter]);
19630
+ const { params } = core.useParsed();
19631
+ const nameKeyword = params == null ? void 0 : params[NAME_KEYWORD_PARAM];
19632
+ const nameKeywordFilters = React.useMemo(() => {
19633
+ if (disableNameKeywordFilter || !nameKeyword || nameKeyword.trim() === "") {
19634
+ return [];
19635
+ }
19636
+ return [
19637
+ {
19638
+ field: "metadata.name",
19639
+ operator: "contains",
19640
+ value: nameKeyword.trim()
19641
+ }
19642
+ ];
19643
+ }, [nameKeyword, disableNameKeywordFilter]);
19644
+ const filters = React.useMemo(
19645
+ () => ({
19646
+ permanent: [...namespaceFilters, ...nameKeywordFilters]
19647
+ }),
19648
+ [namespaceFilters, nameKeywordFilters]
19649
+ );
19650
+ return filters;
19651
+ }
19540
19652
  const styles = "";
19541
19653
  const Dovetail = (props) => {
19542
19654
  const {
@@ -19648,7 +19760,9 @@ class ModelPlugin {
19648
19760
  StorageClass: StorageClassModel,
19649
19761
  PersistentVolume: PersistentVolumeModel,
19650
19762
  PersistentVolumeClaim: PersistentVolumeClaimModel,
19651
- ReplicaSet: ReplicaSetModel
19763
+ ReplicaSet: ReplicaSetModel,
19764
+ ControllerRevision: ControllerRevisionModel,
19765
+ IngressClass: IngressClassModel
19652
19766
  })
19653
19767
  ));
19654
19768
  }
@@ -19795,6 +19909,7 @@ exports.ConditionsGroup = ConditionsGroup;
19795
19909
  exports.ConditionsTab = ConditionsTab;
19796
19910
  exports.ConditionsTable = ConditionsTable;
19797
19911
  exports.ConfigsContext = ConfigsContext;
19912
+ exports.ControllerRevisionModel = ControllerRevisionModel;
19798
19913
  exports.CreateButton = CreateButton;
19799
19914
  exports.CronJobDropdown = CronJobDropdown;
19800
19915
  exports.CronJobModel = CronJobModel;
@@ -19838,6 +19953,7 @@ exports.INGRESS_INIT_VALUE = INGRESS_INIT_VALUE;
19838
19953
  exports.ImageField = ImageField;
19839
19954
  exports.ImageNames = ImageNames;
19840
19955
  exports.IngressClassColumnRenderer = IngressClassColumnRenderer;
19956
+ exports.IngressClassModel = IngressClassModel;
19841
19957
  exports.IngressDefaultBackendColumnRenderer = IngressDefaultBackendColumnRenderer;
19842
19958
  exports.IngressModel = IngressModel;
19843
19959
  exports.IngressRulesColumnRenderer = IngressRulesColumnRenderer;
@@ -19868,6 +19984,7 @@ exports.MetadataForm = MetadataForm;
19868
19984
  exports.ModelPlugin = ModelPlugin;
19869
19985
  exports.MonacoYamlDiffEditor = MonacoYamlDiffEditor;
19870
19986
  exports.MonacoYamlEditor = MonacoYamlEditor;
19987
+ exports.NAME_KEYWORD_PARAM = NAME_KEYWORD_PARAM;
19871
19988
  exports.NETWORK_POLICY_INIT_VALUE = NETWORK_POLICY_INIT_VALUE;
19872
19989
  exports.NODE_INIT_VALUE = NODE_INIT_VALUE;
19873
19990
  exports.NS_STORE_KEY = NS_STORE_KEY;
@@ -20035,6 +20152,7 @@ exports.generateSchemaTypeValue = generateSchemaTypeValue;
20035
20152
  exports.generateValueFromSchema = generateValueFromSchema;
20036
20153
  exports.getApiVersion = getApiVersion;
20037
20154
  exports.getResourceNameByKind = getResourceNameByKind;
20155
+ exports.isFirstLetterEnglish = isFirstLetterEnglish;
20038
20156
  exports.matchSelector = matchSelector;
20039
20157
  exports.modelPlugin = modelPlugin;
20040
20158
  exports.namespaceRules = namespaceRules;
@@ -20045,6 +20163,8 @@ exports.resolveRef = resolveRef;
20045
20163
  exports.rfc1035LabelRules = rfc1035LabelRules;
20046
20164
  exports.rfc1123LabelRules = rfc1123LabelRules;
20047
20165
  exports.routerProvider = routerProvider;
20166
+ exports.shortenedImage = shortenedImage;
20167
+ exports.transformResourceKindInSentence = transformResourceKindInSentence;
20048
20168
  exports.useApiGroupSchema = useApiGroupSchema;
20049
20169
  exports.useDeleteModal = useDeleteModal;
20050
20170
  exports.useDeleteModalOnly = useDeleteModalOnly;
@@ -20056,6 +20176,7 @@ exports.useGlobalStore = useGlobalStore;
20056
20176
  exports.useNamespaceRefineFilter = useNamespaceRefineFilter;
20057
20177
  exports.useNamespacesFilter = useNamespacesFilter;
20058
20178
  exports.useOpenForm = useOpenForm;
20179
+ exports.useRefineFilters = useRefineFilters;
20059
20180
  exports.useRefineForm = useRefineForm;
20060
20181
  exports.useSchema = useSchema;
20061
20182
  exports.validateDataKey = validateDataKey;
package/dist/refine.js CHANGED
@@ -1206,6 +1206,8 @@ const label_annotations = "标签与注解";
1206
1206
  const target_service = "目标服务";
1207
1207
  const target_service_port = "目标服务端口";
1208
1208
  const select_workload = "选择工作负载";
1209
+ const no_search_result = "无搜索结果";
1210
+ const clear_search_condition = "清空搜索条件";
1209
1211
  const dovetail = {
1210
1212
  copy,
1211
1213
  reset_arguments,
@@ -1474,7 +1476,9 @@ const dovetail = {
1474
1476
  label_annotations,
1475
1477
  target_service,
1476
1478
  target_service_port,
1477
- select_workload
1479
+ select_workload,
1480
+ no_search_result,
1481
+ clear_search_condition
1478
1482
  };
1479
1483
  const ZH = {
1480
1484
  dovetail
@@ -7976,7 +7980,7 @@ const WidgetErrorContent = (props) => {
7976
7980
  children: [/* @__PURE__ */ jsxRuntimeExports.jsx("p", {
7977
7981
  className: cx_default(fontMap[type2], "title", `${type2}-title`),
7978
7982
  children: errorText || t2("dovetail.obtain_data_error")
7979
- }), !refetch ? null : /* @__PURE__ */ jsxRuntimeExports.jsx(kit.button, {
7983
+ }), props.children, !refetch ? null : /* @__PURE__ */ jsxRuntimeExports.jsx(kit.button, {
7980
7984
  size: type2 === "list" ? "middle" : "small",
7981
7985
  type: "ordinary",
7982
7986
  onClick: (e2) => {
@@ -9601,9 +9605,9 @@ class PodModel extends WorkloadBaseModel {
9601
9605
  }
9602
9606
  };
9603
9607
  }
9604
- getBelongToDeployment(deployments) {
9608
+ getBelongToDeployment(deployments, replicaSets) {
9605
9609
  return deployments.find((deployment) => {
9606
- return deployment.replicaSets.find((replicaSet) => {
9610
+ return deployment.getReplicaSets(replicaSets).find((replicaSet) => {
9607
9611
  return replicaSet.pods.find((pod2) => pod2.metadata.uid === this.metadata.uid);
9608
9612
  });
9609
9613
  });
@@ -9789,26 +9793,19 @@ class EventModel extends ResourceModel {
9789
9793
  class DeploymentModel extends WorkloadModel {
9790
9794
  constructor(_rawYaml, _globalStore) {
9791
9795
  super(_rawYaml, _globalStore);
9792
- __publicField(this, "replicaSets", []);
9793
9796
  this._rawYaml = _rawYaml;
9794
9797
  }
9795
9798
  async init() {
9796
9799
  await super.init();
9797
- await this.getReplicaSets();
9798
9800
  }
9799
- async getReplicaSets() {
9800
- const replicaSets = await this._globalStore.get("replicasets", {
9801
- resourceBasePath: "/apis/apps/v1",
9802
- kind: "ReplicaSet"
9803
- });
9804
- const myReplicaSets = replicaSets.items.filter((rs) => {
9801
+ getReplicaSets(replicaSets) {
9802
+ return replicaSets.filter((rs) => {
9805
9803
  var _a, _b, _c;
9806
9804
  const ownerRef = (_b = (_a = rs.metadata) == null ? void 0 : _a.ownerReferences) == null ? void 0 : _b.find(
9807
9805
  (ref) => ref.kind === "Deployment" && ref.apiVersion === "apps/v1" && ref.name === this.name && ref.uid === this.metadata.uid
9808
9806
  );
9809
9807
  return !!ownerRef && ((_c = rs.metadata) == null ? void 0 : _c.namespace) === this.metadata.namespace;
9810
9808
  });
9811
- this.replicaSets = myReplicaSets;
9812
9809
  }
9813
9810
  get stateDisplay() {
9814
9811
  var _a, _b, _c;
@@ -9823,8 +9820,9 @@ class DeploymentModel extends WorkloadModel {
9823
9820
  var _a, _b;
9824
9821
  return (_b = (_a = this.metadata) == null ? void 0 : _a.annotations) == null ? void 0 : _b["deployment.kubernetes.io/revision"];
9825
9822
  }
9826
- get currentReplicaSet() {
9827
- return this.replicaSets.find((rs) => rs.revision === this.revision);
9823
+ getCurrentReplicaSet(replicaSets) {
9824
+ const myReplicaSets = this.getReplicaSets(replicaSets);
9825
+ return myReplicaSets.find((rs) => rs.revision === this.revision);
9828
9826
  }
9829
9827
  }
9830
9828
  class DaemonSetModel extends WorkloadModel {
@@ -9832,6 +9830,22 @@ class DaemonSetModel extends WorkloadModel {
9832
9830
  super(_rawYaml, _globalStore);
9833
9831
  this._rawYaml = _rawYaml;
9834
9832
  }
9833
+ getControllerRevisions(controllerVisions) {
9834
+ return controllerVisions.filter(
9835
+ (controllerRevision) => {
9836
+ var _a, _b;
9837
+ return (_b = (_a = controllerRevision.metadata) == null ? void 0 : _a.ownerReferences) == null ? void 0 : _b.some(
9838
+ (ownerReference) => ownerReference.kind === "DaemonSet" && ownerReference.uid === this.metadata.uid
9839
+ );
9840
+ }
9841
+ );
9842
+ }
9843
+ getRevision(controllerVisions) {
9844
+ const myControllerVisions = this.getControllerRevisions(controllerVisions);
9845
+ return myControllerVisions.reduce((result, controllerRevision) => {
9846
+ return Math.max(result, Number(controllerRevision.revision || 0));
9847
+ }, 0);
9848
+ }
9835
9849
  get stateDisplay() {
9836
9850
  var _a, _b;
9837
9851
  if (((_a = this.status) == null ? void 0 : _a.desiredNumberScheduled) !== ((_b = this.status) == null ? void 0 : _b.numberReady)) {
@@ -9851,6 +9865,22 @@ class StatefulSetModel extends WorkloadModel {
9851
9865
  super(_rawYaml, _globalStore);
9852
9866
  this._rawYaml = _rawYaml;
9853
9867
  }
9868
+ getControllerRevisions(controllerVisions) {
9869
+ return controllerVisions.filter(
9870
+ (controllerRevision) => {
9871
+ var _a, _b;
9872
+ return (_b = (_a = controllerRevision.metadata) == null ? void 0 : _a.ownerReferences) == null ? void 0 : _b.some(
9873
+ (ownerReference) => ownerReference.kind === "DaemonSet" && ownerReference.uid === this.metadata.uid
9874
+ );
9875
+ }
9876
+ );
9877
+ }
9878
+ getRevision(controllerVisions) {
9879
+ const myControllerVisions = this.getControllerRevisions(controllerVisions);
9880
+ return myControllerVisions.reduce((result, controllerRevision) => {
9881
+ return Math.max(result, Number(controllerRevision.revision || 0));
9882
+ }, 0);
9883
+ }
9854
9884
  get stateDisplay() {
9855
9885
  var _a, _b, _c;
9856
9886
  if (((_a = this.spec) == null ? void 0 : _a.replicas) === 0) {
@@ -10053,6 +10083,29 @@ class PersistentVolumeClaimModel extends ResourceModel {
10053
10083
  return set(yaml2, "spec.resources.requests.storage", `${distributeStorage}Gi`);
10054
10084
  }
10055
10085
  }
10086
+ class ControllerRevisionModel extends ResourceModel {
10087
+ constructor(_rawYaml, _globalStore) {
10088
+ super(_rawYaml, _globalStore);
10089
+ this._rawYaml = _rawYaml;
10090
+ }
10091
+ get revision() {
10092
+ return this._rawYaml.revision;
10093
+ }
10094
+ }
10095
+ class IngressClassModel extends ResourceModel {
10096
+ constructor(_rawYaml, _globalStore) {
10097
+ super(_rawYaml, _globalStore);
10098
+ this._rawYaml = _rawYaml;
10099
+ }
10100
+ get isDefault() {
10101
+ var _a, _b;
10102
+ return ((_b = (_a = this._rawYaml.metadata) == null ? void 0 : _a.annotations) == null ? void 0 : _b["ingressclass.kubernetes.io/is-default-class"]) === "true";
10103
+ }
10104
+ get controller() {
10105
+ var _a;
10106
+ return (_a = this.spec) == null ? void 0 : _a.controller;
10107
+ }
10108
+ }
10056
10109
  const index_1r58r8x = "";
10057
10110
  const ServiceInClusterAccessComponent = ({
10058
10111
  service
@@ -10640,6 +10693,9 @@ function validateLabelKey(key2) {
10640
10693
  if (prefix2 && prefix2.length > 253) {
10641
10694
  return { isValid: false };
10642
10695
  }
10696
+ if (!labelRegex.test(name2)) {
10697
+ return { isValid: false };
10698
+ }
10643
10699
  if (name2 && name2.length > 63) {
10644
10700
  return { isValid: false };
10645
10701
  }
@@ -10958,7 +11014,6 @@ const TableToolBar = ({
10958
11014
  selectedKeys,
10959
11015
  hideCreate
10960
11016
  }) => {
10961
- var _a;
10962
11017
  const {
10963
11018
  resource
10964
11019
  } = useResource();
@@ -10968,7 +11023,7 @@ const TableToolBar = ({
10968
11023
  className: ToolbarStyle$1,
10969
11024
  children: [/* @__PURE__ */ jsxRuntimeExports.jsx("span", {
10970
11025
  className: cx_default(Typo.Display.d2_regular_title, TitleStyle$2),
10971
- children: title || ((_a = resource == null ? void 0 : resource.meta) == null ? void 0 : _a.kind)
11026
+ children: title
10972
11027
  }), /* @__PURE__ */ jsxRuntimeExports.jsxs(Space, {
10973
11028
  children: [selectedKeys.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx(DeleteManyButton, {
10974
11029
  ids: selectedKeys
@@ -12052,9 +12107,18 @@ function Table(props) {
12052
12107
  const { tableProps, displayName, errorContentProps } = props;
12053
12108
  const { Table: TableComponent } = useContext(ComponentContext);
12054
12109
  const Table2 = TableComponent || Table$1;
12110
+ const { params } = useParsed();
12055
12111
  const { i18n: i18n2 } = useTranslation();
12056
12112
  const resourceType = transformResourceKindInSentence(displayName, i18n2.language);
12057
12113
  if (!((_a = tableProps.data) == null ? void 0 : _a.length) && !tableProps.loading) {
12114
+ const nameKeyword = (params == null ? void 0 : params[NAME_KEYWORD_PARAM]) || "";
12115
+ if (nameKeyword) {
12116
+ const onClear = () => {
12117
+ var _a2;
12118
+ (_a2 = tableProps.onClearSearchKeyword) == null ? void 0 : _a2.call(tableProps);
12119
+ };
12120
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(WidgetErrorContent, { errorText: i18n2.t("dovetail.no_search_result"), children: /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { onClick: onClear, type: "ordinary", children: i18n2.t("dovetail.clear_search_condition") }) });
12121
+ }
12058
12122
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
12059
12123
  WidgetErrorContent,
12060
12124
  {
@@ -14408,30 +14472,6 @@ const NamespacesFilter = ({
14408
14472
  })
14409
14473
  });
14410
14474
  };
14411
- function useNamespaceRefineFilter() {
14412
- const { value: nsFilters = [] } = useNamespacesFilter();
14413
- const filters = useMemo(() => {
14414
- const filters2 = nsFilters.filter((filter) => filter !== ALL_NS);
14415
- if (filters2.length === 0) {
14416
- return {
14417
- permanent: []
14418
- };
14419
- }
14420
- return {
14421
- permanent: [
14422
- {
14423
- operator: "or",
14424
- value: filters2.map((filter) => ({
14425
- field: "metadata.namespace",
14426
- operator: "eq",
14427
- value: filter
14428
- }))
14429
- }
14430
- ]
14431
- };
14432
- }, [nsFilters]);
14433
- return filters;
14434
- }
14435
14475
  const index_1l2xllo = "";
14436
14476
  const ListPageStyle = "laykzsq";
14437
14477
  const ListContentStyle = "l1ng0psc";
@@ -14454,7 +14494,7 @@ function ListPage(props) {
14454
14494
  children: [!config.hideListToolBar ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
14455
14495
  children: [/* @__PURE__ */ jsxRuntimeExports.jsx(TableToolBar, {
14456
14496
  selectedKeys,
14457
- title: config == null ? void 0 : config.displayName,
14497
+ title: (config == null ? void 0 : config.customListTitle) || (config == null ? void 0 : config.displayName) || config.kind,
14458
14498
  description: config == null ? void 0 : config.description,
14459
14499
  hideCreate: config == null ? void 0 : config.hideCreate
14460
14500
  }), belowToolBarContent, /* @__PURE__ */ jsxRuntimeExports.jsx(Divider, {
@@ -14491,7 +14531,7 @@ function ResourceList(props) {
14491
14531
  const { formatter, columns, Dropdown: Dropdown2, noShow } = props.config;
14492
14532
  const { i18n: i18n2 } = useTranslation();
14493
14533
  const nameRenderer = noShow ? PlainTextNameColumnRenderer(i18n2) : NameColumnRenderer(i18n2);
14494
- const filters = useNamespaceRefineFilter();
14534
+ const filters = useRefineFilters();
14495
14535
  const { tableProps, selectedKeys } = useEagleTable({
14496
14536
  useTableParams: {
14497
14537
  filters
@@ -18968,7 +19008,7 @@ const AgeColumnRenderer = (i18n2, config, {
18968
19008
  dataIndex,
18969
19009
  title: i18n2.t("dovetail.created_time"),
18970
19010
  width: 120,
18971
- sorter: true,
19011
+ sorter: CommonSorter(dataIndex),
18972
19012
  render: (value2) => {
18973
19013
  return isRelativeTime ? /* @__PURE__ */ jsxRuntimeExports.jsx(Time, {
18974
19014
  date: new Date(value2)
@@ -19518,6 +19558,78 @@ const SCAllowExpandColumnRenderer = (i18n2) => {
19518
19558
  }
19519
19559
  };
19520
19560
  };
19561
+ function useNamespaceRefineFilter() {
19562
+ const { value: nsFilters = [] } = useNamespacesFilter();
19563
+ const filters = useMemo(() => {
19564
+ const filters2 = nsFilters.filter((filter) => filter !== ALL_NS);
19565
+ if (filters2.length === 0) {
19566
+ return {
19567
+ permanent: []
19568
+ };
19569
+ }
19570
+ return {
19571
+ permanent: [
19572
+ {
19573
+ operator: "or",
19574
+ value: filters2.map((filter) => ({
19575
+ field: "metadata.namespace",
19576
+ operator: "eq",
19577
+ value: filter
19578
+ }))
19579
+ }
19580
+ ]
19581
+ };
19582
+ }, [nsFilters]);
19583
+ return filters;
19584
+ }
19585
+ const NAME_KEYWORD_PARAM = "name_keyword";
19586
+ function useRefineFilters(options = {}) {
19587
+ const {
19588
+ disableNamespaceFilter = false,
19589
+ disableNameKeywordFilter = false
19590
+ } = options;
19591
+ const { value: nsFilters = [] } = useNamespacesFilter();
19592
+ const namespaceFilters = useMemo(() => {
19593
+ if (disableNamespaceFilter) {
19594
+ return [];
19595
+ }
19596
+ const filters2 = nsFilters.filter((filter) => filter !== ALL_NS);
19597
+ if (filters2.length === 0) {
19598
+ return [];
19599
+ }
19600
+ return [
19601
+ {
19602
+ operator: "or",
19603
+ value: filters2.map((filter) => ({
19604
+ field: "metadata.namespace",
19605
+ operator: "eq",
19606
+ value: filter
19607
+ }))
19608
+ }
19609
+ ];
19610
+ }, [nsFilters, disableNamespaceFilter]);
19611
+ const { params } = useParsed();
19612
+ const nameKeyword = params == null ? void 0 : params[NAME_KEYWORD_PARAM];
19613
+ const nameKeywordFilters = useMemo(() => {
19614
+ if (disableNameKeywordFilter || !nameKeyword || nameKeyword.trim() === "") {
19615
+ return [];
19616
+ }
19617
+ return [
19618
+ {
19619
+ field: "metadata.name",
19620
+ operator: "contains",
19621
+ value: nameKeyword.trim()
19622
+ }
19623
+ ];
19624
+ }, [nameKeyword, disableNameKeywordFilter]);
19625
+ const filters = useMemo(
19626
+ () => ({
19627
+ permanent: [...namespaceFilters, ...nameKeywordFilters]
19628
+ }),
19629
+ [namespaceFilters, nameKeywordFilters]
19630
+ );
19631
+ return filters;
19632
+ }
19521
19633
  const styles = "";
19522
19634
  const Dovetail = (props) => {
19523
19635
  const {
@@ -19629,7 +19741,9 @@ class ModelPlugin {
19629
19741
  StorageClass: StorageClassModel,
19630
19742
  PersistentVolume: PersistentVolumeModel,
19631
19743
  PersistentVolumeClaim: PersistentVolumeClaimModel,
19632
- ReplicaSet: ReplicaSetModel
19744
+ ReplicaSet: ReplicaSetModel,
19745
+ ControllerRevision: ControllerRevisionModel,
19746
+ IngressClass: IngressClassModel
19633
19747
  })
19634
19748
  ));
19635
19749
  }
@@ -19777,6 +19891,7 @@ export {
19777
19891
  ConditionsTab,
19778
19892
  ConditionsTable,
19779
19893
  ConfigsContext,
19894
+ ControllerRevisionModel,
19780
19895
  CreateButton,
19781
19896
  CronJobDropdown,
19782
19897
  CronJobModel,
@@ -19820,6 +19935,7 @@ export {
19820
19935
  ImageField,
19821
19936
  ImageNames,
19822
19937
  IngressClassColumnRenderer,
19938
+ IngressClassModel,
19823
19939
  IngressDefaultBackendColumnRenderer,
19824
19940
  IngressModel,
19825
19941
  IngressRulesColumnRenderer,
@@ -19850,6 +19966,7 @@ export {
19850
19966
  ModelPlugin,
19851
19967
  MonacoYamlDiffEditor,
19852
19968
  MonacoYamlEditor,
19969
+ NAME_KEYWORD_PARAM,
19853
19970
  NETWORK_POLICY_INIT_VALUE,
19854
19971
  NODE_INIT_VALUE,
19855
19972
  NS_STORE_KEY,
@@ -20017,6 +20134,7 @@ export {
20017
20134
  generateValueFromSchema,
20018
20135
  getApiVersion,
20019
20136
  getResourceNameByKind,
20137
+ isFirstLetterEnglish,
20020
20138
  matchSelector,
20021
20139
  modelPlugin,
20022
20140
  namespaceRules,
@@ -20027,6 +20145,8 @@ export {
20027
20145
  rfc1035LabelRules,
20028
20146
  rfc1123LabelRules,
20029
20147
  routerProvider,
20148
+ shortenedImage,
20149
+ transformResourceKindInSentence,
20030
20150
  useApiGroupSchema,
20031
20151
  useDeleteModal,
20032
20152
  useDeleteModalOnly,
@@ -20038,6 +20158,7 @@ export {
20038
20158
  useNamespaceRefineFilter,
20039
20159
  useNamespacesFilter,
20040
20160
  useOpenForm,
20161
+ useRefineFilters,
20041
20162
  useRefineForm,
20042
20163
  useSchema,
20043
20164
  validateDataKey,
@@ -174,6 +174,8 @@ export type ResourceConfig<Model extends ResourceModel = ResourceModel> = {
174
174
  hideCreate?: boolean;
175
175
  /** 资源的描述信息 */
176
176
  description?: React.ReactNode;
177
+ /** 自定义资源列表标题 */
178
+ customListTitle?: string;
177
179
  /** 父级资源名称,用于建立资源层级关系。在 Dovetail2 中用不到这个 */
178
180
  parent?: string;
179
181
  /** 格式化数据参数,目前暂未完全实现,可能会删除 */
@@ -3,3 +3,4 @@ export * from './k8s';
3
3
  export * from './match-selector';
4
4
  export * from './getResourceNameByKind';
5
5
  export * from './validation';
6
+ export * from './string';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dovetail-v2/refine",
3
- "version": "0.3.13-alpha.0",
3
+ "version": "0.3.14-alpha.0",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",