@oneuptime/common 10.2.18 → 10.2.21

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.
Files changed (118) hide show
  1. package/Models/DatabaseModels/Index.ts +4 -0
  2. package/Models/DatabaseModels/ScheduledMaintenanceFeed.ts +2 -0
  3. package/Models/DatabaseModels/ScheduledMaintenanceLabelRule.ts +742 -0
  4. package/Models/DatabaseModels/ScheduledMaintenanceOwnerRule.ts +828 -0
  5. package/Server/Infrastructure/Postgres/SchemaMigrations/1778703414082-AddScheduledMaintenanceRules.ts +375 -0
  6. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +2 -0
  7. package/Server/Services/ScheduledMaintenanceLabelRuleEngineService.ts +463 -0
  8. package/Server/Services/ScheduledMaintenanceLabelRuleService.ts +14 -0
  9. package/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.ts +545 -0
  10. package/Server/Services/ScheduledMaintenanceOwnerRuleService.ts +14 -0
  11. package/Server/Services/ScheduledMaintenanceService.ts +34 -0
  12. package/Types/Call/CallRequest.ts +29 -5
  13. package/Types/Docs/DocsLanguage.ts +36 -0
  14. package/Types/Permission.ts +96 -0
  15. package/UI/Components/AlertBanner/AlertBanner.tsx +4 -1
  16. package/UI/Components/Alerts/Alert.tsx +15 -4
  17. package/UI/Components/Button/DropdownButton.tsx +4 -2
  18. package/UI/Components/Detail/Detail.tsx +5 -1
  19. package/UI/Components/Detail/FieldLabel.tsx +14 -6
  20. package/UI/Components/Detail/PlaceholderText.tsx +4 -1
  21. package/UI/Components/Dropdown/Dropdown.tsx +13 -4
  22. package/UI/Components/ErrorMessage/ErrorMessage.tsx +9 -2
  23. package/UI/Components/Filters/FilterViewer.tsx +42 -31
  24. package/UI/Components/Filters/FiltersForm.tsx +13 -6
  25. package/UI/Components/Forms/BasicForm.tsx +23 -6
  26. package/UI/Components/Forms/Fields/FieldLabel.tsx +18 -6
  27. package/UI/Components/ModelTable/BaseModelTable.tsx +16 -13
  28. package/UI/Components/MoreMenu/MoreMenuSection.tsx +4 -1
  29. package/UI/Components/Navbar/NavBarItem.tsx +4 -1
  30. package/UI/Components/Navbar/NavBarMenuItem.tsx +7 -2
  31. package/UI/Components/Navbar/NavBarMenuSubItem.tsx +4 -1
  32. package/UI/Components/ProgressButtons/ProgressButtonItem.tsx +4 -1
  33. package/UI/Components/Table/Table.tsx +13 -7
  34. package/UI/Components/Table/TableHeader.tsx +3 -1
  35. package/UI/Components/Tabs/Tab.tsx +5 -1
  36. package/UI/Components/TopAlert/TopAlert.tsx +8 -2
  37. package/UI/Components/Workflow/ArgumentsForm.tsx +55 -12
  38. package/UI/Components/Workflow/ComponentSettingsModal.tsx +143 -255
  39. package/UI/Components/Workflow/ModelFieldPicker.tsx +1234 -0
  40. package/build/dist/Models/DatabaseModels/Index.js +4 -0
  41. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  42. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceFeed.js +2 -0
  43. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceFeed.js.map +1 -1
  44. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceLabelRule.js +749 -0
  45. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceLabelRule.js.map +1 -0
  46. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceOwnerRule.js +834 -0
  47. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceOwnerRule.js.map +1 -0
  48. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1778703414082-AddScheduledMaintenanceRules.js +132 -0
  49. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1778703414082-AddScheduledMaintenanceRules.js.map +1 -0
  50. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +2 -0
  51. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  52. package/build/dist/Server/Services/ScheduledMaintenanceLabelRuleEngineService.js +375 -0
  53. package/build/dist/Server/Services/ScheduledMaintenanceLabelRuleEngineService.js.map +1 -0
  54. package/build/dist/Server/Services/ScheduledMaintenanceLabelRuleService.js +13 -0
  55. package/build/dist/Server/Services/ScheduledMaintenanceLabelRuleService.js.map +1 -0
  56. package/build/dist/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.js +431 -0
  57. package/build/dist/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.js.map +1 -0
  58. package/build/dist/Server/Services/ScheduledMaintenanceOwnerRuleService.js +13 -0
  59. package/build/dist/Server/Services/ScheduledMaintenanceOwnerRuleService.js.map +1 -0
  60. package/build/dist/Server/Services/ScheduledMaintenanceService.js +28 -0
  61. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  62. package/build/dist/Types/Call/CallRequest.js +28 -5
  63. package/build/dist/Types/Call/CallRequest.js.map +1 -1
  64. package/build/dist/Types/Docs/DocsLanguage.js +25 -0
  65. package/build/dist/Types/Docs/DocsLanguage.js.map +1 -0
  66. package/build/dist/Types/Permission.js +84 -0
  67. package/build/dist/Types/Permission.js.map +1 -1
  68. package/build/dist/UI/Components/AlertBanner/AlertBanner.js +5 -1
  69. package/build/dist/UI/Components/AlertBanner/AlertBanner.js.map +1 -1
  70. package/build/dist/UI/Components/Alerts/Alert.js +9 -4
  71. package/build/dist/UI/Components/Alerts/Alert.js.map +1 -1
  72. package/build/dist/UI/Components/Button/DropdownButton.js +6 -2
  73. package/build/dist/UI/Components/Button/DropdownButton.js.map +1 -1
  74. package/build/dist/UI/Components/Detail/Detail.js +4 -1
  75. package/build/dist/UI/Components/Detail/Detail.js.map +1 -1
  76. package/build/dist/UI/Components/Detail/FieldLabel.js +11 -6
  77. package/build/dist/UI/Components/Detail/FieldLabel.js.map +1 -1
  78. package/build/dist/UI/Components/Detail/PlaceholderText.js +5 -1
  79. package/build/dist/UI/Components/Detail/PlaceholderText.js.map +1 -1
  80. package/build/dist/UI/Components/Dropdown/Dropdown.js +11 -4
  81. package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
  82. package/build/dist/UI/Components/ErrorMessage/ErrorMessage.js +8 -2
  83. package/build/dist/UI/Components/ErrorMessage/ErrorMessage.js.map +1 -1
  84. package/build/dist/UI/Components/Filters/FilterViewer.js +49 -32
  85. package/build/dist/UI/Components/Filters/FilterViewer.js.map +1 -1
  86. package/build/dist/UI/Components/Filters/FiltersForm.js +9 -3
  87. package/build/dist/UI/Components/Filters/FiltersForm.js.map +1 -1
  88. package/build/dist/UI/Components/Forms/BasicForm.js +16 -6
  89. package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
  90. package/build/dist/UI/Components/Forms/Fields/FieldLabel.js +13 -6
  91. package/build/dist/UI/Components/Forms/Fields/FieldLabel.js.map +1 -1
  92. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +15 -10
  93. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  94. package/build/dist/UI/Components/MoreMenu/MoreMenuSection.js +5 -1
  95. package/build/dist/UI/Components/MoreMenu/MoreMenuSection.js.map +1 -1
  96. package/build/dist/UI/Components/Navbar/NavBarItem.js +5 -1
  97. package/build/dist/UI/Components/Navbar/NavBarItem.js.map +1 -1
  98. package/build/dist/UI/Components/Navbar/NavBarMenuItem.js +7 -2
  99. package/build/dist/UI/Components/Navbar/NavBarMenuItem.js.map +1 -1
  100. package/build/dist/UI/Components/Navbar/NavBarMenuSubItem.js +5 -1
  101. package/build/dist/UI/Components/Navbar/NavBarMenuSubItem.js.map +1 -1
  102. package/build/dist/UI/Components/ProgressButtons/ProgressButtonItem.js +5 -1
  103. package/build/dist/UI/Components/ProgressButtons/ProgressButtonItem.js.map +1 -1
  104. package/build/dist/UI/Components/Table/Table.js +12 -7
  105. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  106. package/build/dist/UI/Components/Table/TableHeader.js +4 -2
  107. package/build/dist/UI/Components/Table/TableHeader.js.map +1 -1
  108. package/build/dist/UI/Components/Tabs/Tab.js +5 -1
  109. package/build/dist/UI/Components/Tabs/Tab.js.map +1 -1
  110. package/build/dist/UI/Components/TopAlert/TopAlert.js +7 -2
  111. package/build/dist/UI/Components/TopAlert/TopAlert.js.map +1 -1
  112. package/build/dist/UI/Components/Workflow/ArgumentsForm.js +32 -10
  113. package/build/dist/UI/Components/Workflow/ArgumentsForm.js.map +1 -1
  114. package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js +57 -145
  115. package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js.map +1 -1
  116. package/build/dist/UI/Components/Workflow/ModelFieldPicker.js +694 -0
  117. package/build/dist/UI/Components/Workflow/ModelFieldPicker.js.map +1 -0
  118. package/package.json +1 -1
@@ -1,5 +1,6 @@
1
1
  import API from "../../Utils/API/API";
2
2
  import UiAnalytics from "../../Utils/Analytics";
3
+ import useTranslateValue from "../../Utils/Translation";
3
4
  import Alert, { AlertType } from "../Alerts/Alert";
4
5
  import Button, { ButtonStyleType } from "../Button/Button";
5
6
  import ButtonTypes from "../Button/ButtonTypes";
@@ -104,6 +105,7 @@ const BasicForm: ForwardRefExoticComponent<any> = forwardRef(
104
105
  props: ComponentProps<T>,
105
106
  ref: Ref<any>,
106
107
  ): ReactElement => {
108
+ const { translateString } = useTranslateValue();
107
109
  const isSubmitting: MutableRefObject<boolean> = useRef(false);
108
110
 
109
111
  const [didSomethingChange, setDidSomethingChange] =
@@ -164,9 +166,11 @@ const BasicForm: ForwardRefExoticComponent<any> = forwardRef(
164
166
  ((formSteps as Array<FormStep<T>>)[formSteps.length - 1] as FormStep<T>)
165
167
  .id === currentFormStepId;
166
168
 
167
- const submitButtonText: string = isOnLastFormStep
169
+ const submitButtonTextRaw: string = isOnLastFormStep
168
170
  ? props.submitButtonText || "Submit"
169
171
  : "Next";
172
+ const submitButtonText: string =
173
+ translateString(submitButtonTextRaw) ?? submitButtonTextRaw;
170
174
 
171
175
  useEffect(() => {
172
176
  if (props.values) {
@@ -597,12 +601,16 @@ const BasicForm: ForwardRefExoticComponent<any> = forwardRef(
597
601
  <div className="col-lg-1">
598
602
  <div>
599
603
  {props.title && (
600
- <h1 className="text-lg text-gray-700 mt-5">{props.title}</h1>
604
+ <h1 className="text-lg text-gray-700 mt-5">
605
+ {translateString(props.title) ?? props.title}
606
+ </h1>
601
607
  )}
602
608
 
603
609
  {Boolean(props.description) && (
604
610
  <div className="text-sm text-gray-500 mb-5">
605
- {props.description}
611
+ {typeof props.description === "string"
612
+ ? translateString(props.description) ?? props.description
613
+ : props.description}
606
614
  </div>
607
615
  )}
608
616
 
@@ -679,11 +687,17 @@ const BasicForm: ForwardRefExoticComponent<any> = forwardRef(
679
687
  className={`${fullRowSpan} mt-4 pt-5 first:mt-0 first:pt-0 border-t first:border-t-0 border-gray-200`}
680
688
  >
681
689
  <h3 className="text-base font-semibold text-gray-900">
682
- {field.sectionTitle}
690
+ {translateString(field.sectionTitle) ??
691
+ field.sectionTitle}
683
692
  </h3>
684
693
  {field.sectionDescription && (
685
694
  <p className="mt-1 text-sm text-gray-500">
686
- {field.sectionDescription}
695
+ {typeof field.sectionDescription ===
696
+ "string"
697
+ ? translateString(
698
+ field.sectionDescription,
699
+ ) ?? field.sectionDescription
700
+ : field.sectionDescription}
687
701
  </p>
688
702
  )}
689
703
  </div>
@@ -774,7 +788,10 @@ const BasicForm: ForwardRefExoticComponent<any> = forwardRef(
774
788
  {props.onCancel && (
775
789
  <div>
776
790
  <Button
777
- title={props.cancelButtonText || "Cancel"}
791
+ title={
792
+ translateString(props.cancelButtonText || "Cancel") ??
793
+ (props.cancelButtonText || "Cancel")
794
+ }
778
795
  type={ButtonTypes.Button}
779
796
  id={`${props.id}-cancel-button`}
780
797
  disabled={
@@ -1,5 +1,6 @@
1
1
  import Link from "../../Link/Link";
2
2
  import { FormFieldSideLink } from "../Types/Field";
3
+ import useTranslateValue from "../../../Utils/Translation";
3
4
  import React, { FunctionComponent, ReactElement } from "react";
4
5
 
5
6
  export interface ComponentProps {
@@ -15,6 +16,13 @@ export interface ComponentProps {
15
16
  const FieldLabelElement: FunctionComponent<ComponentProps> = (
16
17
  props: ComponentProps,
17
18
  ): ReactElement => {
19
+ const { translateString, translateValue } = useTranslateValue();
20
+ const translatedTitle: string = translateString(props.title) ?? props.title;
21
+ const translatedSideLinkText: string | undefined = translateString(
22
+ props.sideLink?.text,
23
+ );
24
+ const translatedDescription: string | ReactElement | undefined =
25
+ translateValue(props.description);
18
26
  return (
19
27
  <>
20
28
  <label
@@ -26,26 +34,30 @@ const FieldLabelElement: FunctionComponent<ComponentProps> = (
26
34
  }
27
35
  >
28
36
  <span>
29
- {props.title}{" "}
37
+ {translatedTitle}{" "}
30
38
  <span className="text-gray-400 text-xs">
31
- {props.required || props.hideOptionalLabel ? "" : "(Optional)"}
39
+ {props.required || props.hideOptionalLabel
40
+ ? ""
41
+ : translateString("(Optional)") ?? "(Optional)"}
32
42
  </span>
33
43
  </span>
34
- {props.sideLink && props.sideLink?.text && props.sideLink?.url && (
44
+ {props.sideLink && translatedSideLinkText && props.sideLink?.url && (
35
45
  <span data-testid="login-forgot-password">
36
46
  <Link
37
47
  to={props.sideLink?.url}
38
48
  openInNewTab={props.sideLink?.openLinkInNewTab}
39
49
  className="text-indigo-500 hover:text-indigo-900 cursor-pointer"
40
50
  >
41
- {props.sideLink?.text}
51
+ {translatedSideLinkText}
42
52
  </Link>
43
53
  </span>
44
54
  )}
45
55
  </label>
46
56
 
47
- {props.description && (
48
- <div className="mt-1 text-sm text-gray-500">{props.description}</div>
57
+ {translatedDescription && (
58
+ <div className="mt-1 text-sm text-gray-500">
59
+ {translatedDescription}
60
+ </div>
49
61
  )}
50
62
  </>
51
63
  );
@@ -281,7 +281,10 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
281
281
  ) => ReactElement = <TBaseModel extends BaseModel | AnalyticsBaseModel>(
282
282
  props: ComponentProps<TBaseModel>,
283
283
  ): ReactElement => {
284
- const { translateValue } = useTranslateValue();
284
+ const { translateValue, translateString } = useTranslateValue();
285
+ const tx: (value: string) => string = (value: string): string => {
286
+ return translateString(value) ?? value;
287
+ };
285
288
  const [tableView, setTableView] = useState<TableView | null>(null);
286
289
 
287
290
  const matchBulkSelectedItemByField: keyof TBaseModel =
@@ -803,7 +806,7 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
803
806
 
804
807
  if (showActionsColumn) {
805
808
  columns.push({
806
- title: "Actions",
809
+ title: tx("Actions"),
807
810
  type: FieldType.Actions,
808
811
  });
809
812
  }
@@ -1305,7 +1308,7 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
1305
1308
  // Add documentation link button first if provided
1306
1309
  if (props.documentationLink) {
1307
1310
  headerbuttons.push({
1308
- title: "View Documentation",
1311
+ title: tx("View Documentation"),
1309
1312
  icon: IconProp.Book,
1310
1313
  buttonStyle: ButtonStyleType.HOVER_PRIMARY_OUTLINE,
1311
1314
  buttonSize: ButtonSize.Small,
@@ -1335,7 +1338,7 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
1335
1338
  // Add video link button if provided
1336
1339
  if (props.videoLink) {
1337
1340
  headerbuttons.push({
1338
- title: "Watch Demo",
1341
+ title: tx("Watch Demo"),
1339
1342
  icon: IconProp.Play,
1340
1343
  buttonStyle: ButtonStyleType.HOVER_PRIMARY_OUTLINE,
1341
1344
  buttonSize: ButtonSize.Small,
@@ -1371,9 +1374,9 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
1371
1374
  showAs !== ShowAs.OrderedStatesList
1372
1375
  ) {
1373
1376
  headerbuttons.push({
1374
- title: `${props.createVerb || "Create"} ${
1375
- props.singularName || model.singularName
1376
- }`,
1377
+ title: `${tx(props.createVerb || "Create")} ${tx(
1378
+ props.singularName || model.singularName || "",
1379
+ )}`,
1377
1380
  buttonStyle: ButtonStyleType.NORMAL,
1378
1381
  buttonSize: ButtonSize.Normal,
1379
1382
  className: "",
@@ -1581,7 +1584,7 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
1581
1584
 
1582
1585
  if (props.showViewIdButton) {
1583
1586
  actionsSchema.push({
1584
- title: "Show ID",
1587
+ title: tx("Show ID"),
1585
1588
  buttonStyleType: ButtonStyleType.OUTLINE,
1586
1589
  hideOnMobile: true,
1587
1590
  onClick: async (
@@ -1613,9 +1616,9 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
1613
1616
  (model.hasReadPermissions(permissions) || User.isMasterAdmin())
1614
1617
  ) {
1615
1618
  actionsSchema.push({
1616
- title:
1617
- props.viewButtonText ||
1618
- `View ${props.singularName || model.singularName}`,
1619
+ title: props.viewButtonText
1620
+ ? tx(props.viewButtonText)
1621
+ : `${tx("View")} ${tx(props.singularName || model.singularName || "")}`,
1619
1622
  buttonStyleType: ButtonStyleType.NORMAL,
1620
1623
  onClick: async (
1621
1624
  item: TBaseModel,
@@ -1675,7 +1678,7 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
1675
1678
  (model.hasUpdatePermissions(permissions) || User.isMasterAdmin())
1676
1679
  ) {
1677
1680
  actionsSchema.push({
1678
- title: props.editButtonText || "Edit",
1681
+ title: tx(props.editButtonText || "Edit"),
1679
1682
  buttonStyleType: ButtonStyleType.OUTLINE,
1680
1683
  onClick: async (
1681
1684
  item: TBaseModel,
@@ -1704,7 +1707,7 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
1704
1707
  (model.hasDeletePermissions(permissions) || User.isMasterAdmin())
1705
1708
  ) {
1706
1709
  actionsSchema.push({
1707
- title: props.deleteButtonText || "Delete",
1710
+ title: tx(props.deleteButtonText || "Delete"),
1708
1711
  icon: IconProp.Trash,
1709
1712
  buttonStyleType: ButtonStyleType.DANGER_OUTLINE,
1710
1713
  onClick: async (
@@ -1,3 +1,4 @@
1
+ import useTranslateValue from "../../Utils/Translation";
1
2
  import React, { FunctionComponent, ReactElement } from "react";
2
3
  import MoreMenuDivider from "./Divider";
3
4
  export interface ComponentProps {
@@ -8,10 +9,12 @@ export interface ComponentProps {
8
9
  const MoreMenuSection: FunctionComponent<ComponentProps> = (
9
10
  props: ComponentProps,
10
11
  ): ReactElement => {
12
+ const { translateString } = useTranslateValue();
13
+ const translatedTitle: string = translateString(props.title) ?? props.title;
11
14
  return (
12
15
  <div>
13
16
  <div className="text-gray-400 text-xs font-medium pt-2 pl-3 pr-3 pb-2">
14
- {props.title.toUpperCase()}
17
+ {translatedTitle.toUpperCase()}
15
18
  </div>
16
19
  {props.children}
17
20
  <MoreMenuDivider />
@@ -1,5 +1,6 @@
1
1
  // Tailwind
2
2
  import Navigation from "../../Utils/Navigation";
3
+ import useTranslateValue from "../../Utils/Translation";
3
4
  import Icon, { ThickProp } from "../Icon/Icon";
4
5
  import Link from "../Link/Link";
5
6
  import Route from "../../../Types/API/Route";
@@ -23,6 +24,8 @@ export interface ComponentProps {
23
24
  const NavBarItem: FunctionComponent<ComponentProps> = (
24
25
  props: ComponentProps,
25
26
  ): ReactElement => {
27
+ const { translateString } = useTranslateValue();
28
+ const translatedTitle: string = translateString(props.title) ?? props.title;
26
29
  const activeRoute: Route | undefined = props.activeRoute || props.route;
27
30
  const isActive: boolean = Boolean(
28
31
  activeRoute &&
@@ -67,7 +70,7 @@ const NavBarItem: FunctionComponent<ComponentProps> = (
67
70
  ) : (
68
71
  <></>
69
72
  )}
70
- <span>{props.title}</span>
73
+ <span>{translatedTitle}</span>
71
74
  {props.children ? <div className="arrow-down"></div> : <></>}
72
75
  </Link>
73
76
  {props.children}
@@ -2,6 +2,7 @@ import Icon from "../Icon/Icon";
2
2
  import Link from "../Link/Link";
3
3
  import Route from "../../../Types/API/Route";
4
4
  import IconProp from "../../../Types/Icon/IconProp";
5
+ import useTranslateValue from "../../Utils/Translation";
5
6
  import React, { FunctionComponent, ReactElement } from "react";
6
7
 
7
8
  export interface ComponentProps {
@@ -16,6 +17,10 @@ export interface ComponentProps {
16
17
  const NavBarMenuItem: FunctionComponent<ComponentProps> = (
17
18
  props: ComponentProps,
18
19
  ): ReactElement => {
20
+ const { translateString } = useTranslateValue();
21
+ const translatedTitle: string = translateString(props.title) ?? props.title;
22
+ const translatedDescription: string =
23
+ translateString(props.description) ?? props.description;
19
24
  // Default to indigo if no color specified
20
25
  const colorName: string = props.iconColor || "indigo";
21
26
 
@@ -130,8 +135,8 @@ const NavBarMenuItem: FunctionComponent<ComponentProps> = (
130
135
  <Icon icon={props.icon} className="h-4 w-4 text-gray-600" />
131
136
  </div>
132
137
  <div className="flex-1 min-w-0 text-left">
133
- <p className="text-sm font-medium text-gray-900">{props.title}</p>
134
- <p className="text-xs text-gray-500">{props.description}</p>
138
+ <p className="text-sm font-medium text-gray-900">{translatedTitle}</p>
139
+ <p className="text-xs text-gray-500">{translatedDescription}</p>
135
140
  </div>
136
141
  </Link>
137
142
  </div>
@@ -1,5 +1,6 @@
1
1
  import Link from "../Link/Link";
2
2
  import Route from "../../../Types/API/Route";
3
+ import useTranslateValue from "../../Utils/Translation";
3
4
  import React, { FunctionComponent, ReactElement } from "react";
4
5
 
5
6
  export interface ComponentProps {
@@ -10,9 +11,11 @@ export interface ComponentProps {
10
11
  const NavBarMenuItem: FunctionComponent<ComponentProps> = (
11
12
  props: ComponentProps,
12
13
  ): ReactElement => {
14
+ const { translateString } = useTranslateValue();
15
+ const translatedTitle: string = translateString(props.title) ?? props.title;
13
16
  return (
14
17
  <Link className="dropdown-item" to={props.route}>
15
- {props.title}
18
+ {translatedTitle}
16
19
  </Link>
17
20
  );
18
21
  };
@@ -2,6 +2,7 @@ import React, { FunctionComponent, ReactElement } from "react";
2
2
  import Color from "../../../Types/Color";
3
3
  import Icon from "../Icon/Icon";
4
4
  import IconProp from "../../../Types/Icon/IconProp";
5
+ import useTranslateValue from "../../Utils/Translation";
5
6
 
6
7
  export interface ProgressItemProps {
7
8
  id: string;
@@ -20,6 +21,8 @@ export interface ComponentProps extends ProgressItemProps {
20
21
  const ProgressButtonItem: FunctionComponent<ComponentProps> = (
21
22
  props: ComponentProps,
22
23
  ): ReactElement => {
24
+ const { translateString } = useTranslateValue();
25
+ const translatedTitle: string = translateString(props.title) ?? props.title;
23
26
  return (
24
27
  <li
25
28
  className="relative md:flex md:flex-1 "
@@ -75,7 +78,7 @@ const ProgressButtonItem: FunctionComponent<ComponentProps> = (
75
78
  className="ml-4 text-sm font-medium text-gray-900"
76
79
  style={{ color: props.color.toString() }}
77
80
  >
78
- {props.title}
81
+ {translatedTitle}
79
82
  </span>
80
83
  </span>
81
84
  </div>
@@ -1,4 +1,5 @@
1
1
  import { GetReactElementFunction } from "../../Types/FunctionTypes";
2
+ import useTranslateValue from "../../Utils/Translation";
2
3
  import ActionButtonSchema from "../ActionButton/ActionButtonSchema";
3
4
  import BulkUpdateForm, {
4
5
  BulkActionButtonSchema,
@@ -84,6 +85,11 @@ type TableFunction = <T extends GenericObject>(
84
85
  const Table: TableFunction = <T extends GenericObject>(
85
86
  props: ComponentProps<T>,
86
87
  ): ReactElement => {
88
+ const { translateString } = useTranslateValue();
89
+ const translatedSingularLabel: string =
90
+ translateString(props.singularLabel) ?? props.singularLabel;
91
+ const translatedPluralLabel: string =
92
+ translateString(props.pluralLabel) ?? props.pluralLabel;
87
93
  const isBulkActionsEnabled: boolean | undefined =
88
94
  props.bulkActions &&
89
95
  props.bulkActions.buttons &&
@@ -156,7 +162,7 @@ const Table: TableFunction = <T extends GenericObject>(
156
162
  message={
157
163
  props.noItemsMessage
158
164
  ? props.noItemsMessage
159
- : `No ${props.singularLabel.toLocaleLowerCase()}`
165
+ : `${translateString("No") ?? "No"} ${translatedSingularLabel.toLocaleLowerCase()}`
160
166
  }
161
167
  onRefreshClick={props.onRefreshClick}
162
168
  />
@@ -242,8 +248,8 @@ const Table: TableFunction = <T extends GenericObject>(
242
248
  filters={props.filters || []}
243
249
  onFilterModalClose={props.onFilterModalClose}
244
250
  onFilterModalOpen={props.onFilterModalOpen}
245
- singularLabel={props.singularLabel}
246
- pluralLabel={props.pluralLabel}
251
+ singularLabel={translatedSingularLabel}
252
+ pluralLabel={translatedPluralLabel}
247
253
  filterData={props.filterData}
248
254
  onAdvancedFiltersToggle={props.onAdvancedFiltersToggle}
249
255
  />
@@ -259,8 +265,8 @@ const Table: TableFunction = <T extends GenericObject>(
259
265
  setIsAllItemsSelected(true);
260
266
  }}
261
267
  selectedItems={bulkSelectedItems}
262
- singularLabel={props.singularLabel}
263
- pluralLabel={props.pluralLabel}
268
+ singularLabel={translatedSingularLabel}
269
+ pluralLabel={translatedPluralLabel}
264
270
  isAllItemsSelected={isAllItemsSelected}
265
271
  onActionStart={props.onBulkActionStart}
266
272
  onActionEnd={() => {
@@ -324,8 +330,8 @@ const Table: TableFunction = <T extends GenericObject>(
324
330
  <div className="bg-gray-50 text-right md:-mx-6 -mb-6 rounded-b-xl">
325
331
  {!props.disablePagination && (
326
332
  <Pagination
327
- singularLabel={props.singularLabel}
328
- pluralLabel={props.pluralLabel}
333
+ singularLabel={translatedSingularLabel}
334
+ pluralLabel={translatedPluralLabel}
329
335
  currentPageNumber={props.currentPageNumber}
330
336
  totalItemsCount={props.totalItemsCount}
331
337
  itemsOnPage={props.itemsOnPage}
@@ -8,6 +8,7 @@ import SortOrder, {
8
8
  } from "../../../Types/BaseDatabase/SortOrder";
9
9
  import GenericObject from "../../../Types/GenericObject";
10
10
  import IconProp from "../../../Types/Icon/IconProp";
11
+ import useTranslateValue from "../../Utils/Translation";
11
12
  import React, { ReactElement, useEffect, useState } from "react";
12
13
 
13
14
  export interface ComponentProps<T extends GenericObject> {
@@ -31,6 +32,7 @@ type TableHeaderFunction = <T extends GenericObject>(
31
32
  const TableHeader: TableHeaderFunction = <T extends GenericObject>(
32
33
  props: ComponentProps<T>,
33
34
  ): ReactElement => {
35
+ const { translateString } = useTranslateValue();
34
36
  // Track mobile view for responsive behavior
35
37
  const [isMobile, setIsMobile] = useState<boolean>(false);
36
38
 
@@ -128,7 +130,7 @@ const TableHeader: TableHeaderFunction = <T extends GenericObject>(
128
130
  : "justify-start"
129
131
  }`}
130
132
  >
131
- {column.title}
133
+ {translateString(column.title) ?? column.title}
132
134
  {canSort &&
133
135
  props.sortBy === column.key &&
134
136
  props.sortOrder === SortOrder.Ascending && (
@@ -1,3 +1,4 @@
1
+ import useTranslateValue from "../../Utils/Translation";
1
2
  import React, { FunctionComponent, ReactElement } from "react";
2
3
 
3
4
  export enum TabType {
@@ -24,6 +25,9 @@ export interface ComponentProps {
24
25
  const TabElement: FunctionComponent<ComponentProps> = (
25
26
  props: ComponentProps,
26
27
  ): ReactElement => {
28
+ const { translateString } = useTranslateValue();
29
+ const translatedName: string =
30
+ translateString(props.tab.name) ?? props.tab.name;
27
31
  const backgroundColor: string = "bg-gray-100";
28
32
 
29
33
  const baseClasses: string =
@@ -55,7 +59,7 @@ const TabElement: FunctionComponent<ComponentProps> = (
55
59
  aria-selected={props.isSelected}
56
60
  aria-controls={props.tabPanelId}
57
61
  >
58
- <div>{props.tab.name}</div>
62
+ <div>{translatedName}</div>
59
63
 
60
64
  {props.tab.countBadge && props.tab.countBadge > 0 ? (
61
65
  <span
@@ -1,3 +1,4 @@
1
+ import useTranslateValue from "../../Utils/Translation";
1
2
  import React, { FunctionComponent, ReactElement } from "react";
2
3
 
3
4
  export enum TopAlertType {
@@ -16,6 +17,11 @@ export interface ComponentProps {
16
17
  const TopAlert: FunctionComponent<ComponentProps> = (
17
18
  props: ComponentProps,
18
19
  ): ReactElement => {
20
+ const { translateString, translateValue } = useTranslateValue();
21
+ const translatedTitle: string = translateString(props.title) ?? props.title;
22
+ const translatedDescription: string | ReactElement =
23
+ (translateValue(props.description) as string | ReactElement | undefined) ??
24
+ props.description;
19
25
  const alertType: TopAlertType = props.alertType || TopAlertType.INFO;
20
26
 
21
27
  return (
@@ -26,9 +32,9 @@ const TopAlert: FunctionComponent<ComponentProps> = (
26
32
  >
27
33
  <div className="text-sm leading-6 text-white w-full">
28
34
  <div className="w-full">
29
- <strong className="font-semibold">{props.title}</strong>
35
+ <strong className="font-semibold">{translatedTitle}</strong>
30
36
  &nbsp;-&nbsp;
31
- {props.description} &nbsp;&nbsp;
37
+ {translatedDescription} &nbsp;&nbsp;
32
38
  {/** Uncomment the follwing line if you need a button on top alert */}
33
39
  {/* <a
34
40
  href="#"
@@ -1,8 +1,11 @@
1
1
  import ComponentLoader from "../ComponentLoader/ComponentLoader";
2
2
  import ErrorMessage from "../ErrorMessage/ErrorMessage";
3
3
  import BasicForm, { FormProps } from "../Forms/BasicForm";
4
+ import FormFieldSchemaType from "../Forms/Types/FormFieldSchemaType";
5
+ import { CustomElementProps } from "../Forms/Types/Field";
4
6
  import FormValues from "../Forms/Types/FormValues";
5
7
  import ComponentValuePickerModal from "./ComponentValuePickerModal";
8
+ import ModelFieldPicker from "./ModelFieldPicker";
6
9
  import { componentInputTypeToFormFieldType } from "./Utils";
7
10
  import VariableModal from "./VariableModal";
8
11
  import Dictionary from "../../../Types/Dictionary";
@@ -190,15 +193,51 @@ const ArgumentsForm: FunctionComponent<ComponentProps> = (
190
193
  const isWorkflowSelect: boolean =
191
194
  arg.type === ComponentInputType.WorkflowSelect;
192
195
 
196
+ /*
197
+ * Database Select args (the "Select Fields" / "Listen on"
198
+ * trigger inputs) get a tree-style field picker backed by
199
+ * the model's schema, instead of a raw JSON textarea. We
200
+ * need a tableName on the component metadata to fetch the
201
+ * column list; without it, fall back to the JSON editor.
202
+ */
203
+ const useFieldPicker: boolean =
204
+ arg.type === ComponentInputType.Select &&
205
+ Boolean(component.metadata.tableName);
206
+
193
207
  const baseField: {
194
208
  fieldType: import("../Forms/Types/FormFieldSchemaType").default;
195
209
  dropdownOptions?: Array<DropdownOption> | undefined;
196
- } = componentInputTypeToFormFieldType(
197
- arg.type,
198
- component.arguments && component.arguments[arg.id]
199
- ? component.arguments[arg.id]
200
- : null,
201
- );
210
+ getCustomElement?: (
211
+ values: FormValues<JSONObject>,
212
+ customProps: CustomElementProps,
213
+ ) => ReactElement | undefined;
214
+ } = useFieldPicker
215
+ ? {
216
+ fieldType: FormFieldSchemaType.CustomComponent,
217
+ getCustomElement: (
218
+ _values: FormValues<JSONObject>,
219
+ customProps: CustomElementProps,
220
+ ): ReactElement => {
221
+ return (
222
+ <ModelFieldPicker
223
+ tableName={component.metadata.tableName as string}
224
+ initialValue={customProps.initialValue}
225
+ onChange={(value: string) => {
226
+ void customProps.onChange?.(value);
227
+ }}
228
+ placeholder={customProps.placeholder}
229
+ error={customProps.error}
230
+ tabIndex={customProps.tabIndex}
231
+ />
232
+ );
233
+ },
234
+ }
235
+ : componentInputTypeToFormFieldType(
236
+ arg.type,
237
+ component.arguments && component.arguments[arg.id]
238
+ ? component.arguments[arg.id]
239
+ : null,
240
+ );
202
241
 
203
242
  /*
204
243
  * For WorkflowSelect, inject the dynamically fetched list
@@ -208,13 +247,17 @@ const ArgumentsForm: FunctionComponent<ComponentProps> = (
208
247
  baseField.dropdownOptions = workflowDropdownOptions;
209
248
  }
210
249
 
250
+ /*
251
+ * The "pick from component / variable" footer doesn't
252
+ * apply to the field picker (it edits a structured object,
253
+ * not a free-text expression) or to WorkflowSelect.
254
+ */
255
+ const showVariableFooter: boolean =
256
+ !isWorkflowSelect && !useFieldPicker;
257
+
211
258
  return {
212
259
  title: `${arg.name}`,
213
- /*
214
- * WorkflowSelect has no "pick from component/variable"
215
- * footer — it's a bound dropdown, not a free-text field.
216
- */
217
- footerElement: isWorkflowSelect ? undefined : (
260
+ footerElement: showVariableFooter ? (
218
261
  <div className="text-gray-500">
219
262
  <p className="text-sm">
220
263
  Pick this value from other{" "}
@@ -239,7 +282,7 @@ const ArgumentsForm: FunctionComponent<ComponentProps> = (
239
282
  </button>
240
283
  </p>
241
284
  </div>
242
- ),
285
+ ) : undefined,
243
286
  description: `${
244
287
  arg.required ? "Required" : "Optional"
245
288
  }. ${arg.description}`,