Context.tsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. import React, { Component } from "react";
  2. import {
  3. CapabilityType,
  4. ClusterType,
  5. ContextProps,
  6. ProjectType,
  7. } from "shared/types";
  8. import { pushQueryParams } from "shared/routing";
  9. const Context = React.createContext<Partial<ContextProps>>(null);
  10. const { Provider } = Context;
  11. const ContextConsumer = Context.Consumer;
  12. type PropsType = {
  13. history: any;
  14. location: any;
  15. };
  16. type StateType = GlobalContextType;
  17. export interface GlobalContextType {
  18. currentModal: string;
  19. currentModalData: any;
  20. setCurrentModal: (currentModal: string, currentModalData?: any) => void;
  21. currentOverlay: {
  22. message: string;
  23. onYes: any;
  24. onNo: any;
  25. };
  26. setCurrentOverlay: (x: any) => void;
  27. currentError: string | null;
  28. setCurrentError: (currentError: string) => void;
  29. currentCluster: ClusterType;
  30. setCurrentCluster: (currentCluster: ClusterType, callback?: any) => void;
  31. currentProject: ProjectType | null;
  32. setCurrentProject: (
  33. currentProject: ProjectType,
  34. callback?: () => void
  35. ) => void;
  36. projects: ProjectType[];
  37. setProjects: (projects: ProjectType[]) => void;
  38. user: any;
  39. setUser: (userId: number, email: string) => void;
  40. devOpsMode: boolean;
  41. setDevOpsMode: (devOpsMode: boolean) => void;
  42. capabilities: CapabilityType;
  43. setCapabilities: (capabilities: CapabilityType) => void;
  44. clearContext: () => void;
  45. }
  46. /**
  47. * Component managing a universal (application-wide) data store.
  48. *
  49. * Important Usage Notes:
  50. * 1) Each field must have an accompanying setter
  51. * 2) No function calls are allowed from within Context (not counting
  52. * initialization)
  53. * 3) Context should be used as a last-resort (changes will re-render ALL
  54. * components consuming Context)
  55. * 4) As a rule of thumb, Context should not be used for UI-related state
  56. */
  57. class ContextProvider extends Component<PropsType, StateType> {
  58. state: GlobalContextType = {
  59. currentModal: null,
  60. currentModalData: null,
  61. setCurrentModal: (currentModal: string, currentModalData?: any) => {
  62. this.setState({ currentModal, currentModalData });
  63. },
  64. currentOverlay: null,
  65. setCurrentOverlay: (x: any) => this.setState({ currentOverlay: x }),
  66. currentError: null,
  67. setCurrentError: (currentError: string) => {
  68. this.setState({ currentError });
  69. },
  70. currentCluster: {
  71. id: -1,
  72. name: "",
  73. server: "",
  74. service_account_id: -1,
  75. infra_id: -1,
  76. service: "",
  77. },
  78. setCurrentCluster: (currentCluster: ClusterType, callback?: any) => {
  79. localStorage.setItem(
  80. this.state.currentProject.id + "-cluster",
  81. JSON.stringify(currentCluster)
  82. );
  83. this.setState({ currentCluster }, () => {
  84. callback && callback();
  85. });
  86. },
  87. currentProject: null,
  88. setCurrentProject: (currentProject: ProjectType, callback?: any) => {
  89. if (currentProject) {
  90. localStorage.setItem("currentProject", currentProject.id.toString());
  91. pushQueryParams(this.props, {
  92. project_id: currentProject.id.toString(),
  93. });
  94. } else {
  95. localStorage.removeItem("currentProject");
  96. }
  97. this.setState({ currentProject }, () => {
  98. callback && callback();
  99. });
  100. },
  101. projects: [],
  102. setProjects: (projects: ProjectType[]) => {
  103. projects.sort((a: any, b: any) => (a.name > b.name ? 1 : -1));
  104. this.setState({ projects });
  105. },
  106. user: null,
  107. setUser: (userId: number, email: string) => {
  108. this.setState({ user: { userId, email } });
  109. },
  110. devOpsMode: true,
  111. setDevOpsMode: (devOpsMode: boolean) => {
  112. this.setState({ devOpsMode });
  113. },
  114. capabilities: null,
  115. setCapabilities: (capabilities: CapabilityType) => {
  116. this.setState({ capabilities });
  117. },
  118. clearContext: () => {
  119. this.setState({
  120. currentModal: null,
  121. currentModalData: null,
  122. currentError: null,
  123. currentCluster: null,
  124. currentProject: null,
  125. projects: [],
  126. user: null,
  127. devOpsMode: true,
  128. });
  129. },
  130. };
  131. render() {
  132. return <Provider value={this.state}>{this.props.children}</Provider>;
  133. }
  134. }
  135. export { Context, ContextProvider, ContextConsumer };