GitHub Issues

40 of 122
Github Issues demo demonstrates how easy it is setup ZingGrid to create, read, update, and delete issues through a few zg-param's. You can view the github repository for the issues here.
Result Full HTML CSS JS
Edit Download
Github Issues Demo+ Add Issue;

Full Code

<!DOCTYPE html>
<html class="zg-html">

<head>
  <meta charset="utf-8">
  <title>ZingGrid: Github Issues Demo</title>
  <base target="_blank">
  <script src="https://cdn.zinggrid.com/zinggrid.min.js" defer></script>
  <style>
    .zg-body {
      background: #fff;
    }

    /* Button */

    .zg-body .button {
      background: #2B98F0;
      border: none;
      border-radius: 2px;
      color: #fff;
      cursor: pointer;
      height: 33px;
      font-size: .875rem;
      padding: .5rem .625rem;
      text-transform: uppercase;
    }

    .zg-body .button zg-icon {
      display: none;
    }

    .zg-body .button:hover {
      background: #1b6ead;
    }

    /* Comments */

    .zg-body .comment {
      color: #586069;
      fill: #586069;
      text-decoration: none;
    }

    .zg-body .comment:hover,
    .zg-body .title:hover {
      color: #0366d6;
      fill: #0366d6;
    }

    .zg-body .comment--svg {
      position: relative;
      top: 5px;
    }

    /* Status */

    .zg-body .hide {
      position: absolute;
      opacity: 0;
      pointer-events: none;
    }

    .zg-body .open,
    .zg-body .closed {
      cursor: pointer;
      min-width: 14px;
    }

    .zg-body .open {
      fill: #28a745;
    }

    .zg-body .closed {
      fill: #cb2431;
    }

    /* Title/Subtitle */

    .zg-body .subtitle {
      color: #586069;
      margin-top: 0.25rem;
      font-size: 0.75rem;
    }

    .zg-body .title {
      font-size: 1rem;
      font-weight: 600;
    }

    /* ZingGrid Overwrites */

    zg-body,
    zg-body zg-row:first-child {
      border-top: 0;
    }

    zg-caption {
      border-bottom: 1px solid #e1e4e8;
      border-radius: .28571429rem .28571429rem 0 0;
    }

    zg-caption .button {
      margin: 15px 0 15px 15px;
    }

    zg-head {
      display: none;
    }

    zing-grid {
      border-radius: .28571429rem;
      border: 1px solid rgba(34, 36, 38, .1);
      --zg-caption-background: #f6f8fa;
      --zg-caption-border-bottom: 0;
      --zg-caption-color: #000;
      --zg-caption-font-size: 0.9rem;
      --zg-caption-font-weight: bold;
      --zg-caption-height: 3.5rem;
      --zg-cell-padding: 0.5rem 1rem;
      --zg-row-background_hover: #F6F8FA;
      --zg-watermark-background: transparent;
      --zg-watermark-border: 0;
      --zing-grid-border: 0;
    }

    zing-grid[loading] {
      height: 393px;
    }
  </style>
</head>

<body class="zg-body">
  <!-- ZingGrid -->
  <zing-grid editor="modal" height="300" layout="row" layout-controls="disabled">
    <zg-caption>
      Github Issues Demo
      <zg-button class="button" action="createrecord">+ Add Issue</zg-button>
    </zg-caption>
    <zg-card editor-template="editorTemplate"></zg-card>
    <zg-colgroup>
      <zg-column index="state" type="toggle" renderer="renderState" type-toggle-options='["open", "close"]' width="30px"></zg-column>
      <zg-column index="title" hidden></zg-column>
      <zg-column index="title, number, created_at, user" editor="false" renderer="renderTitle" width="30%"></zg-column>
      <zg-column index="body" editor-template="editorTemplate"></zg-column>
      <zg-column index="comments, html_url" editor="false" renderer="renderComment" width="75px"></zg-column>
    </zg-colgroup>
    <zg-data>
      <zg-param name="headers" value='{"Authorization": "token 288483a06d7ca33d9abfaf5cfda1dda99c5c23da"}'></zg-param>;
      <zg-param name="idKey" value="number"></zg-param>
      <zg-param name="src" value="https://api.github.com/repos/zgdemo123/zgtest/issues"></zg-param>
    </zg-data>
  </zing-grid>

  <!-- Editor Template -->
  <template id="editorTemplate">
      <div class="custom-editor">
        <label for="title" style="color:#949494; font-size:12px; margin:0 0 5px 20px;">Title</label>
        <input type="text" name="title" value="[[record.title]]" style="margin-left:20px;">
        <label for="body" style="color:#949494; font-size:12px; margin:20px 0 5px 20px;">Body</label>
        <input type="text" name="title" value="[[record.body]]" style="margin:0 0 64px 20px;">
      </div>
    </template>
  <script>
    const MONTH = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

    window.addEventListener('load', () => {
      let zgRef = document.querySelector('zing-grid');
      zgRef.executeOnLoad(() => {
        // Listener to refresh grid to render newly added row
        zgRef.addEventListener('data:record:insert', () => {
          setTimeout(() => {
            zgRef.refresh();
          }, 0);
        });
      });
    });

    // Display time based on how long ago
    function formatCreatedAt(date) {
      let dateObj = new Date(date);
      let month = dateObj.getMonth();
      let day = dateObj.getDate();
      let curDateObj = new Date();
      let curMonth = curDateObj.getMonth();
      let curDay = curDateObj.getDate();
      let time = null;
      // Within same day
      if (month === curMonth && day === curDay) {
        let hour = dateObj.getHours();
        let curHour = curDateObj.getHours();
        let diff = Math.abs(hour - curHour);
        if (hour !== curHour) time = `${diff} hour${diff === 1 ? '' : 's'} ago`;
        else { // Created just now
          let min = dateObj.getMinutes();
          let curMin = curDateObj.getMinutes();
          let diff = Math.abs(min - curMin);
          if (min !== curMin) time = `${diff} minute${diff === 1 ? '' : 's'} ago`;
          else time = `just now`;
        }
      } else if (month === curMonth && day !== curDay) {
        // Created within the month
        let diff = Math.abs(day - curDay);
        time = `${diff} day${diff === 1 ? '' : 's'} ago`;
      } else time = `on ${MONTH[month]} ${day}`;
      return time;
    }

    // Render title and subtitle
    var renderTitle = (title, number, created_at, user) => `<div class="title">${title}</div>
  <div class="subtitle">#${number} opened ${formatCreatedAt(created_at)} by ${user.login}`;

    // Render icon for 'state' column
    function renderState(curVal, $cell) {
      const OPEN = '<svg class="open" width="14" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"/></svg>';
      const CLOSED = '<svg class="closed" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7 10h2v2H7v-2zm2-6H7v5h2V4zm1.5 1.5l-1 1L12 9l4-4.5-1-1L12 7l-1.5-1.5zM8 13.7A5.71 5.71 0 0 1 2.3 8c0-3.14 2.56-5.7 5.7-5.7 1.83 0 3.45.88 4.5 2.2l.92-.92A6.947 6.947 0 0 0 8 1C4.14 1 1 4.14 1 8s3.14 7 7 7 7-3.14 7-7l-1.52 1.52c-.66 2.41-2.86 4.19-5.48 4.19v-.01z"/></svg>';
      if (curVal === 'open') {
        return OPEN;
      } else {
        return CLOSED;
      }
    }

    // Render linked icon for 'comment' column if issue contains comments
    function renderComment(num, url) {
      // Return if no comments to render
      if (num === 0) return;
      // Render with clickable icon that links to comment
      return `<a class="comment" href="${url}">
    <svg class="comment--svg" width="16" height="16" aria-hidden="true">
      <path fill-rule="evenodd" d="M14 1H2c-.55 0-1 .45-1 1v8c0 .55.45 1 1 1h2v3.5L7.5 11H14c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 9H7l-2 2v-2H2V2h12v8z"/>
    </svg>
    <span class="comment--num">${num}</span>
  </a>`;
    }
  </script>
</body>

</html>
<!DOCTYPE html>
<html class="zg-html">
  <head>
    <meta charset="utf-8">
    <title>ZingGrid: Github Issues Demo</title>
    <base target="_blank">
    <script src="https://cdn.zinggrid.com/zinggrid.min.js" defer></script>
	</head>
  <body class="zg-body">
    <!-- ZingGrid -->
    <zing-grid editor="modal" height="300" layout="row" layout-controls="disabled">
      <zg-caption>
        Github Issues Demo
        <zg-button class="button" action="createrecord">+ Add Issue</zg-button>
      </zg-caption>
      <zg-card editor-template="editorTemplate"></zg-card>
      <zg-colgroup>
        <zg-column index="state" type="toggle" renderer="renderState" type-toggle-options='["open", "close"]' width="30px"></zg-column>
        <zg-column index="title" hidden></zg-column>
        <zg-column index="title, number, created_at, user" editor="false" renderer="renderTitle" width="30%"></zg-column>
        <zg-column index="body" editor-template="editorTemplate"></zg-column>
        <zg-column index="comments, html_url" editor="false" renderer="renderComment" width="75px"></zg-column>
      </zg-colgroup>
      <zg-data>
        <zg-param name="headers" value='{"Authorization": "token 288483a06d7ca33d9abfaf5cfda1dda99c5c23da"}'></zg-param>;
        <zg-param name="idKey" value="number"></zg-param>
        <zg-param name="src" value="https://api.github.com/repos/zgdemo123/zgtest/issues"></zg-param>
      </zg-data>
    </zing-grid>

    <!-- Editor Template -->
    <template id="editorTemplate">
      <div class="custom-editor">
        <label for="title" style="color:#949494; font-size:12px; margin:0 0 5px 20px;">Title</label>
        <input type="text" name="title" value="[[record.title]]" style="margin-left:20px;">
        <label for="body" style="color:#949494; font-size:12px; margin:20px 0 5px 20px;">Body</label>
        <input type="text" name="title" value="[[record.body]]" style="margin:0 0 64px 20px;">
      </div>
    </template>
  </body>
</html>
.zg-body{
  background:#fff;
}

/* Button */
.zg-body .button {
  background: #2B98F0;
  border: none;
  border-radius: 2px;
  color: #fff;
  cursor: pointer;
  height: 33px;
  font-size: .875rem;
  padding: .5rem .625rem;
  text-transform: uppercase;
}
.zg-body .button zg-icon {
  display: none;
}
.zg-body .button:hover {
  background: #1b6ead;
}

/* Comments */
.zg-body .comment {
  color: #586069;
  fill: #586069;
  text-decoration: none;
}
.zg-body .comment:hover,
.zg-body .title:hover {
  color: #0366d6;
  fill: #0366d6;
}
.zg-body .comment--svg {
  position:relative;
  top:5px;
}

/* Status */
.zg-body .hide {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.zg-body .open,
.zg-body .closed {  
  cursor: pointer;
  min-width: 14px;
}
.zg-body .open { 
  fill: #28a745;
}
.zg-body .closed { 
  fill: #cb2431;
}

/* Title/Subtitle */
.zg-body .subtitle {
  color: #586069;
  margin-top: 0.25rem;
  font-size: 0.75rem;
}
.zg-body .title {
  font-size: 1rem;
  font-weight: 600;
}

/* ZingGrid Overwrites */
zg-body,
zg-body zg-row:first-child {
  border-top: 0;
}

zg-caption {
  border-bottom: 1px solid #e1e4e8;
  border-radius: .28571429rem .28571429rem 0 0;
}
zg-caption .button {
  margin: 15px 0 15px 15px;
}

zg-head{ 
  display:none; 
}

zing-grid { 
  border-radius: .28571429rem;
  border: 1px solid rgba(34,36,38,.1);

  --zg-caption-background: #f6f8fa;
  --zg-caption-border-bottom: 0;
  --zg-caption-color: #000;
  --zg-caption-font-size: 0.9rem;
  --zg-caption-font-weight: bold;
  --zg-caption-height: 3.5rem;
  --zg-cell-padding: 0.5rem 1rem;
  --zg-row-background_hover: #F6F8FA;
  --zg-watermark-background: transparent;
  --zg-watermark-border: 0;
  --zing-grid-border: 0;
}
const MONTH = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

window.addEventListener('load', () => {
  let zgRef = document.querySelector('zing-grid');
  zgRef.executeOnLoad(() => {
    // Listener to refresh grid to render newly added row
    zgRef.addEventListener('data:record:insert', () => {
      setTimeout(() => {
        zgRef.refresh();
      }, 0);
    });
  });
});

// Display time based on how long ago
function formatCreatedAt(date) {
  let dateObj = new Date(date);
  let month = dateObj.getMonth();
  let day = dateObj.getDate();
  let curDateObj = new Date();
  let curMonth = curDateObj.getMonth();
  let curDay = curDateObj.getDate();
  let time = null;
  // Within same day
  if (month === curMonth && day === curDay) {
    let hour = dateObj.getHours();
    let curHour = curDateObj.getHours();
    let diff = Math.abs(hour-curHour);
    if (hour !== curHour) time = `${diff} hour${diff === 1 ? '' : 's'} ago`;
    else { // Created just now
      let min = dateObj.getMinutes();
      let curMin = curDateObj.getMinutes();
      let diff = Math.abs(min-curMin);
      if (min !== curMin) time = `${diff} minute${diff === 1 ? '' : 's'} ago`;
      else time = `just now`;
    }
  } else if (month === curMonth && day !== curDay) {
    // Created within the month
    let diff = Math.abs(day-curDay);
    time = `${diff} day${diff === 1 ? '' : 's'} ago`;
  } else time = `on ${MONTH[month]} ${day}`;
  return time;
}

// Render title and subtitle
var renderTitle = (title, number, created_at, user) => `<div class="title">${title}</div>
  <div class="subtitle">#${number} opened ${formatCreatedAt(created_at)} by ${user.login}`;

// Render icon for 'state' column
function renderState(curVal, $cell) {
  const OPEN = '<svg class="open" width="14" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"/></svg>';
  const CLOSED = '<svg class="closed" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7 10h2v2H7v-2zm2-6H7v5h2V4zm1.5 1.5l-1 1L12 9l4-4.5-1-1L12 7l-1.5-1.5zM8 13.7A5.71 5.71 0 0 1 2.3 8c0-3.14 2.56-5.7 5.7-5.7 1.83 0 3.45.88 4.5 2.2l.92-.92A6.947 6.947 0 0 0 8 1C4.14 1 1 4.14 1 8s3.14 7 7 7 7-3.14 7-7l-1.52 1.52c-.66 2.41-2.86 4.19-5.48 4.19v-.01z"/></svg>';
  if (curVal === 'open') {
    return OPEN;
  } else {
    return CLOSED;
  }
}

// Render linked icon for 'comment' column if issue contains comments
function renderComment(num, url) {
  // Return if no comments to render
  if (num === 0) return;
  // Render with clickable icon that links to comment
  return `<a class="comment" href="${url}">
    <svg class="comment--svg" width="16" height="16" aria-hidden="true">
      <path fill-rule="evenodd" d="M14 1H2c-.55 0-1 .45-1 1v8c0 .55.45 1 1 1h2v3.5L7.5 11H14c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 9H7l-2 2v-2H2V2h12v8z"/>
    </svg>
    <span class="comment--num">${num}</span>
  </a>`;
}

Interested in this demo? Modify it to your needs in ZingSoft Studio, our testing sandbox. It's free to sign up, and you can come back and edit at any time!

Edit in Studio

Demo Gallery