Skip to content

Commit

Permalink
WIP: V1 Samples (tableau#13)
Browse files Browse the repository at this point in the history
* Added Settings Sample

* added datasource sample

* cleanup

* moved from innerHTML to jquery.text()

* added missing gitignore and removed nod_modules

* Added semistandard linter

* Fixed tslint errors for settings and datasources

* added 0.6.1 with parameter id change

* updating to use 0.6.1

* added filtering sample

* Parameters sample no REACT. (tableau#16)

* removing old images and updating Flex

* Fetching is complete

* Fix style issues

* parity with original demo, but uglier

* Address code review feedback

* moving to wrapping everything into an anonymous function

* Initial tutorial (tableau#17)

* Initial checkin

* Initial react checkin

* Progressing along

* Paste in old readme

* React progress

* Eventing

* Complete functionality

* Switch to modal

* Add loading screens

* readme updates

* Part 0 with links

* Part 1 readme

* Fix links

* More tutorials

* Part 3 readme

* Full res gif

* Part 4

* Part 5

* Part 6 and a complete manfiest

* Clean up initial readme

* Better screenshot for part 3

* Completed screenshot

* Delete unused test stuff

* Cleanup

* Add note about the react version

* first round of feedback responses

* Lint errors for tutorial

* bug fixes
  • Loading branch information
lbrendanl authored Oct 6, 2017
1 parent 0b027d1 commit f403070
Show file tree
Hide file tree
Showing 96 changed files with 26,174 additions and 23,737 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules/
npm-debug.log
npm-debug.log
package-lock.json
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
4. Run `npm start`.
5. Launch Tableau and use the sample in a dashboard.

## Submissions
We would love submissions to either the Docs or Sample code! To contribute, first sign our CLA that can be found [here](https://tableau.github.io/contributing.html). To submit a contribution, please fork the repository then submit a pull request to the `submissions` branch.

## Code Style
Our sample code follows the [Semi-Standard Style](https://github.com/Flet/semistandard). If you add your own extension code to the Samples directory, you can run `npm run lint` to validate the style of your code. Please run this command before submitting any pull requests for Sample code.

## Known Issues (as of June 14, 2017)
Use [Issues](https://github.com/tableau/ProjectFrelard/issues) to log any problems or bugs you encounter in the docs or sample code.
Expand Down
67 changes: 63 additions & 4 deletions Samples/DataSources/datasources.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,75 @@
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" ></script>

<!-- Extensions Library (this will be hosted on a CDN eventually) -->
<script src="../../lib/tableau-extensions-0.6.0.js"></script>
<script src="../../lib/tableau-extensions-0.6.1.js"></script>

<!-- Our extensions's code -->
<script src="./datasources.js"></script>
<script src="./dataSources.js"></script>
</head>
<body>
<div class="container">
<div>
<h1>DataSources Sample</h1>
<!-- DataSources Table -->
<div id="dataSources">
<h4>All DataSources</h4>
<div class="table-responsive">
<table id="loading" class="table">
<tbody><tr><td>Loading...</td></tr></tbody>
</table>
<table id="dataSourcesTable" class="table table-striped hidden">
<thead>
<tr>
<th>DataSource Name</th>
<th>Auto Refresh</th>
<th style="width: 100%">Info</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>

<!-- More dataSource info modal -->
<div class="modal fade" id="infoModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h4 class="modal-title">DataSource Details</h4>
</div>
<div id="dataSourceDetails" class="modal-body">
<div class="table-responsive">
<table id="detailsTable" class="table">
<tbody>
<tr>
<td>DataSource Name</td>
<td id="nameDetail"></td>
</tr>
<tr>
<td>DataSource Id</td>
<td id="idDetail"></td>
</tr>
<tr>
<td>Type</td>
<td id="typeDetail"></td>
</tr>
<tr>
<td>Fields</td>
<td id="fieldsDetail"></td>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>

</div>
</div>
</div>
</body>
</html>
104 changes: 103 additions & 1 deletion Samples/DataSources/datasources.js
Original file line number Diff line number Diff line change
@@ -1 +1,103 @@
// TODO
'use strict';

// Wrap everything in an anonymous function to avoid poluting the global namespace
(function () {
$(document).ready(function () {
tableau.extensions.initializeAsync().then(function () {
// Since dataSource info is attached to the worksheet, we will perform
// one async call per worksheet to get every dataSource used in this
// dashboard. This demonstrates the use of Promise.all to combine
// promises together and wait for each of them to resolve.
let dataSourceFetchPromises = [];

// Maps dataSource id to dataSource so we can keep track of unique dataSources.
let dashboardDataSources = {};

// To get dataSource info, first get the dashboard.
const dashboard = tableau.extensions.dashboardContent.dashboard;

// Then loop through each worksheet and get its dataSources, save promise for later.
dashboard.worksheets.forEach(function (worksheet) {
dataSourceFetchPromises.push(worksheet.getDataSourcesAsync());
});

Promise.all(dataSourceFetchPromises).then(function (fetchResults) {
fetchResults.forEach(function (dataSourcesForWorksheet) {
dataSourcesForWorksheet.forEach(function (dataSource) {
if (!dashboardDataSources[dataSource.id]) { // We've already seen it, skip it.
dashboardDataSources[dataSource.id] = dataSource;
}
});
});

buildDataSourcesTable(dashboardDataSources);

// This just modifies the UI by removing the loading banner and showing the dataSources table.
$('#loading').addClass('hidden');
$('#dataSourcesTable').removeClass('hidden').addClass('show');
});
}, function (err) {
// Something went wrong in initialization.
console.log('Error while Initializing: ' + err.toString());
});
});

// Refreshes the a given dataSource.
function refreshDataSource (dataSource) {
dataSource.refreshAsync().then(function () {
console.log(dataSource.name + ': Refreshed Successfully');
});
}

// Displays a modal dialog with more details about a given dataSource.
function showModal (dataSource) {
var modal = $('#infoModal');

$('#nameDetail').text(dataSource.name);
$('#idDetail').text(dataSource.id);
$('#typeDetail').text((dataSource.isExtract) ? 'Extract' : 'Live');

// Loop through every field in the dataSource and concat it to a string.
var fieldNamesStr = '';
dataSource.fields.forEach(function (field) {
fieldNamesStr += field.name + ', ';
});

// Slice of the last ", " for formatting.
$('#fieldsDetail').text(fieldNamesStr.slice(0, -2));

modal.modal('show');
}

// Contructs UI that displays all the dataSources in this dashboard
// given a mapping from dataSourceId to dataSource objects.
function buildDataSourcesTable (dataSources) {
// Clear the table first.
$('#dataSourcesTable > tbody tr').remove();
const dataSourcesTable = $('#dataSourcesTable > tbody')[0];

// Add an entry to the dataSources table for each dataSource.
for (let dataSourceId in dataSources) {
const dataSource = dataSources[dataSourceId];

let newRow = dataSourcesTable.insertRow(dataSourcesTable.rows.length);
let nameCell = newRow.insertCell(0);
let refreshCell = newRow.insertCell(1);
let infoCell = newRow.insertCell(2);

let refreshButton = document.createElement('button');
refreshButton.innerHTML = ('Refresh Now');
refreshButton.type = 'button';
refreshButton.className = 'btn btn-primary';
refreshButton.addEventListener('click', function () { refreshDataSource(dataSource); });

let infoSpan = document.createElement('span');
infoSpan.className = 'glyphicon glyphicon-info-sign';
infoSpan.addEventListener('click', function () { showModal(dataSource); });

nameCell.innerHTML = dataSource.name;
refreshCell.appendChild(refreshButton);
infoCell.appendChild(infoSpan);
}
}
})();
32 changes: 29 additions & 3 deletions Samples/Filtering/filtering.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,41 @@
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" ></script>

<!-- Extensions Library (this will be hosted on a CDN eventually) -->
<script src="../../lib/tableau-extensions-0.6.0.js"></script>
<script src="../../lib/tableau-extensions-0.6.1.js"></script>

<!-- Our extensions's code -->
<script src="./filtering.js"></script>
</head>
<body>
<div class="container">
<div>
<h1>Filtering Sample</h1>
<!-- Filters Table -->
<div id="filters">
<h4>Current Filters</h4>
<div class="table-responsive">
<table id="loading" class="table">
<tbody><tr><td>Loading...</td></tr></tbody>
</table>
<table id="filtersTable" class="table table-striped hidden">
<thead>
<tr>
<th>Filtered Field</th>
<th>Filtered Worksheet</th>
<th>Filter Type</th>
<th style="width: 100%">Current Values</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<table id="noFiltersWarning" class="table bg-danger hidden">
<tbody><tr><td>There are no filters currently active in this dashboard.</td></tr></tbody>
</table>
</div>
</div>

<!-- New Settings Submission Form -->
<div id="filterActions">
<button id="clear" type="button" class="btn btn-primary">Clear All</button>
</div>
</div>
</body>
Expand Down
Loading

0 comments on commit f403070

Please sign in to comment.