<commit_before>import React, { Component } from 'react';
import { withRouter } from 'react-router';
import { injectIntl } from 'react-intl';
import queryString from 'query-string';

import Query from 'src/app/Query';
import Screen from 'src/components/Screen/Screen';
import EntityContextLoader from 'src/components/Entity/EntityContextLoader';
import { compose } from 'redux';
import { connect } from 'react-redux';
import EntityHeading from 'src/components/Entity/EntityHeading';
import EntityInfoMode from 'src/components/Entity/EntityInfoMode';
import EntityViews from 'src/components/Entity/EntityViews';
import LoadingScreen from 'src/components/Screen/LoadingScreen';
import ErrorScreen from 'src/components/Screen/ErrorScreen';
import Property from 'src/components/Property';
import { Collection, DualPane, Entity, Breadcrumbs } from 'src/components/common';
import { DownloadButton } from 'src/components/Toolbar';
import getEntityLink from 'src/util/getEntityLink';
import { queryEntityReference } from 'src/queries';
import {
  selectEntity, selectEntityReference, selectEntityView,
} from 'src/selectors';

import 'src/components/common/ItemOverview.scss';

const SEARCHABLES = ['Pages', 'Folder', 'Package', 'Workbook'];


class EntityScreen extends Component {
  constructor(props) {
    super(props);
    this.onCollectionSearch = this.onCollectionSearch.bind(this);
    this.onSearch = this.onSearch.bind(this);
  }

  onCollectionSearch(queryText) {
    const { history, entity } = this.props;
    const query = {
      q: queryText,
      'filter:collection_id': entity.collection.id,
    };
    history.push({
      pathname: '/search',
      search: queryString.stringify(query),
    });
  }

  onSearch(queryText, entityLink) {
    const { history, location, query } = this.props;
    const parsedHash = queryString.parse(location.hash);
    const newQuery = query.setString('q', queryText);
    parsedHash['preview:id'] = undefined;
    parsedHash['preview:mode'] = undefined;
    parsedHash.page = undefined;
    history.push({
      pathname: entityLink,
      search: newQuery.toLocation(),
      hash: queryString.stringify(parsedHash),
    });
  }

  getEntitySearchScope(entity) {
    const hasSearch = entity.schema.isAny(SEARCHABLES) && !entity.schema.isA('Email');
    if (!hasSearch) {
      return null;
    }
    const entityLink = getEntityLink(entity);
    return {
      listItem: <Entity.Label entity={entity} icon truncate={30} />,
      label: entity.getCaption(),
      onSearch: queryText => this.onSearch(queryText, entityLink),
    };
  }

  getReferenceSearchScope(entity) {
    const { reference } = this.props;
    if (!reference || reference.count < 10) {
      return null;
    }
    const item = (
      <>
        <Entity.Label entity={entity} icon truncate={30} />
        { ': ' }
        <Property.Reverse prop={reference.property} />
      </>
    );
    const entityLink = getEntityLink(entity);
    return {
      listItem: item,
      label: reference.property.getReverse().label,
      onSearch: queryText => this.onSearch(queryText, entityLink),
    };
  }

  getSearchScopes() {
    const { entity } = this.props;
    const scopes = [];

    const referenceScope = this.getReferenceSearchScope(entity);
    if (referenceScope) {
      scopes.push(referenceScope);
    }

    let currEntity = entity;
    while (currEntity) {
      const entityScope = this.getEntitySearchScope(currEntity);
      if (entityScope) {
        scopes.push(entityScope);
      }
      currEntity = currEntity.getFirst('parent');
    }

    scopes.push({
      listItem: <Collection.Label collection={entity.collection} icon truncate={30} />,
      label: entity.collection.label,
      onSearch: this.onCollectionSearch,
    });

    return scopes.reverse();
  }

  render() {
    const {
      entity, entityId, activeMode, query, isDocument,
    } = this.props;
    if (entity.isError) {
      return <ErrorScreen error={entity.error} />;
    }
    if (entity.id === undefined) {
      return (
        <EntityContextLoader entityId={entityId}>
          <LoadingScreen />
        </EntityContextLoader>
      );
    }

    const showDownloadButton = isDocument && entity && entity.links && entity.links.file;
    const operation = showDownloadButton && (
      <DownloadButton document={entity} />
    );

    const breadcrumbs = (
      <Breadcrumbs operation={operation}>
        <Breadcrumbs.Collection collection={entity.collection} />
        <Breadcrumbs.Entity entity={entity} />
      </Breadcrumbs>
    );

    return (
      <EntityContextLoader entityId={entityId}>
        <Screen title={entity.getCaption()} searchScopes={this.getSearchScopes()} query={query}>
          {breadcrumbs}
          <DualPane>
            <DualPane.SidePane className="ItemOverview">
              <div className="ItemOverview__heading">
                <EntityHeading entity={entity} isPreview={false} />
              </div>
              <div className="ItemOverview__content">
                <EntityInfoMode entity={entity} isPreview={false} />
              </div>
            </DualPane.SidePane>
            <DualPane.ContentPane>
              <EntityViews
                entity={entity}
                activeMode={activeMode}
                isPreview={false}
              />
            </DualPane.ContentPane>
          </DualPane>
        </Screen>
      </EntityContextLoader>
    );
  }
}

const mapStateToProps = (state, ownProps) => {
  const { entityId } = ownProps.match.params;
  const { location } = ownProps;
  const entity = selectEntity(state, entityId);
  const hashQuery = queryString.parse(location.hash);
  const isDocument = entity && entity.id && entity.schema.isDocument();
  const activeMode = selectEntityView(state, entityId, hashQuery.mode, false);
  const reference = selectEntityReference(state, entityId, activeMode);
  const referenceQuery = queryEntityReference(location, entity, reference);
  const documentQuery = Query.fromLocation('entities', location, {}, 'document');
  return {
    entity,
    entityId,
    reference,
    activeMode,
    isDocument,
    query: referenceQuery || documentQuery,
  };
};

export default compose(
  withRouter,
  connect(mapStateToProps),
  injectIntl,
)(EntityScreen);
<commit_msg>added delete button and delete dialog to entity screen<commit_after>import React, { Component } from 'react';
import { withRouter } from 'react-router';
import { injectIntl, FormattedMessage } from 'react-intl';
import queryString from 'query-string';
import { Button, ButtonGroup } from '@blueprintjs/core';

import Query from 'src/app/Query';
import Screen from 'src/components/Screen/Screen';
import EntityContextLoader from 'src/components/Entity/EntityContextLoader';
import { compose } from 'redux';
import { connect } from 'react-redux';
import EntityHeading from 'src/components/Entity/EntityHeading';
import EntityInfoMode from 'src/components/Entity/EntityInfoMode';
import EntityViews from 'src/components/Entity/EntityViews';
import EntityDeleteDialog from 'src/dialogs/EntityDeleteDialog/EntityDeleteDialog';
import LoadingScreen from 'src/components/Screen/LoadingScreen';
import ErrorScreen from 'src/components/Screen/ErrorScreen';
import Property from 'src/components/Property';
import { Collection, DualPane, Entity, Breadcrumbs } from 'src/components/common';
import { DownloadButton } from 'src/components/Toolbar';
import getEntityLink from 'src/util/getEntityLink';
import { queryEntityReference } from 'src/queries';
import {
  selectEntity, selectEntityReference, selectEntityView,
} from 'src/selectors';

import 'src/components/common/ItemOverview.scss';

const SEARCHABLES = ['Pages', 'Folder', 'Package', 'Workbook'];


class EntityScreen extends Component {
  constructor(props) {
    super(props);

    this.state = {
      deleteIsOpen: false,
    };

    this.onCollectionSearch = this.onCollectionSearch.bind(this);
    this.onSearch = this.onSearch.bind(this);
    this.toggleDeleteDialog = this.toggleDeleteDialog.bind(this);
  }

  onCollectionSearch(queryText) {
    const { history, entity } = this.props;
    const query = {
      q: queryText,
      'filter:collection_id': entity.collection.id,
    };
    history.push({
      pathname: '/search',
      search: queryString.stringify(query),
    });
  }

  onSearch(queryText, entityLink) {
    const { history, location, query } = this.props;
    const parsedHash = queryString.parse(location.hash);
    const newQuery = query.setString('q', queryText);
    parsedHash['preview:id'] = undefined;
    parsedHash['preview:mode'] = undefined;
    parsedHash.page = undefined;
    history.push({
      pathname: entityLink,
      search: newQuery.toLocation(),
      hash: queryString.stringify(parsedHash),
    });
  }

  getEntitySearchScope(entity) {
    console.log(entity);
    const hasSearch = entity.schema.isAny(SEARCHABLES) && !entity.schema.isA('Email');
    if (!hasSearch) {
      return null;
    }
    const entityLink = getEntityLink(entity);
    return {
      listItem: <Entity.Label entity={entity} icon truncate={30} />,
      label: entity.getCaption(),
      onSearch: queryText => this.onSearch(queryText, entityLink),
    };
  }

  getReferenceSearchScope(entity) {
    const { reference } = this.props;
    if (!reference || reference.count < 10) {
      return null;
    }
    const item = (
      <>
        <Entity.Label entity={entity} icon truncate={30} />
        { ': ' }
        <Property.Reverse prop={reference.property} />
      </>
    );
    const entityLink = getEntityLink(entity);
    return {
      listItem: item,
      label: reference.property.getReverse().label,
      onSearch: queryText => this.onSearch(queryText, entityLink),
    };
  }

  getSearchScopes() {
    const { entity } = this.props;
    const scopes = [];

    const referenceScope = this.getReferenceSearchScope(entity);
    if (referenceScope) {
      scopes.push(referenceScope);
    }

    let currEntity = entity;
    while (currEntity) {
      const entityScope = this.getEntitySearchScope(currEntity);
      if (entityScope) {
        scopes.push(entityScope);
      }
      currEntity = currEntity.getFirst('parent');
    }

    scopes.push({
      listItem: <Collection.Label collection={entity.collection} icon truncate={30} />,
      label: entity.collection.label,
      onSearch: this.onCollectionSearch,
    });

    return scopes.reverse();
  }

  toggleDeleteDialog() {
    this.setState(({ deleteIsOpen }) => ({ deleteIsOpen: !deleteIsOpen }));
  }

  render() {
    const {
      entity, entityId, activeMode, query, isDocument,
    } = this.props;
    if (entity.isError) {
      return <ErrorScreen error={entity.error} />;
    }
    if (entity.id === undefined) {
      return (
        <EntityContextLoader entityId={entityId}>
          <LoadingScreen />
        </EntityContextLoader>
      );
    }

    const showDownloadButton = isDocument && entity && entity.links && entity.links.file;
    const showDeleteButton = entity.collection.writeable;

    const operation = (
      <ButtonGroup>
        {showDownloadButton && <DownloadButton document={entity} /> }
        {showDeleteButton && (
          <Button icon="delete" onClick={this.toggleDeleteDialog}>
            <FormattedMessage id="entity.delete" defaultMessage="Delete" />
          </Button>
        )}
      </ButtonGroup>
    );

    const breadcrumbs = (
      <Breadcrumbs operation={operation}>
        <Breadcrumbs.Collection collection={entity.collection} />
        <Breadcrumbs.Entity entity={entity} />
      </Breadcrumbs>
    );

    return (
      <EntityContextLoader entityId={entityId}>
        <Screen title={entity.getCaption()} searchScopes={this.getSearchScopes()} query={query}>
          {breadcrumbs}
          <DualPane>
            <DualPane.SidePane className="ItemOverview">
              <div className="ItemOverview__heading">
                <EntityHeading entity={entity} isPreview={false} />
              </div>
              <div className="ItemOverview__content">
                <EntityInfoMode entity={entity} isPreview={false} />
              </div>
            </DualPane.SidePane>
            <DualPane.ContentPane>
              <EntityViews
                entity={entity}
                activeMode={activeMode}
                isPreview={false}
              />
              <EntityDeleteDialog
                entities={[entity]}
                isOpen={this.state.deleteIsOpen}
                toggleDialog={this.toggleDeleteDialog}
              />
            </DualPane.ContentPane>
          </DualPane>
        </Screen>
      </EntityContextLoader>
    );
  }
}

const mapStateToProps = (state, ownProps) => {
  const { entityId } = ownProps.match.params;
  const { location } = ownProps;
  const entity = selectEntity(state, entityId);
  const hashQuery = queryString.parse(location.hash);
  const isDocument = entity && entity.id && entity.schema.isDocument();
  const activeMode = selectEntityView(state, entityId, hashQuery.mode, false);
  const reference = selectEntityReference(state, entityId, activeMode);
  const referenceQuery = queryEntityReference(location, entity, reference);
  const documentQuery = Query.fromLocation('entities', location, {}, 'document');

  console.log(state, entityId, selectEntity(state, entityId));
  return {
    entity,
    entityId,
    reference,
    activeMode,
    isDocument,
    query: referenceQuery || documentQuery,
  };
};

export default compose(
  withRouter,
  connect(mapStateToProps),
  injectIntl,
)(EntityScreen);

{'fraction_non_alphanumeric': 0.12342957901697156, 'fraction_numerical': 0.0011755198001616339, 'mean_word_length': 3.118608169440242, 'pattern_counts': {'":': 0, '<': 75, '<?xml version=': 0, '>': 80, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6429888', 'n_tokens_mistral': 3857, 'n_tokens_neox': 3814, 'n_words': 792}