Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

react写的tsx文件 可以转成vue的js文件么 #22

Open
Keep-working-enthusiasm opened this issue Apr 18, 2022 · 1 comment
Open

Comments

@Keep-working-enthusiasm

Please copy your code of React Component into the following block

// your code
@Keep-working-enthusiasm
Copy link
Author

import React, { FC, useState, useEffect, useRef } from 'react';
import { Button, InputGroup, InputGroupAddon, InputGroupText } from 'reactstrap';

import { EditorView, highlightSpecialChars, keymap, ViewUpdate, placeholder } from '@codemirror/view';
import { EditorState, Prec, Compartment } from '@codemirror/state';
import { indentOnInput, syntaxTree } from '@codemirror/language';
import { history, historyKeymap } from '@codemirror/history';
import { defaultKeymap, insertNewlineAndIndent } from '@codemirror/commands';
import { bracketMatching } from '@codemirror/matchbrackets';
import { closeBrackets, closeBracketsKeymap } from '@codemirror/closebrackets';
import { searchKeymap, highlightSelectionMatches } from '@codemirror/search';
import { commentKeymap } from '@codemirror/comment';
import { lintKeymap } from '@codemirror/lint';
import { PromQLExtension } from 'codemirror-promql';
import { autocompletion, completionKeymap, CompletionContext, CompletionResult } from '@codemirror/autocomplete';
import { theme, promqlHighlighter } from './CMTheme';

import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faSearch, faSpinner, faGlobeEurope } from '@fortawesome/free-solid-svg-icons';
import MetricsExplorer from './MetricsExplorer';
import { CompleteStrategy, newCompleteStrategy } from 'codemirror-promql/complete';
import { usePathPrefix } from '../../contexts/PathPrefixContext';

const promqlExtension = new PromQLExtension();

interface CMExpressionInputProps {
value: string;
onExpressionChange: (expr: string) => void;
queryHistory: string[];
metricNames: string[];
executeQuery: () => void;
loading: boolean;
enableAutocomplete: boolean;
enableHighlighting: boolean;
enableLinter: boolean;
}

const dynamicConfigCompartment = new Compartment();

// Autocompletion strategy that wraps the main one and enriches
// it with past query items.
export class HistoryCompleteStrategy implements CompleteStrategy {
private complete: CompleteStrategy;
private queryHistory: string[];
constructor(complete: CompleteStrategy, queryHistory: string[]) {
this.complete = complete;
this.queryHistory = queryHistory;
}

promQL(context: CompletionContext): Promise<CompletionResult | null> | CompletionResult | null {
return Promise.resolve(this.complete.promQL(context)).then(res => {
const { state, pos } = context;
const tree = syntaxTree(state).resolve(pos, -1);
const start = res != null ? res.from : tree.from;

  if (start !== 0) {
    return res;
  }

  const historyItems: CompletionResult = {
    from: start,
    to: pos,
    options: this.queryHistory.map(q => ({
      label: q.length < 80 ? q : q.slice(0, 76).concat('...'),
      detail: 'past query',
      apply: q,
      info: q.length < 80 ? undefined : q,
    })),
    span: /^[a-zA-Z0-9_:]+$/,
  };

  if (res !== null) {
    historyItems.options = historyItems.options.concat(res.options);
  }
  return historyItems;
});

}
}

const CMExpressionInput: FC = ({
value,
onExpressionChange,
queryHistory,
metricNames,
executeQuery,
loading,
enableAutocomplete,
enableHighlighting,
enableLinter,
}) => {
const containerRef = useRef(null);
const viewRef = useRef<EditorView | null>(null);
const [showMetricsExplorer, setShowMetricsExplorer] = useState(false);
const pathPrefix = usePathPrefix();

// (Re)initialize editor based on settings / setting changes.
useEffect(() => {
// Build the dynamic part of the config.
promqlExtension.activateCompletion(enableAutocomplete);
promqlExtension.activateLinter(enableLinter);
promqlExtension.setComplete({
completeStrategy: new HistoryCompleteStrategy(
newCompleteStrategy({
remote: { url: pathPrefix },
}),
queryHistory
),
});
const dynamicConfig = [enableHighlighting ? promqlHighlighter : [], promqlExtension.asExtension()];

// Create or reconfigure the editor.
const view = viewRef.current;
if (view === null) {
  // If the editor does not exist yet, create it.
  if (!containerRef.current) {
    throw new Error('expected CodeMirror container element to exist');
  }

  const startState = EditorState.create({
    doc: value,
    extensions: [
      theme,
      highlightSpecialChars(),
      history(),
      EditorState.allowMultipleSelections.of(true),
      indentOnInput(),
      bracketMatching(),
      closeBrackets(),
      autocompletion(),
      highlightSelectionMatches(),
      EditorView.lineWrapping,
      keymap.of([
        ...closeBracketsKeymap,
        ...defaultKeymap,
        ...searchKeymap,
        ...historyKeymap,
        ...commentKeymap,
        ...completionKeymap,
        ...lintKeymap,
      ]),
      placeholder('Expression (press Shift+Enter for newlines)'),
      dynamicConfigCompartment.of(dynamicConfig),
      // This keymap is added without precedence so that closing the autocomplete dropdown
      // via Escape works without blurring the editor.
      keymap.of([
        {
          key: 'Escape',
          run: (v: EditorView): boolean => {
            v.contentDOM.blur();
            return false;
          },
        },
      ]),
      Prec.override(
        keymap.of([
          {
            key: 'Enter',
            run: (v: EditorView): boolean => {
              executeQuery();
              return true;
            },
          },
          {
            key: 'Shift-Enter',
            run: insertNewlineAndIndent,
          },
        ])
      ),
      EditorView.updateListener.of((update: ViewUpdate): void => {
        onExpressionChange(update.state.doc.toString());
      }),
    ],
  });

  const view = new EditorView({
    state: startState,
    parent: containerRef.current,
  });

  viewRef.current = view;

  view.focus();
} else {
  // The editor already exists, just reconfigure the dynamically configured parts.
  view.dispatch(
    view.state.update({
      effects: dynamicConfigCompartment.reconfigure(dynamicConfig),
    })
  );
}
// "value" is only used in the initial render, so we don't want to
// re-run this effect every time that "value" changes.
//
// eslint-disable-next-line react-hooks/exhaustive-deps

}, [enableAutocomplete, enableHighlighting, enableLinter, executeQuery, onExpressionChange, queryHistory]);

const insertAtCursor = (value: string) => {
const view = viewRef.current;
if (view === null) {
return;
}
const { from, to } = view.state.selection.ranges[0];
view.dispatch(
view.state.update({
changes: { from, to, insert: value },
})
);
};

return (
<>



{loading ? : }




<Button className="btn-light border" title="Open metrics explorer" onClick={() => setShowMetricsExplorer(true)}>





Execute


  <MetricsExplorer
    show={showMetricsExplorer}
    updateShow={setShowMetricsExplorer}
    metrics={metricNames}
    insertAtCursor={insertAtCursor}
  />
</>

);
};

export default CMExpressionInput;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant