<commit_before>import msx from 'lib/msx';
import * as m from 'mithril';
import * as API from 'lib/api';
import Theme from 'lib/theme';
import { MustAuthController } from 'components/auth';

export default class InstallThemePage extends MustAuthController {
  installedThemes: { [key: string]: boolean };
  themes: API.Registry;
  installing: string;

  constructor() {
    super();
    this.installedThemes = {};
    Theme.list().then((themes) => {
      let installed: { [key: string]: boolean } = {};
      themes.forEach((theme) => {
        installed[theme.name] = true;
      });
      this.installedThemes = installed;
    });
    Theme.getAll().then((registry: API.Registry) => (this.themes = registry));
  }

  themeInstalled(name: string): boolean {
    return !!this.installedThemes[name];
  }

  view() {
    let themeInstall = (p: API.Package) => {
      return () => {
        if (this.installing) {
          return;
        }
        this.installing = p.name;
        m.redraw();
        Theme.install(p).then(() => {
          this.installing = null;
          m.redraw();
        });
      };
    };
    let packages = this.themes && this.themes.packages ? this.themes.packages : [];
    let themes = packages.map((p: API.Package) => {
      let themeControl;
      if (this.themeInstalled(p.name)) {
        themeControl = (
          <a class='tr' href={`/admin/themes/${p.name}`} oncreate={m.route.link}>
            installed
          </a>
        );
      } else {
        let themeControlClasses = ['button', 'button--small'];
        if (!!this.installedThemes) {
          themeControlClasses.push('button--disabled');
        } else {
          themeControlClasses.push('button--blue');
        }
        themeControl = (
          <a
            disabled={!!this.installing}
            class={themeControlClasses.join(' ')}
            onclick={themeInstall(p)}
          >
            install
          </a>
        );
        return (
          <div class='tr'>
            <div>{p.name}</div>
            <div>{p.vcsUrl}</div>
            {themeControl}
          </div>
        );
      }
    });

    return (
      <div>
        <h1>Theme Manager</h1>
        {!this.installing ? '' : <div>{`Installing theme ${this.installing}...`}</div>}
        <div class='table'>{themes}</div>
      </div>
    );
  }
}<commit_msg>admin: Show a modal on theme install.<commit_after>import msx from 'lib/msx';
import * as m from 'mithril';
import * as API from 'lib/api';
import Theme from 'lib/theme';
import { MustAuthController } from 'components/auth';
import { LinkRow, Row } from 'components/table';
import { ModalComponent } from 'components/modal';
import { Loader } from 'components/loading';
import * as Toaster from 'components/toaster';

export default class InstallThemePage extends MustAuthController {
  installedThemes: { [key: string]: boolean };
  themes: API.Registry;
  installing: string;

  constructor() {
    super();
    this.installedThemes = {};
    this.loadThemes();
    Theme.getAll().then((registry: API.Registry) => (this.themes = registry));
  }

  loadThemes() {
    Theme.list().then((themes) => {
      let installed: { [key: string]: boolean } = {};
      themes.forEach((theme) => {
        installed[theme.name] = true;
      });
      this.installedThemes = installed;
      m.redraw();
    });
  }

  themeInstalled(name: string): boolean {
    return !!this.installedThemes[name];
  }

  installTheme(p: API.Package) {
    if (this.installing) {
      return;
    }
    this.installing = p.name;
    Theme.install(p).then(() => {
      Toaster.add(this.installing + ' theme installed.');
      this.installing = null;
      return this.loadThemes();
    });
  }

  view() {
    let packages = this.themes && this.themes.packages ? this.themes.packages : [];
    let themes = packages.map((p: API.Package) => {
      if (this.themeInstalled(p.name)) {
        return (
          <LinkRow href={`/admin/themes/${p.name}`} link>
            <div>{p.name}</div>
            <div>{p.vcsUrl}</div>
            <div>installed</div>
          </LinkRow>
        );
      }

      return (
        <Row center>
          <div>{p.name}</div>
          <div>{p.vcsUrl}</div>
          <a
            class='button button--small button--blue'
            disabled={!!this.installing}
            onclick={() => this.installTheme(p)}
          >
            install
          </a>
        </Row>
      );
    });

    return (
      <div>
        <h1>Theme Manager</h1>
        <div class='table'>{themes}</div>
        <ModalComponent
          title='Installing theme...'
          visible={() => !!this.installing}
          toggle={() => {}}
        >
          {Loader}
        </ModalComponent>
      </div>
    );
  }
}
{'fraction_non_alphanumeric': 0.162863722001256, 'fraction_numerical': 0.0008373456144023446, 'mean_word_length': 2.062820512820513, 'pattern_counts': {'":': 0, '<': 45, '<?xml version=': 0, '>': 60, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '912663', 'n_tokens_mistral': 1459, 'n_tokens_neox': 1432, 'n_words': 281}