Scenes: Enforce explicit accessibility modifiers (ESLint) (#58331)

* Public test

* Update

* Update

* revert

* Added some public accessability modifiers

* Force public acessability only for scenes/* folder

* Fixes
pull/58116/head
Torkel Ödegaard 3 years ago committed by GitHub
parent eb3ee35e1c
commit 1fb37b54b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      .eslintrc
  2. 6
      public/app/features/scenes/components/NestedScene.tsx
  3. 8
      public/app/features/scenes/components/Scene.tsx
  4. 4
      public/app/features/scenes/components/SceneCanvasText.tsx
  5. 6
      public/app/features/scenes/components/SceneFlexLayout.tsx
  6. 8
      public/app/features/scenes/components/ScenePanelRepeater.tsx
  7. 2
      public/app/features/scenes/components/SceneTimePicker.tsx
  8. 4
      public/app/features/scenes/components/SceneToolbarButton.tsx
  9. 6
      public/app/features/scenes/components/VizPanel.tsx
  10. 51
      public/app/features/scenes/core/SceneObjectBase.tsx
  11. 10
      public/app/features/scenes/core/SceneTimeRange.tsx
  12. 9
      public/app/features/scenes/core/events.ts
  13. 10
      public/app/features/scenes/editor/SceneEditManager.tsx
  14. 8
      public/app/features/scenes/querying/SceneQueryRunner.ts
  15. 8
      public/app/features/scenes/services/UrlSyncManager.ts
  16. 2
      public/app/features/scenes/variables/SceneVariableSet.ts

@ -44,6 +44,12 @@
"@typescript-eslint/no-redeclare": ["error"] "@typescript-eslint/no-redeclare": ["error"]
}, },
"overrides": [ "overrides": [
{
"files": ["public/app/features/scenes/**/*.{ts,tsx}"],
"rules": {
"@typescript-eslint/explicit-member-accessibility": ["error", { "accessibility": "explicit" }]
}
},
{ {
"files": ["packages/grafana-ui/src/components/uPlot/**/*.{ts,tsx}"], "files": ["packages/grafana-ui/src/components/uPlot/**/*.{ts,tsx}"],
"rules": { "rules": {

@ -18,9 +18,9 @@ interface NestedSceneState extends SceneLayoutChildState {
} }
export class NestedScene extends SceneObjectBase<NestedSceneState> { export class NestedScene extends SceneObjectBase<NestedSceneState> {
static Component = NestedSceneRenderer; public static Component = NestedSceneRenderer;
onToggle = () => { public onToggle = () => {
this.setState({ this.setState({
isCollapsed: !this.state.isCollapsed, isCollapsed: !this.state.isCollapsed,
size: { size: {
@ -31,7 +31,7 @@ export class NestedScene extends SceneObjectBase<NestedSceneState> {
}; };
/** Removes itself from its parent's children array */ /** Removes itself from its parent's children array */
onRemove = () => { public onRemove = () => {
const parent = this.parent!; const parent = this.parent!;
if ('children' in parent.state) { if ('children' in parent.state) {
parent.setState({ parent.setState({

@ -18,15 +18,15 @@ interface SceneState extends SceneObjectStatePlain {
} }
export class Scene extends SceneObjectBase<SceneState> { export class Scene extends SceneObjectBase<SceneState> {
static Component = SceneRenderer; public static Component = SceneRenderer;
urlSyncManager?: UrlSyncManager; private urlSyncManager?: UrlSyncManager;
activate() { public activate() {
super.activate(); super.activate();
this.urlSyncManager = new UrlSyncManager(this); this.urlSyncManager = new UrlSyncManager(this);
} }
deactivate() { public deactivate() {
super.deactivate(); super.deactivate();
this.urlSyncManager!.cleanUp(); this.urlSyncManager!.cleanUp();
} }

@ -12,8 +12,8 @@ export interface SceneCanvasTextState extends SceneLayoutChildState {
} }
export class SceneCanvasText extends SceneObjectBase<SceneCanvasTextState> { export class SceneCanvasText extends SceneObjectBase<SceneCanvasTextState> {
static Editor = Editor; public static Editor = Editor;
static Component = ({ model }: SceneComponentProps<SceneCanvasText>) => { public static Component = ({ model }: SceneComponentProps<SceneCanvasText>) => {
const { text, fontSize = 20, align = 'left' } = model.useState(); const { text, fontSize = 20, align = 'left' } = model.useState();
const style: CSSProperties = { const style: CSSProperties = {

@ -12,10 +12,10 @@ interface SceneFlexLayoutState extends SceneLayoutState {
} }
export class SceneFlexLayout extends SceneObjectBase<SceneFlexLayoutState> { export class SceneFlexLayout extends SceneObjectBase<SceneFlexLayoutState> {
static Component = FlexLayoutRenderer; public static Component = FlexLayoutRenderer;
static Editor = FlexLayoutEditor; public static Editor = FlexLayoutEditor;
toggleDirection() { public toggleDirection() {
this.setState({ this.setState({
direction: this.state.direction === 'row' ? 'column' : 'row', direction: this.state.direction === 'row' ? 'column' : 'row',
}); });

@ -17,10 +17,10 @@ interface RepeatOptions extends SceneObjectStatePlain {
} }
export class ScenePanelRepeater extends SceneObjectBase<RepeatOptions> { export class ScenePanelRepeater extends SceneObjectBase<RepeatOptions> {
activate(): void { public activate(): void {
super.activate(); super.activate();
this.subs.add( this._subs.add(
this.getData().subscribeToState({ this.getData().subscribeToState({
next: (data) => { next: (data) => {
if (data.data?.state === LoadingState.Done) { if (data.data?.state === LoadingState.Done) {
@ -31,7 +31,7 @@ export class ScenePanelRepeater extends SceneObjectBase<RepeatOptions> {
); );
} }
performRepeat(data: PanelData) { private performRepeat(data: PanelData) {
// assume parent is a layout // assume parent is a layout
const firstChild = this.state.layout.state.children[0]!; const firstChild = this.state.layout.state.children[0]!;
const newChildren: SceneLayoutChild[] = []; const newChildren: SceneLayoutChild[] = [];
@ -53,7 +53,7 @@ export class ScenePanelRepeater extends SceneObjectBase<RepeatOptions> {
this.state.layout.setState({ children: newChildren }); this.state.layout.setState({ children: newChildren });
} }
static Component = ({ model, isEditing }: SceneComponentProps<ScenePanelRepeater>) => { public static Component = ({ model, isEditing }: SceneComponentProps<ScenePanelRepeater>) => {
const { layout } = model.useState(); const { layout } = model.useState();
return <layout.Component model={layout} isEditing={isEditing} />; return <layout.Component model={layout} isEditing={isEditing} />;
}; };

@ -11,7 +11,7 @@ export interface SceneTimePickerState extends SceneObjectStatePlain {
} }
export class SceneTimePicker extends SceneObjectBase<SceneTimePickerState> { export class SceneTimePicker extends SceneObjectBase<SceneTimePickerState> {
static Component = SceneTimePickerRenderer; public static Component = SceneTimePickerRenderer;
} }
function SceneTimePickerRenderer({ model }: SceneComponentProps<SceneTimePicker>) { function SceneTimePickerRenderer({ model }: SceneComponentProps<SceneTimePicker>) {

@ -11,7 +11,7 @@ export interface ToolbarButtonState extends SceneObjectStatePlain {
} }
export class SceneToolbarButton extends SceneObjectBase<ToolbarButtonState> { export class SceneToolbarButton extends SceneObjectBase<ToolbarButtonState> {
static Component = ({ model }: SceneComponentProps<SceneToolbarButton>) => { public static Component = ({ model }: SceneComponentProps<SceneToolbarButton>) => {
const state = model.useState(); const state = model.useState();
return <ToolbarButton onClick={state.onClick} icon={state.icon} />; return <ToolbarButton onClick={state.onClick} icon={state.icon} />;
@ -24,7 +24,7 @@ export interface SceneToolbarInputState extends SceneObjectStatePlain {
} }
export class SceneToolbarInput extends SceneObjectBase<SceneToolbarInputState> { export class SceneToolbarInput extends SceneObjectBase<SceneToolbarInputState> {
static Component = ({ model }: SceneComponentProps<SceneToolbarInput>) => { public static Component = ({ model }: SceneComponentProps<SceneToolbarInput>) => {
const state = model.useState(); const state = model.useState();
return ( return (

@ -16,10 +16,10 @@ export interface VizPanelState extends SceneLayoutChildState {
} }
export class VizPanel extends SceneObjectBase<VizPanelState> { export class VizPanel extends SceneObjectBase<VizPanelState> {
static Component = ScenePanelRenderer; public static Component = ScenePanelRenderer;
static Editor = VizPanelEditor; public static Editor = VizPanelEditor;
onSetTimeRange = (timeRange: AbsoluteTimeRange) => { public onSetTimeRange = (timeRange: AbsoluteTimeRange) => {
const sceneTimeRange = this.getTimeRange(); const sceneTimeRange = this.getTimeRange();
sceneTimeRange.setState({ sceneTimeRange.setState({
raw: { raw: {

@ -16,9 +16,9 @@ export abstract class SceneObjectBase<TState extends SceneObjectState = {}> impl
private _events = new EventBusSrv(); private _events = new EventBusSrv();
protected _parent?: SceneObject; protected _parent?: SceneObject;
protected subs = new Subscription(); protected _subs = new Subscription();
constructor(state: TState) { public constructor(state: TState) {
if (!state.key) { if (!state.key) {
state.key = uuidv4(); state.key = uuidv4();
} }
@ -29,17 +29,17 @@ export abstract class SceneObjectBase<TState extends SceneObjectState = {}> impl
} }
/** Current state */ /** Current state */
get state(): TState { public get state(): TState {
return this._state; return this._state;
} }
/** True if currently being active (ie displayed for visual objects) */ /** True if currently being active (ie displayed for visual objects) */
get isActive(): boolean { public get isActive(): boolean {
return this._isActive; return this._isActive;
} }
/** Returns the parent, undefined for root object */ /** Returns the parent, undefined for root object */
get parent(): SceneObject | undefined { public get parent(): SceneObject | undefined {
return this._parent; return this._parent;
} }
@ -47,14 +47,14 @@ export abstract class SceneObjectBase<TState extends SceneObjectState = {}> impl
* Used in render functions when rendering a SceneObject. * Used in render functions when rendering a SceneObject.
* Wraps the component in an EditWrapper that handles edit mode * Wraps the component in an EditWrapper that handles edit mode
*/ */
get Component(): SceneComponent<this> { public get Component(): SceneComponent<this> {
return SceneComponentWrapper; return SceneComponentWrapper;
} }
/** /**
* Temporary solution, should be replaced by declarative options * Temporary solution, should be replaced by declarative options
*/ */
get Editor(): SceneComponent<this> { public get Editor(): SceneComponent<this> {
return ((this as any).constructor['Editor'] ?? (() => null)) as SceneComponent<this>; return ((this as any).constructor['Editor'] ?? (() => null)) as SceneComponent<this>;
} }
@ -77,18 +77,18 @@ export abstract class SceneObjectBase<TState extends SceneObjectState = {}> impl
/** /**
* Subscribe to the scene state subject * Subscribe to the scene state subject
**/ **/
subscribeToState(observerOrNext?: Partial<Observer<TState>>): Subscription { public subscribeToState(observerOrNext?: Partial<Observer<TState>>): Subscription {
return this._subject.subscribe(observerOrNext); return this._subject.subscribe(observerOrNext);
} }
/** /**
* Subscribe to the scene event * Subscribe to the scene event
**/ **/
subscribeToEvent<T extends BusEvent>(eventType: BusEventType<T>, handler: BusEventHandler<T>): Unsubscribable { public subscribeToEvent<T extends BusEvent>(eventType: BusEventType<T>, handler: BusEventHandler<T>): Unsubscribable {
return this._events.subscribe(eventType, handler); return this._events.subscribe(eventType, handler);
} }
setState(update: Partial<TState>) { public setState(update: Partial<TState>) {
const prevState = this._state; const prevState = this._state;
this._state = { this._state = {
...this._state, ...this._state,
@ -112,7 +112,7 @@ export abstract class SceneObjectBase<TState extends SceneObjectState = {}> impl
/* /*
* Publish an event and optionally bubble it up the scene * Publish an event and optionally bubble it up the scene
**/ **/
publishEvent(event: BusEvent, bubble?: boolean) { public publishEvent(event: BusEvent, bubble?: boolean) {
this._events.publish(event); this._events.publish(event);
if (bubble && this.parent) { if (bubble && this.parent) {
@ -120,11 +120,14 @@ export abstract class SceneObjectBase<TState extends SceneObjectState = {}> impl
} }
} }
getRoot(): SceneObject { public getRoot(): SceneObject {
return !this._parent ? this : this._parent.getRoot(); return !this._parent ? this : this._parent.getRoot();
} }
activate() { /**
* Called by the SceneComponentWrapper when the react component is mounted
*/
public activate() {
this._isActive = true; this._isActive = true;
const { $data, $variables } = this.state; const { $data, $variables } = this.state;
@ -138,7 +141,10 @@ export abstract class SceneObjectBase<TState extends SceneObjectState = {}> impl
} }
} }
deactivate(): void { /**
* Called by the SceneComponentWrapper when the react component is unmounted
*/
public deactivate(): void {
this._isActive = false; this._isActive = false;
const { $data, $variables } = this.state; const { $data, $variables } = this.state;
@ -153,14 +159,17 @@ export abstract class SceneObjectBase<TState extends SceneObjectState = {}> impl
// Clear subscriptions and listeners // Clear subscriptions and listeners
this._events.removeAllListeners(); this._events.removeAllListeners();
this.subs.unsubscribe(); this._subs.unsubscribe();
this.subs = new Subscription(); this._subs = new Subscription();
this._subject.complete(); this._subject.complete();
this._subject = new Subject<TState>(); this._subject = new Subject<TState>();
} }
useState() { /**
* Utility hook to get and subscribe to state
*/
public useState() {
// eslint-disable-next-line react-hooks/rules-of-hooks // eslint-disable-next-line react-hooks/rules-of-hooks
return useSceneObjectState(this); return useSceneObjectState(this);
} }
@ -168,7 +177,7 @@ export abstract class SceneObjectBase<TState extends SceneObjectState = {}> impl
/** /**
* Will walk up the scene object graph to the closest $timeRange scene object * Will walk up the scene object graph to the closest $timeRange scene object
*/ */
getTimeRange(): SceneTimeRange { public getTimeRange(): SceneTimeRange {
const { $timeRange } = this.state; const { $timeRange } = this.state;
if ($timeRange) { if ($timeRange) {
return $timeRange; return $timeRange;
@ -184,7 +193,7 @@ export abstract class SceneObjectBase<TState extends SceneObjectState = {}> impl
/** /**
* Will walk up the scene object graph to the closest $data scene object * Will walk up the scene object graph to the closest $data scene object
*/ */
getData(): SceneObject<SceneDataState> { public getData(): SceneObject<SceneDataState> {
const { $data } = this.state; const { $data } = this.state;
if ($data) { if ($data) {
return $data; return $data;
@ -200,7 +209,7 @@ export abstract class SceneObjectBase<TState extends SceneObjectState = {}> impl
/** /**
* Will walk up the scene object graph to the closest $editor scene object * Will walk up the scene object graph to the closest $editor scene object
*/ */
getSceneEditor(): SceneEditor { public getSceneEditor(): SceneEditor {
const { $editor } = this.state; const { $editor } = this.state;
if ($editor) { if ($editor) {
return $editor; return $editor;
@ -216,7 +225,7 @@ export abstract class SceneObjectBase<TState extends SceneObjectState = {}> impl
/** /**
* Will create new SceneItem with shalled cloned state, but all states items of type SceneObject are deep cloned * Will create new SceneItem with shalled cloned state, but all states items of type SceneObject are deep cloned
*/ */
clone(withState?: Partial<TState>): this { public clone(withState?: Partial<TState>): this {
const clonedState = { ...this.state }; const clonedState = { ...this.state };
// Clone any SceneItems in state // Clone any SceneItems in state

@ -4,26 +4,26 @@ import { SceneObjectBase } from './SceneObjectBase';
import { SceneObjectWithUrlSync, SceneTimeRangeState } from './types'; import { SceneObjectWithUrlSync, SceneTimeRangeState } from './types';
export class SceneTimeRange extends SceneObjectBase<SceneTimeRangeState> implements SceneObjectWithUrlSync { export class SceneTimeRange extends SceneObjectBase<SceneTimeRangeState> implements SceneObjectWithUrlSync {
onTimeRangeChange = (timeRange: TimeRange) => { public onTimeRangeChange = (timeRange: TimeRange) => {
this.setState(timeRange); this.setState(timeRange);
}; };
onRefresh = () => { public onRefresh = () => {
// TODO re-eval time range // TODO re-eval time range
this.setState({ ...this.state }); this.setState({ ...this.state });
}; };
onIntervalChanged = (_: string) => {}; public onIntervalChanged = (_: string) => {};
/** These url sync functions are only placeholders for something more sophisticated */ /** These url sync functions are only placeholders for something more sophisticated */
getUrlState() { public getUrlState() {
return { return {
from: this.state.raw.from, from: this.state.raw.from,
to: this.state.raw.to, to: this.state.raw.to,
} as any; } as any;
} }
updateFromUrl(values: UrlQueryMap) { public updateFromUrl(values: UrlQueryMap) {
// TODO // TODO
} }
} }

@ -10,12 +10,5 @@ export interface SceneObjectStateChangedPayload {
} }
export class SceneObjectStateChangedEvent extends BusEventWithPayload<SceneObjectStateChangedPayload> { export class SceneObjectStateChangedEvent extends BusEventWithPayload<SceneObjectStateChangedPayload> {
static type = 'scene-object-state-change'; public static readonly type = 'scene-object-state-change';
}
export class SceneObjectActivedEvent extends BusEventWithPayload<SceneObject> {
static type = 'scene-object-activated';
}
export class SceneObjectDeactivatedEvent extends BusEventWithPayload<SceneObject> {
static type = 'scene-object-deactivated';
} }

@ -11,17 +11,17 @@ import { SceneObjectEditor } from './SceneObjectEditor';
import { SceneObjectTree } from './SceneObjectTree'; import { SceneObjectTree } from './SceneObjectTree';
export class SceneEditManager extends SceneObjectBase<SceneEditorState> implements SceneEditor { export class SceneEditManager extends SceneObjectBase<SceneEditorState> implements SceneEditor {
static Component = SceneEditorRenderer; public static Component = SceneEditorRenderer;
get Component(): SceneComponent<this> { public get Component(): SceneComponent<this> {
return SceneEditorRenderer; return SceneEditorRenderer;
} }
onMouseEnterObject(model: SceneObject) { public onMouseEnterObject(model: SceneObject) {
this.setState({ hoverObject: { ref: model } }); this.setState({ hoverObject: { ref: model } });
} }
onMouseLeaveObject(model: SceneObject) { public onMouseLeaveObject(model: SceneObject) {
if (model.parent) { if (model.parent) {
this.setState({ hoverObject: { ref: model.parent } }); this.setState({ hoverObject: { ref: model.parent } });
} else { } else {
@ -29,7 +29,7 @@ export class SceneEditManager extends SceneObjectBase<SceneEditorState> implemen
} }
} }
onSelectObject(model: SceneObject) { public onSelectObject(model: SceneObject) {
this.setState({ selectedObject: { ref: model } }); this.setState({ selectedObject: { ref: model } });
} }
} }

@ -31,12 +31,12 @@ export interface DataQueryExtended extends DataQuery {
export class SceneQueryRunner extends SceneObjectBase<QueryRunnerState> { export class SceneQueryRunner extends SceneObjectBase<QueryRunnerState> {
private querySub?: Unsubscribable; private querySub?: Unsubscribable;
activate() { public activate() {
super.activate(); super.activate();
const timeRange = this.getTimeRange(); const timeRange = this.getTimeRange();
this.subs.add( this._subs.add(
timeRange.subscribeToState({ timeRange.subscribeToState({
next: (timeRange) => { next: (timeRange) => {
this.runWithTimeRange(timeRange); this.runWithTimeRange(timeRange);
@ -49,7 +49,7 @@ export class SceneQueryRunner extends SceneObjectBase<QueryRunnerState> {
} }
} }
deactivate(): void { public deactivate(): void {
super.deactivate(); super.deactivate();
if (this.querySub) { if (this.querySub) {
@ -58,7 +58,7 @@ export class SceneQueryRunner extends SceneObjectBase<QueryRunnerState> {
} }
} }
runQueries() { public runQueries() {
const timeRange = this.getTimeRange(); const timeRange = this.getTimeRange();
this.runWithTimeRange(timeRange.state); this.runWithTimeRange(timeRange.state);
} }

@ -10,16 +10,16 @@ export class UrlSyncManager {
private locationListenerUnsub: () => void; private locationListenerUnsub: () => void;
private stateChangeSub: Unsubscribable; private stateChangeSub: Unsubscribable;
constructor(sceneRoot: SceneObject) { public constructor(sceneRoot: SceneObject) {
this.stateChangeSub = sceneRoot.subscribeToEvent(SceneObjectStateChangedEvent, this.onStateChanged); this.stateChangeSub = sceneRoot.subscribeToEvent(SceneObjectStateChangedEvent, this.onStateChanged);
this.locationListenerUnsub = locationService.getHistory().listen(this.onLocationUpdate); this.locationListenerUnsub = locationService.getHistory().listen(this.onLocationUpdate);
} }
onLocationUpdate = (location: Location) => { private onLocationUpdate = (location: Location) => {
// TODO: find any scene object whose state we need to update // TODO: find any scene object whose state we need to update
}; };
onStateChanged = ({ payload }: SceneObjectStateChangedEvent) => { private onStateChanged = ({ payload }: SceneObjectStateChangedEvent) => {
const changedObject = payload.changedObject; const changedObject = payload.changedObject;
if ('getUrlState' in changedObject) { if ('getUrlState' in changedObject) {
@ -28,7 +28,7 @@ export class UrlSyncManager {
} }
}; };
cleanUp() { public cleanUp() {
this.stateChangeSub.unsubscribe(); this.stateChangeSub.unsubscribe();
this.locationListenerUnsub(); this.locationListenerUnsub();
} }

@ -8,7 +8,7 @@ import { SceneVariable, SceneVariables, SceneVariableSetState, SceneVariableStat
export class TextBoxSceneVariable extends SceneObjectBase<SceneVariableState> implements SceneVariable {} export class TextBoxSceneVariable extends SceneObjectBase<SceneVariableState> implements SceneVariable {}
export class SceneVariableSet extends SceneObjectBase<SceneVariableSetState> implements SceneVariables { export class SceneVariableSet extends SceneObjectBase<SceneVariableSetState> implements SceneVariables {
getVariableByName(name: string): SceneVariable | undefined { public getVariableByName(name: string): SceneVariable | undefined {
// TODO: Replace with index // TODO: Replace with index
return this.state.variables.find((x) => x.state.name === name); return this.state.variables.find((x) => x.state.name === name);
} }

Loading…
Cancel
Save