Skip to content

Commit

Permalink
Merge pull request #74 from contentstack/staging
Browse files Browse the repository at this point in the history
Add Content Type Visualizer and Developer Tool extensions to our public Github repository [ECO-656]
  • Loading branch information
karantalapalli authored May 5, 2022
2 parents c7e8947 + 6b8b705 commit b2ef097
Show file tree
Hide file tree
Showing 14 changed files with 2,093 additions and 0 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,19 @@ This widget uses the Google Analytics data to display the traffic analysis and s
[Optimizely Experiments](./optimizely-experiments):
This extension lets you retrieve and display Optimizely Experiments and their details in your entry.

[Developer Tools](./developer-tools):
This widget extension provides developers with quick tools (API endpoint, JSON, etc.) to work with an entry or all entries of a content type and do a lot more.

### Examples of dashboard widgets created using Extensions

Here are some examples/use cases of dashboard widgets that can be created using Extensions. These examples come with readme files that explain how to install and get started with these widgets.

[Google Analytics](./dashboard-widget-google-analytics):
This dashboard widget uses the Google Analytics data to display the traffic analysis and statistics of your site on the stack dashboard.

[Content Type Visualizer](./content-type-visualizer):
Content Type Visualizer Dashboard Widget offers a graphical representation of all content types, along with their fields, in a particular stack.

### Examples of JSON RTE Plugin created using Extensions

Here are some examples/use cases of JSON RTE Plugin that can be created using Extensions. These examples come with readme files that explain how to install and get started with these plugins.
Expand Down
18 changes: 18 additions & 0 deletions content-type-visualizer/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"env": {
"browser": true,
"es6": true,
"jquery": true
},
"extends": "airbnb-base/legacy",
"parserOptions": {
"ecmaVersion": 2016,
"sourceType": "module"
},
"globals": {
"ContentstackUIExtension": false
},
"rules": {
"no-restricted-syntax": ["error", "LabeledStatement", "WithStatement"]
}
}
4 changes: 4 additions & 0 deletions content-type-visualizer/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.log
.cache
package-lock.json
node_modules
21 changes: 21 additions & 0 deletions content-type-visualizer/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2020 Contentstack

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
30 changes: 30 additions & 0 deletions content-type-visualizer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Content Type Visualizer – Contentstack Extension

#### About this extension.
Content Type Visualizer Dashboard Widget offers a graphical representation of all content types, along with their fields, in a particular stack.

![Content Type Visualizer Screenshot](https://images.contentstack.io/v3/assets/blt83726f918894d893/bltae909a9786341bbf/5f394a3ddb5c28785b6f048d/content-type-visualizer.png)


#### How to use this extension
We have created a step-by-step guide on how to create a Content Type Visualizer extension for your content types. You can refer the [Content Type Visualizer extension guide](https://www.contentstack.com/docs/developers/create-dashboard-widgets/content-type-visualizer-dashboard-widget/) on our documentation site for more info.


#### Other Documentation
- [Extensions guide](https://www.contentstack.com/docs/guide/extensions)
- [Common questions about extensions](https://www.contentstack.com/docs/faqs#extensions)


#### Modifying Extension

To modify the extension, first clone this repo and install the dependencies. Then, edit the HTML, CSS and JS files from the source folder, and create a build using gulp task.

To install dependencies, run the following command in the root folder
```
npm install gulp-cli -g
npm install
```
To create new build for the extension, run the following command (index.html):

gulp build

50 changes: 50 additions & 0 deletions content-type-visualizer/gulpfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const gulp = require('gulp');
const inline = require('gulp-inline');
const uglify = require('gulp-uglify');
const gulpStylelint = require('gulp-stylelint');
const minifyCss = require('gulp-clean-css');
const babel = require('gulp-babel');
const eslint = require('gulp-eslint');


gulp.task('lint-js', () => {
return gulp.src('source/*.js')
.pipe(eslint())
.pipe(eslint.format())
.pipe(eslint.failAfterError());
});

gulp.task('lint-css', () => {
return gulp
.src('source/*.css')
.pipe(gulpStylelint({
config: {
extends: 'stylelint-config-standard'
},
reporters: [{
formatter: 'string',
console: true
}],
failAfterError: false
}));
});

gulp.task('inline', () => {
return gulp.src('./source/index.html')
.pipe(inline({
js: [babel({
presets: ["@babel/preset-env"]
}), uglify],
css: [minifyCss],
disabledTypes: ['svg', 'img']
}))
.pipe(gulp.dest('./'));
});

gulp.task('build', gulp.series('lint-js', 'lint-css', 'inline'));

gulp.task('watch', () => {
gulp.watch('source/*', gulp.series('build'));
});

gulp.task('default', gulp.series('build'));
160 changes: 160 additions & 0 deletions content-type-visualizer/index.html

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions content-type-visualizer/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "@contentstack/extension-custom-dashboard-content-type-visualizer",
"version": "1.0.0",
"description": "A diagrammatic representation of all content types in a stack.",
"main": "gulpfile.js",
"scripts": {
"build": "npx gulp build"
},
"author": "Contentstack",
"license": "MIT",
"devDependencies": {
"@babel/cli": "7.5.0",
"@babel/core": "7.5.4",
"@babel/preset-env": "7.5.4",
"eslint": "^5.6.0",
"eslint-config-airbnb-base": "13.1.0",
"gulp": "4.0.0",
"gulp-babel": "8.0.0",
"gulp-clean-css": "4.2.0",
"gulp-eslint": "6.0.0",
"gulp-inline": "0.1.3",
"gulp-stylelint": "7.0.0",
"gulp-uglify": "3.0.0",
"stylelint": "13.2.0",
"stylelint-config-standard": "20.0.0"
}
}
179 changes: 179 additions & 0 deletions content-type-visualizer/source/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
<!doctype html>
<html>

<head>
<meta charset="UTF-8">
<title>External API UI Extension Sample</title>
<link rel="stylesheet" href="https://unpkg.com/@contentstack/[email protected]/dist/ui-extension-sdk.css"
type="text/css" media="all">
<script src="https://unpkg.com/@contentstack/[email protected]/dist/ui-extension-sdk.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jsPlumb/2.15.6/css/jsplumbtoolkit-defaults.css"
integrity="sha512-jd/fOFC21187laNAUa3jXsPbm9L25MSscoZ/v/t6fznpllp0KOgEDwBabuvRr/gNT7VlRfZz9ItshGbmAXMy8g=="
crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-jsonview/1.2.3/jquery.jsonview.css"
integrity="sha512-6dqKyKlSER24gVyNQkP3cUfIaA5OfAEHxDBRiElKxSmlZTTdY6Z7uiUW5pADcTzqjEmli6Dv+IuTPsMLuFPeBg=="
crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="stylesheet" href="style.css">
<script type="text/javascript" src="https://code.jquery.com/jquery-1.x-git.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsPlumb/2.15.6/js/jsplumb.js"
integrity="sha512-Apg1ZeuGs7Z8jiTHs9sonPBemcCMlYprJUOTbT8ytsTaFrAXnBmmmgFsvl2bBUONW26L/5eY9RPhrprozxEhXA=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js"
integrity="sha512-RNLkV3d+aLtfcpEyFG8jRbnWHxUqVZozacROI4J2F1sTaDqo1dPQYs01OMi1t1w9Y2FdbSCDSQ2ZVdAC8bzgAg=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"
integrity="sha512-uto9mlQzrs59VwILcLiRYeLKPPbS/bT71da/OEBYEwcdNUk8jYIy+D176RYoop1Da+f9mvkYrmj5MCLZWEtQuA=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"
integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG+ljU96qKRCWh+quCY7yefSmlkQw1ANQ=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dagre/0.8.5/dagre.min.js"
integrity="sha512-psLUZfcgPmi012lcpVHkWoOqyztollwCGu4w/mXijFMK/YcdUdP06voJNVOJ7f/dUIlO2tGlDLuypRyXX2lcvQ=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.panzoom/3.2.3/jquery.panzoom.min.js"
integrity="sha512-Qa/wLxf5ZtzGUcPBlaRGJhvXe2vDq2LwnXMVdyFdETpI7RnPT6du7XEP2qA4/ZOPywzUdF6eBoq7A7wz9X+5jg=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-jsonview/1.2.3/jquery.jsonview.min.js"
integrity="sha512-ff/E/8AEnLDXnTCyIa+l80evPRNH8q5XnPGY/NgBL645jzHL1ksmXonVMDt7e5D34Y4DTOv+P+9Rmo9jBSSyIg=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.10/clipboard.min.js"
integrity="sha512-PIisRT8mFfdxx99gMs7WAY5Gp+CtjYYxKvF93w8yWAvX548UBNADHu7Qkavgr6yRG+asocqfuk5crjNd5z9s6Q=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</head>

<body>
<div class="parent-container">
<div class="jtk-surface container" id="canvas">
<div class="panzoom">
<div id="diagram-placeholder" class="diagram"></div>
</div>
</div>
<div class="content-type-count">
<span>_</span> Content Types
</div>
<div class="refresh" title="Refresh" onclick="refresh()">
<i class="icon-refresh"></i>
</div>
<div class="zoom-container">
<div class="zoom-btns">
<button title="Zoom in" type="button" class="zoom-in">
<img
src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2218%22%20height%3D%2218%22%20viewBox%3D%220%200%2018%2018%22%3E%0A%20%20%3Cpolygon%20fill%3D%22%23666%22%20points%3D%2218%2C7%2011%2C7%2011%2C0%207%2C0%207%2C7%200%2C7%200%2C11%207%2C11%207%2C18%2011%2C18%2011%2C11%2018%2C11%22%2F%3E%0A%3C%2Fsvg%3E%0A">
</button>
<div class="divider"></div>
<button title="Zoom out" type="button" class="zoom-out">
<img
src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2218%22%20height%3D%2218%22%20viewBox%3D%220%200%2018%2018%22%3E%0A%20%20%3Cpath%20fill%3D%22%23666%22%20d%3D%22M0%2C7h18v4H0V7z%22%2F%3E%0A%3C%2Fsvg%3E%0A">
</button>
</div>
</div>
<div class="sidebar">
<div class="rotate new-icon toggle">
<img src="https://new-static.contentstack.io/images/breadcrumb-carat-icon.svg" class="">
</div>
<div class="json-viewer">
<span class="title">JSON View</span>
<a class="edit-icon" href="" target="_blank"></a>
<span class="count">Field count: 0</span>
<div class="form-group">
<select id="environments" class="form-control">
<option value="default" disabled>Select Environment</option>
</select>
<span id="entry-count">Entry count: _</span>
</div>
<div class="json">
<button class="btn copy-btn">Copy</button>
<div id="json-collapsed"></div>
</div>
</div>
</div>
<script id="partial" type="text/x-handlebars-template">
{{# each this.schema}}
{{!-- Start Group IF --}}
{{#if_eq data_type 'group'}}

<ul class="group">
<li>
<div class="icon"><img src="{{fieldIcon data_type field_metadata display_type}}" alt="" /></div>
<div class="name">{{display_name}}</div>
<div class="type">{{data_type}}</div>
</li>
{{> list}}
</ul>

{{else}}
{{!-- Start Global Field IF --}}
{{#if_eq data_type 'global_field'}}

<ul class="global-field">
<li>
<div class="icon"><img src="{{fieldIcon data_type field_metadata display_type}}" alt="" /></div>
<div class="name">{{display_name}}
<span class="tooltiptext">{{uid}}</span>
</div>
<div class="type">{{data_type}}</div>
</li>
{{> list}}
</ul>

{{else}}
{{!-- Start Modular Block IF --}}
{{#if_eq data_type 'blocks'}}
<ul class="modular-block">
<li>
<div class="icon"><img src="{{fieldIcon data_type field_metadata display_type}}" alt="" /></div>
<div class="name">{{display_name}}
<span class="tooltiptext">{{uid}}</span>
</div>
<div class="type">{{data_type}}</div>
</li>
{{#blocks}}
{{> list}}
{{/blocks}}
</ul>
{{else}}
<li>
<div class="icon"><img src="{{fieldIcon data_type field_metadata display_type}}" alt="" /></div>
<div class="name">{{display_name}}
<span class="tooltiptext">{{uid}}</span>
</div>
<div class="type">{{data_type}}</div>
</li>

{{/if_eq}}
{{!-- End Modular Block IF --}}

{{/if_eq}}
{{!-- End Global Field IF --}}

{{/if_eq}}
{{!-- End Group IF --}}
{{/each}}
</script>

<script id="diagram-template" type="text/x-handlebars-template">
{{#each diagramData}}
<div class="window tab" id="{{uid}}">
<div class="heading">
<a href="{{contentTypeBuilderUrl uid}}" target="_blank">{{title}}</a>
<i class="icon-eye-open" data-id="{{uid}}" title="Json preview"></i>
</div>
<ul class="tab-content">
{{> list}}
</ul>
</div>
{{/each}}
</script>
</div>
<div class="reference-loading">
<div class="loading-flash">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
<script src="index.js"></script>
</body>

</html>
Loading

0 comments on commit b2ef097

Please sign in to comment.