Skip to content
Snippets Groups Projects
CondensateDetailPage.vue 34.07 KiB
<template>
  <div class="d-flex" id="wrapper">
    <!-- Sidebar -->
    <!--<div class="bg-light border-right" id="sidebar-wrapper">-->
    <!--&lt;!&ndash;<div class="sidebar-heading">Menu </div>&ndash;&gt;-->
    <!--<div class="list-group list-group-flush">-->
    <!--<a href="#" class="list-group-item list-group-item-action bg-light">Search</a>-->
    <!--<a href="#" class="list-group-item list-group-item-action bg-light">Columns</a>-->
    <!--<a href="#" class="list-group-item list-group-item-action bg-light">Filters</a>-->
    <!--<a href="#" class="list-group-item list-group-item-action bg-light">Download</a>-->
    <!--<a href="#" class="list-group-item list-group-item-action bg-light">Contacts</a>-->
    <!--</div>-->
    <!--</div>-->
    <!-- /#sidebar-wrapper -->

    <div id="page-content-wrapper" class="main">
      <fetch-condensate :condensate="condensate">
        <template slot-scope="{ response, loading }">
          <slot :response="response" :loading="loading">
            <div v-if="loading || response === null">Loading...</div>
            <div v-else>
              <h2>{{ response.data.name }}</h2>
              <h4 class="round">General Information</h4>
              <div class="panel panel-default">
                <div class="panel-body">
                  <div class="container-fluid col-md-12">
                    <div class="row">
                      <div class="text col-sm-3">Canonical ID</div>
                      <div class="col-sm-9">
                        {{ response.data.canonical_id }}
                      </div>
                    </div>
                    <div class="row">
                      <div class="text col-sm-3">Species</div>
                      <div class="col-sm-9">
                        {{ response.data.species_name }}
                      </div>
                    </div>
                    <div class="row">
                      <div class="text col-sm-3">Description</div>
                      <div class="col-sm-9">
                        {{ response.data.description }}
                        <button
                          v-if="
                            getUserData !== null &&
                            (getUserData === 'Maintainer' ||
                              getUserData === 'Contributor')
                          "
                          class="btn btn-primary btn-link"
                          @click="
                            toggleUpdateDescription(response.data.description)
                          "
                        >
                          <font-awesome-icon
                            icon="fa-solid fa-pen-to-square fa-xl"
                          />
                        </button>
                        <div
                          class="panel panel-default"
                          v-if="showUpdateDescription"
                        >
                          <div class="panel-body">
                            <div class="container-fluid col-md-12">
                              <form
                                class="form-horizontal"
                                autocomplete="off"
                                @submit.prevent="updateDescription(response)"
                              >
                                <div class="form-group">
                                  <label
                                    class="control-label col-sm-2"
                                    for="keyword"
                                    >Update description</label
                                  >
                                  <div class="col-sm-10">
                                    <textarea
                                      class="
                                        form-control
                                        block
                                        px-3
                                        py-1.5
                                        text-base
                                        font-normal
                                        text-gray-700
                                        bg-white bg-clip-padding
                                        border border-solid border-gray-300
                                        rounded
                                        transition
                                        ease-in-out
                                        m-0
                                        focus:text-gray-700
                                        focus:bg-white
                                        focus:border-blue-600
                                        focus:outline-none
                                      "
                                      id="comment"
                                      rows="5"
                                      placeholder="Description"
                                      v-model.trim="description"
                                      @keyup="descriptionKeyup"
                                    ></textarea>

                                    <p
                                      v-if="descriptionErrorMsg"
                                      class="text-red-600 font-bold"
                                    >
                                      {{ descriptionErrorMsg }}
                                    </p>
                                  </div>
                                </div>
                                <div class="form-group">
                                  <label
                                    class="control-label col-sm-2"
                                    for="funComment"
                                    >Reason</label
                                  >

                                  <div class="col-sm-10">
                                    <textarea
                                      class="
                                        form-control
                                        block
                                        px-3
                                        py-1.5
                                        text-base
                                        font-normal
                                        text-gray-700
                                        bg-white bg-clip-padding
                                        border border-solid border-gray-300
                                        rounded
                                        transition
                                        ease-in-out
                                        m-0
                                        focus:text-gray-700
                                        focus:bg-white
                                        focus:border-blue-600
                                        focus:outline-none
                                      "
                                      id="funComment"
                                      rows="5"
                                      :placeholder="
                                        getUserData === 'Maintainer'
                                          ? 'Is optional'
                                          : 'Is Mandatory'
                                      "
                                      v-model.trim="comment"
                                      @keyup="commentKeyup"
                                    ></textarea>
                                    <p
                                      v-if="isCommentError"
                                      class="text-red-600 font-bold"
                                    >
                                      {{ commentErrorMsg }}
                                    </p>
                                    <p
                                      v-if="descriptionMsg"
                                      class="text-green-600 font-bold"
                                    >
                                      {{ descriptionMsg }}
                                    </p>
                                    <div class="flex space-x-4">
                                      <button
                                        class="btn btn-primary"
                                        type="submit"
                                        id="dropdownMenuButton"
                                      >
                                        Update
                                      </button>
                                      <button
                                        class="btn btn-danger border"
                                        type="button"
                                        id="dropdownMenuButton"
                                        @click="toggleUpdateDescription"
                                      >
                                        cancel
                                      </button>
                                    </div>
                                  </div>
                                </div>
                              </form>
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                    <!--<div class="row">-->
                    <!--<div class="text col-sm-3">Evidence Stars</div>-->
                    <!--<div class="col-sm-9 tooltipped tooltipped-w"-->
                    <!--:aria-label="getDbNames(response.data.data_sources)">-->
                    <!--<span v-for="(item, index) in getRating(response.data.data_sources)" :class="item" v-bind:key="index"/>-->
                    <!--</div>-->
                    <!--</div>-->
                    <div class="row" v-show="response.data.synonyms">
                      <div class="text col-sm-3">Also Known As</div>
                      <div class="col-sm-9">
                        {{
                          response.data.synonyms
                            ? response.data.synonyms
                                .map((a) =>
                                  a
                                    .replace("-", " ")
                                    .replace(/\b\w/g, (l) => l.toUpperCase())
                                )
                                .join(", ")
                            : ""
                        }}
                      </div>
                    </div>

                    <div class="row">
                      <div class="text col-sm-3">
                        Markers
                        <a
                          class="uniprot-link tooltipped tooltipped-e"
                          aria-label="Proteins which can help in unique identification of the condensate organelle"
                        >
                          <span class="fa fa-info-circle" />
                        </a>
                      </div>
                      <div class="col-sm-9">
                        <span v-if="!response.data.biomarkers"> None </span>

                        <span
                          v-else
                          v-html="getProteinLinks(response.data.biomarkers)"
                        ></span>

                        <button
                          v-if="
                            getUserData !== null &&
                            (getUserData === 'Maintainer' ||
                              getUserData === 'Contributor')
                          "
                          class="btn btn-primary btn-link"
                          @click="showAddDeleteMarker = !showAddDeleteMarker"
                        >
                          <font-awesome-icon
                            icon="fa-solid fa-pen-to-square fa-xl"
                          />
                        </button>
                        <add-delete-marker
                          v-if="showAddDeleteMarker"
                          :marker-data="response.data.biomarkers"
                          :condensate-id="response.data.canonical_id"
                          :proteins="response.data.proteins"
                          @close="closeAddDeleteMarker"
                        />
                      </div>
                    </div>

                    <div class="row">
                      <div class="text col-sm-3">No. of Proteins</div>
                      <div class="col-sm-9">
                        {{ response.data.protein_count }}
                      </div>
                    </div>
                  </div>
                </div>
              </div>

              <div v-show="response.data.experiments.length > 0">
                <h4 class="round">Experiments</h4>
                <div class="panel panel-default">
                  <table class="csi table table-hover table-responsive">
                    <thead>
                      <tr class="active">
                        <!--                                    <th>Exp. ID</th>-->
                        <th>Method</th>
                        <th>Phase Separated</th>
                        <th>pH value</th>
                        <th>Morphology</th>
                        <th>PubMed</th>
                        <th>Solute Concentration</th>
                        <th>Temperature</th>
                        <th>Salts</th>
                      </tr>
                    </thead>
                    <tbody>
                      <tr
                        v-for="(item, index) in response.data.experiments"
                        v-bind:key="index"
                      >
                        <!--                                    <td>{{item.exp_id}}</td>-->
                        <td class="text-nowrap">{{ item.detection_method }}</td>
                        <td>{{ item.is_phase_separated }}</td>
                        <td>{{ item.ph_value }}</td>
                        <td>{{ item.morphology }}</td>
                        <td>
                          <fetch-pub-med :link="item.publication_link">
                            <template slot-scope="{ response, loading }">
                              <slot :response="response" :loading="loading">
                                <div v-if="loading"></div>
                                <div v-else>
                                  <a
                                    :href="item.publication_link"
                                    class="
                                      uniprot-link
                                      tooltipped
                                      tooltipped-n
                                      tooltipped-multiline
                                    "
                                    :aria-label="
                                      getTitleAuthors(
                                        response.title,
                                        response.authors
                                      )
                                    "
                                    target="_blank"
                                  >
                                    PubMed
                                    <i class="glyphicon glyphicon-link"></i>
                                  </a>
                                </div>
                              </slot>
                            </template>
                          </fetch-pub-med>
                        </td>
                        <td
                          v-html="tokenize(item.solute_concentrations, ';')"
                        ></td>
                        <td>
                          {{ item.temperature }}
                        </td>
                        <td>
                          <ul
                            v-for="(item, index) in item.salts"
                            v-bind:key="index"
                          >
                            <li
                              v-for="(value, key, index) in item"
                              v-bind:key="index"
                            >
                              {{ key }} : {{ value }}
                            </li>
                          </ul>
                        </td>
                      </tr>
                    </tbody>
                  </table>
                </div>
              </div>

              <h4 class="round">Proteins</h4>

              <button
                v-if="
                  getUserData !== null &&
                  (getUserData === 'Maintainer' ||
                    getUserData === 'Contributor')
                "
                class="btn btn-primary dropdown-toggle"
                type="button"
                @click="showAddProtein = !showAddProtein"
              >
                Add a protein to this condensate
              </button>
              <div v-if="showAddProtein" class="panel panel-default mt-4">
                <div class="panel-body">
                  <div class="container-fluid col-md-12">
                    <form
                      class="form-horizontal"
                      autocomplete="off"
                      @submit.prevent="addProtein(response)"
                    >
                      <div class="form-group">
                        <label class="control-label col-sm-2" for="species"
                          >Add protein with uniprod ID</label
                        >
                        <div class="col-sm-4">
                          <input
                            class="form-control input-sm"
                            id="keyword"
                            type="text"
                            v-model.trim="uniprotId"
                            placeholder="Uniprot ID"
                            @keyup="uniprotKeyup"
                          />
                          <p
                            v-if="isUniProtIdError"
                            class="text-red-600 mt-4 font-bold"
                          >
                            {{ uniprotIdErrorMsg }}
                          </p>
                        </div>
                      </div>
                      <div class="form-group">
                        <label class="control-label col-sm-2" for="keyword"
                          >Reason</label
                        >
                        <div class="col-sm-4">
                          <textarea
                            class="
                              form-control
                              block
                              px-3
                              py-1.5
                              text-base
                              font-normal
                              text-gray-700
                              bg-white bg-clip-padding
                              border border-solid border-gray-300
                              rounded
                              transition
                              ease-in-out
                              m-0
                              focus:text-gray-700
                              focus:bg-white
                              focus:border-blue-600
                              focus:outline-none
                            "
                            id="comment"
                            rows="5"
                            :placeholder="
                              getUserData === 'Maintainer'
                                ? 'Is optional.'
                                : 'Is mandatory.'
                            "
                            v-model.trim="comment"
                            @keyup="commentKeyup"
                          ></textarea>
                          <p
                            v-if="isCommentError"
                            class="text-red-600 font-bold"
                          >
                            {{ commentErrorMsg }}
                          </p>
                          <p
                            v-if="isSubmitted"
                            :class="
                              error
                                ? 'text-red-600 font-bold'
                                : 'text-green-600 font-bold'
                            "
                          >
                            {{ message }}
                          </p>
                          <div class="flex space-x-4">
                            <button
                              class="btn btn-primary"
                              type="submit"
                              id="dropdownMenuButton"
                            >
                              Add
                            </button>
                            <button
                              class="btn btn-danger border"
                              type="button"
                              id="dropdownMenuButton"
                              @click="showAddProtein = !showAddProtein"
                            >
                              cancel
                            </button>
                          </div>
                        </div>
                      </div>
                    </form>
                  </div>
                </div>
              </div>
              <llps-table
                id="protein-table"
                :data="response.data.proteins"
                :canonical-id="response.data.canonical_id"
                :map="response.data.protein_confidence_score"
                :is-experimental="response.data.is_experimental"
                :pubmed="response.data.protein_pubmed_ids"
                :db-tags="response.data.protein_source_db_tags"
              >
              </llps-table>
             <!-- <fetch-user-specific-update-items :id="response.data.canonical_id">
                <template slot-scope="{ response, loading }">
          <slot :response="response" :loading="loading">
            <div v-if="loading || response === null">Loading...</div>
            <div v-else>
                 <h4 class="round">Requests</h4>
             <condensate-update-items-table id="condensateUpdateItem" :data="response" />
                </div>
          </slot>
        </template>
             </fetch-user-specific-update-items> -->
               <h4 class="round">Requests</h4>
             <condensate-update-items-table id="condensateUpdateItem" :data="response.data.canonical_id" />
         
              <!-- <request-update-item-table
                id="protein-table"
                :data="response.data.proteins"
              /> -->
              <!--                            {{response.data.experiments}}-->
              <!--<div class="panel panel-default">-->
              <!--<table class="csi table table-hover table-responsive">-->
              <!--<thead>-->
              <!--<tr class="active">-->
              <!--<th>Name</th>-->
              <!--<th>Species</th>-->
              <!--<th>Uniprot</th>-->
              <!--<th>Sequence</th>-->
              <!--</tr>-->
              <!--</thead>-->
              <!--<tbody>-->
              <!--<tr v-for="(item, index) in response.data.llps_ptms" v-bind:key="index">-->
              <!--<td class="col-sm-6">{{item.name}}</td>-->
              <!--<td>{{item.species_name}}</td>-->
              <!--<td>{{item.uniprot_id}}</td>-->
              <!--<td>-->
              <!--<input type="text" :value="item.sequence">-->
              <!--<button class="copy-button" :name="'item.uniprot_id'" :id="'item.uniprot_id'" :data-clipboard-text="item.sequence">Copy</button>-->
              <!--</td>-->
              <!--</tr>-->
              <!--</tbody>-->
              <!--</table>-->
              <!--</div>-->

              <!--<h4 class="round">Additional Information</h4>-->
              <!--<div class="panel panel-default">-->
              <!--<div class="panel-body">-->
              <!--<div class="row">-->
              <!--<div class="text col-sm-3">Proteins</div>-->
              <!--<div class="col-sm-9">-->
              <!--{{response.data.proteins}}-->
              <!--</div>-->
              <!--</div>-->
              <!--</div>-->
              <!--</div>-->
            </div>
          </slot>
        </template>
      </fetch-condensate>
    </div>
  </div>
  <!-- /#wrapper -->
</template>

<script>
import fetchCondensate from "@/components/DDCODE/fetchCondensate.vue";
import llpsTable from "@/components/LlpsTable.vue";
import fetchPubMed from "@/components/DDCODE/fetchPubMed";
import AddDeleteMarker from "./CMS/addDeleteMarker.vue";

import CondensateUpdateItemsTable from './CondensateUpdateItemsTable.vue';
//import FetchUserSpecificUpdateItems from './CMS/fetchUserSpecificUpdateItems.vue';

//import RequestUpdateItemTable from "./RequestUpdateItemTable.vue";
// import TheModal from './UI/TheModal.vue';
const _ = require("lodash");
require("./js/clipboard");

let host = require("./js/const").apiHost;

export default {
  name: "CondensateDetailPage",
  components: {
    fetchCondensate,
    llpsTable,
    fetchPubMed,
    AddDeleteMarker,
    
    CondensateUpdateItemsTable,
    // FetchUserSpecificUpdateItems,

    // RequestUpdateItemTable,
  },
  props: ["condensateId"],
  data() {
    return {
      condensate: this.$route.params.condensate
        ? this.$route.params.condensate
        : this.condensateId,
      dbNames: require("./js/const").db,
      isDev: process.env.NODE_ENV === "development",
      showAddProtein: false,
      uniprotId: "",
      comment: "",
      description: "",
      descriptionMsg: "",
      descriptionErrorMsg: "",
      isUniProtIdError: false,
      isCommentError: false,
      isSubmitted: false,
      error: false,
      showUpdateDescription: false,
      showAddDeleteMarker: false,
      commentErrorMsg: "",
      uniprotIdErrorMsg: "",
      message: "",
      whitespaceRegex: /(\s)/,
      toggleModel: false,
    };
  },
  computed: {
    jwt: function () {
      return this.$store.getters["User/jwt"];
    },
    getUserData() {
      const userRole = this.$store.getters["User/userRole"];

      return userRole;
    },
  },

  methods: {
    confirm() {
      this.toggleModel = false;
    },
    cancel() {
      this.toggleModel = false;
    },
    closeAddDeleteMarker() {
      this.comment = "";
      this.showAddDeleteMarker = false;
    },
    uniprotKeyup() {
      this.message = "";
      this.isUniProtIdError = false;
    },
    commentKeyup() {
      this.message = "";
      this.isCommentError = false;
    },
    descriptionKeyup() {
      this.descriptionMsg = "";
      this.descriptionErrorMsg = "";
    },
    toggleUpdateDescription(res) {
      this.description = res;
      this.descriptionMsg = "";
      this.descriptionErrorMsg = "";
      this.comment = "";
      this.showUpdateDescription = !this.showUpdateDescription;
    },

    async updateDescription(response) {
      if (this.description === "") {
        this.descriptionErrorMsg = "Description should not be empty!";
        return;
      } else if (this.description === response.data.description) {
        this.descriptionErrorMsg =
          "You have not added any description. Please modify the existing description.";
        this.descriptionMsg = "";
        return;
      }

      if (this.isDev) {
        host = require("./js/const").devApiHost;
      }
      let url = `${host}/api/update-items`;
      let data;
      if (this.getUserData === "Maintainer") {
        data = {
          Entity: "condensate",
          EntityId: response.data.canonical_id,
          ChangeOperation: "update",
          Attribute: "description",
          Value: this.description,
          SubmissionComments: this.comment,
          Status: "accepted",
        };
      } else {
        if (this.comment === "") {
          this.isCommentError = true;
          this.commentErrorMsg = "Reason should not be empty!";
          return;
        }
        data = {
          Entity: "condensate",
          EntityId: response.data.canonical_id,
          ChangeOperation: "update",
          Attribute: "description",
          Value: this.description,
          SubmissionComments: this.comment,
          Status: "requested",
        };
      }

      try {
        await this.axios.post(
          url,
          { data: data },
          {
            headers: {
              Authorization: `Bearer ${this.jwt}`,
            },
          }
        );
        this.descriptionMsg = "Request submitted successfully!";
        this.descriptionErrorMsg = "";
        this.description = response.data.description;
        this.commentErrorMsg = "";
        this.comment = "";
        this.isCommentError = false;
      } catch (e) {
        console.error(e);
        this.descriptionMsg = "";
        this.descriptionErrorMsg =
          e.message || "Something went wrong, please try again later!";
      }
    },
    async addProtein(response) {
      if (this.uniprotId === "") {
        this.uniprotIdErrorMsg = "Uniprot ID should not be emplty!";
        this.isUniProtIdError = true;
        return;
      } else if (this.uniprotId.length < 6) {
        this.uniprotIdErrorMsg = "Uniprot ID should be minimum of 6 character.";
        this.isUniProtIdError = true;
        return;
      } else if (this.uniprotId.length > 10) {
        this.uniprotIdErrorMsg =
          "Uniprot ID should be maximum of 10 character.";
        this.isUniProtIdError = true;
        return;
      } else if (this.whitespaceRegex.test(this.uniprotId)) {
        this.uniprotIdErrorMsg = "Uniprot ID should not have space in between.";
        this.isUniProtIdError = true;
        return;
      }

      const findUniprotId = response.data.proteins.find(
        (u) => u.uniprot_id === this.uniprotId
      );
      if (findUniprotId) {
        this.message = "";
        this.uniprotIdErrorMsg = "The Uniprot ID already exists!";
        this.isUniProtIdError = true;
        return;
      }

      this.isError = false;
      if (this.isDev) {
        host = require("./js/const").devApiHost;
      }
      let url = `${host}/api/update-items`;
      let data;
      if (this.getUserData === "Maintainer") {
        data = {
          Entity: "condensate",
          EntityId: response.data.canonical_id,
          ChangeOperation: "add",
          Attribute: "proteins",
          Value: this.uniprotId,
          SubmissionComments: this.comment,
          Status: "accepted",
        };
      } else {
        if (this.comment === "") {
          this.commentErrorMsg = "Reason should not be empty!";
          this.isCommentError = true;
          return;
        }
        data = {
          Entity: "condensate",
          EntityId: response.data.canonical_id,
          ChangeOperation: "add",
          Attribute: "proteins",
          Value: this.uniprotId,
          SubmissionComments: this.comment,
          Status: "requested",
        };
      }

      try {
        await this.axios.post(
          url,
          { data: data },
          {
            headers: {
              Authorization: `Bearer ${this.jwt}`,
            },
          }
        );
        this.message = "Request submitted successfully!";
        this.error = false;
        this.isSubmitted = true;
        this.uniprotId = "";
        this.comment = "";
      } catch (e) {
        console.error(e);
        this.message =
          e.message || "Something went wrong, please try again later!";
        this.isSubmitted = true;
        this.error = true;
      }

      try {
        const res=await this.axios.get(
          `${host}
/api/update-item/findCondensate/${response.data.canonical_id}`,
         
          {
            headers: {
              Authorization: `Bearer ${this.jwt}`,
            },
          }
        );

      console.log(await res)
       
      } catch (e) {
        console.error(e);
       
      }
    },

    // async getRequest() {
    //   if (this.isDev) {
    //     host = require("./js/const").devApiHost;
    //   }
    //   let url = `${host}/api/update-items`;
    //   try {
    //     const response = await this.axios.get(
    //       url,

    //       {
    //         headers: {
    //           Authorization: `Bearer ${this.jwt}`,
    //         },
    //       }
    //     );
    //     return response.data.data;
    //   } catch (e) {
    //     console.error(e);
    //     this.message =
    //       e.message || "Something went wrong, please try again later!";
    //     this.isSubmitted = true;
    //     this.error = true;
    //   }
    // },

    // async getSumittedRequest() {
    //   const requestData = await this.getRequest();
    //   console.log("get req", requestData);
    // },

    getProteinLinks(uniprots) {
      if (uniprots)
        return uniprots
          .map((a) => `<a href='/protein/${a}' target='_blank'>${a}</a>`)
          .join(", ");
      else return "";
    },
    getDbNames(names) {
      return _.map(names, (i) => this.dbNames[i]).join(", ");
    },
    getTitleAuthors(title, data) {
      return `${title}\n\n${_.map(data, (a) => a.name).join(", ")}`;
    },
    tokenize(input, token) {
      return input.replaceAll(token, "<br/>");
    },
    getRating(data) {
      const scoreMap = { hungarian: 5, blue: 5, pink: 1, grey: 1 };

      const rating = _.max(_.map(data, (i) => scoreMap[i]));
      const r = [];
      for (let i = 0; i < 5; i++) {
        if (i < rating) {
          r.push("fa fa-star checked");
        } else {
          r.push("fa fa-star");
        }
      }
      return r;
    },
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
@import url("~@/assets/bootstrap.css");
@import url("~@/assets/datatable.css");
@import url("~@/assets/tooltip.css");

.main {
  /*margin-left: 200px;*/
  margin-left: 20px;
}

h3 {
  margin: 40px 0 0;
}

a {
  color: #42b983;
}

#wrapper {
  overflow-x: hidden;
}

.checked {
  color: orange;
}

#sidebar-wrapper {
  min-height: 100vh;
  margin-left: -15rem;
  -webkit-transition: margin 0.25s ease-out;
  -moz-transition: margin 0.25s ease-out;
  -o-transition: margin 0.25s ease-out;
  transition: margin 0.25s ease-out;

  position: absolute;
  z-index: 1; /* Stay on top */
  left: 0;
}

#sidebar-wrapper .sidebar-heading {
  padding: 0.875rem 1.25rem;
  font-size: 1.2rem;
}

#sidebar-wrapper .list-group {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  width: 15rem;
}

#page-content-wrapper {
  min-width: 100vw;
}

#wrapper.toggled #sidebar-wrapper {
  margin-left: 0;
}

@media (min-width: 768px) {
  #sidebar-wrapper {
    margin-left: 0;
  }

  #page-content-wrapper {
    min-width: 0;
    width: 100%;
  }

  #wrapper.toggled #sidebar-wrapper {
    margin-left: -15rem;
  }
}

.d-flex {
  display: -ms-flexbox !important;
  display: flex !important;
}

.panel {
  font-size: 1.2rem;
}

.table-dark {
  color: #fff;
  background-color: #212529;
}
</style>