├── .gitattributes
├── .gitignore
├── DataDrivenParameters_2.latest.trex
├── LICENSE
├── README.md
├── docs
├── 2.0.0
│ ├── asset-manifest.json
│ ├── favicon.ico
│ ├── index.html
│ ├── manifest.json
│ ├── precache-manifest.dc7e0c72d8caeec99a4b170eb6b8ad0f.js
│ ├── service-worker.js
│ ├── static
│ │ ├── css
│ │ │ ├── main.a0b18684.chunk.css
│ │ │ └── main.a0b18684.chunk.css.map
│ │ └── js
│ │ │ ├── 2.6e32bc5d.chunk.js
│ │ │ ├── 2.6e32bc5d.chunk.js.map
│ │ │ ├── main.8c9ad036.chunk.js
│ │ │ ├── main.8c9ad036.chunk.js.map
│ │ │ ├── runtime~main.717e2416.js
│ │ │ └── runtime~main.717e2416.js.map
│ └── tableau.extensions.1.latest.js
├── 2.1.0
│ ├── asset-manifest.json
│ ├── favicon.ico
│ ├── index.html
│ ├── manifest.json
│ ├── precache-manifest.03cf0849ed10715b922211b8056357c4.js
│ ├── service-worker.js
│ ├── static
│ │ ├── css
│ │ │ ├── main.673a05ca.chunk.css
│ │ │ └── main.673a05ca.chunk.css.map
│ │ └── js
│ │ │ ├── 2.51c5d46f.chunk.js
│ │ │ ├── 2.51c5d46f.chunk.js.map
│ │ │ ├── main.bb588e6f.chunk.js
│ │ │ ├── main.bb588e6f.chunk.js.map
│ │ │ ├── runtime~main.0d9ba244.js
│ │ │ └── runtime~main.0d9ba244.js.map
│ └── tableau.extensions.1.latest.js
├── 2.latest
│ ├── asset-manifest.json
│ ├── favicon.ico
│ ├── index.html
│ ├── manifest.json
│ ├── precache-manifest.d75aafc2866f2a41c3713ec81c2e13c8.js
│ ├── service-worker.js
│ ├── static
│ │ ├── css
│ │ │ ├── main.673a05ca.chunk.css
│ │ │ └── main.673a05ca.chunk.css.map
│ │ └── js
│ │ │ ├── 2.51c5d46f.chunk.js
│ │ │ ├── 2.51c5d46f.chunk.js.map
│ │ │ ├── main.3aea75ac.chunk.js
│ │ │ ├── main.3aea75ac.chunk.js.map
│ │ │ ├── runtime~main.e725b044.js
│ │ │ └── runtime~main.e725b044.js.map
│ └── tableau.extensions.1.latest.js
├── asset-manifest.json
├── favicon.ico
├── index.html
├── manifest.json
├── precache-manifest.8f5c5c66632ab1c8eb2b9ab4c458256a.js
├── service-worker.js
├── static
│ ├── css
│ │ ├── main.cb967471.chunk.css
│ │ └── main.cb967471.chunk.css.map
│ └── js
│ │ ├── 2.bbca4fae.chunk.js
│ │ ├── 2.bbca4fae.chunk.js.map
│ │ ├── main.ae08df8d.chunk.js
│ │ ├── main.ae08df8d.chunk.js.map
│ │ ├── runtime~main.01d56cb3.js
│ │ └── runtime~main.01d56cb3.js.map
└── tableau.extensions.1.latest.js
├── package.json
├── public
├── favicon.ico
├── index.html
├── manifest.json
└── tableau.extensions.1.latest.js
├── sandboxed
├── DataDrivenParameters_Sandboxed.trex
├── DataDrivenParameters_Sandboxed_Test.trex
├── config-overrides.js
├── config.json
├── package.json
├── public
│ ├── config.html
│ ├── favicon.ico
│ ├── index.html
│ ├── manifest.json
│ └── tableau.extensions.1.latest.min.js
├── src
│ ├── Configure.tsx
│ ├── DataDrivenParameter.tsx
│ ├── Selected.tsx
│ ├── Selector.tsx
│ ├── Setting.tsx
│ ├── entry_config.tsx
│ ├── entry_index.tsx
│ ├── imgs
│ │ └── arrow.png
│ ├── index.tsx
│ ├── react-app-env.d.ts
│ ├── serviceWorker.ts
│ └── style.css
├── tsconfig.json
└── yarn.lock
├── src
├── Configure.tsx
├── DataDrivenParameter.tsx
├── Home.tsx
├── Selected.tsx
├── Selector.tsx
├── Setting.tsx
├── home.css
├── imgs
│ └── arrow.png
├── index.tsx
├── react-app-env.d.ts
├── serviceWorker.ts
└── style.css
├── tsconfig.json
└── yarn.lock
/.gitattributes:
--------------------------------------------------------------------------------
1 | /docs/* linguist-generated
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /sandboxed/node_modules
6 | /.pnp
7 | .pnp.js
8 |
9 | # testing
10 | /coverage
11 |
12 | # production
13 | /build
14 | /sandboxed/build
15 |
16 | # misc
17 | .DS_Store
18 | .env.local
19 | .env.development.local
20 | .env.test.local
21 | .env.production.local
22 |
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
--------------------------------------------------------------------------------
/DataDrivenParameters_2.latest.trex:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | en_US
5 |
6 | Automatically update your parameters based on your data!
7 |
8 | 0.9
9 |
10 | https://tableau.github.io/extension-data-driven-parameters/2.latest/#/parameter
11 |
12 | iVBORw0KGgoAAAANSUhEUgAAAEYAAABGCAYAAABxLuKEAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFHGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDUgNzkuMTYzNDk5LCAyMDE4LzA4LzEzLTE2OjQwOjIyICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDE5LTAyLTA2VDE0OjE4OjQ5LTA4OjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAxOS0wMi0wNlQxNDoxOToxNS0wODowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAxOS0wMi0wNlQxNDoxOToxNS0wODowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo3ZjJhNDI0YS02YzY2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
13 |
14 |
15 |
16 |
17 |
18 |
19 | Data-Driven Parameter
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Tableau
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://www.tableau.com/support-levels-it-and-developer-tools)
2 |
3 | # Data-Driven Parameters
4 | This extension allows you to add a parameter to a Tableau dashboard whose domain is based on your data. Added a new product line? Expanding to new regions? No longer do you need to manually edit the parameter to update it, with this extension your parameter values update automatically!
5 |
6 | ## Using the Extension from Tableau Exchange (Recommended)
7 | See the Tableau Help topic [Use Dashboard Extensions](https://help.tableau.com/current/pro/desktop/en-us/dashboard_extensions.htm) for directions. When presented with the list of available Dashboard Extensions, search for Data Driven Parameters to find and install this one.
8 |
9 | ### Using the Extension
10 | 1. Create a parameter that accepts all values (no lists or ranges), make sure it has a data type matching the field you want to use to populate it.
11 | 2. Drag in a new Extension object to your dashboard and click "My Extensions"
12 | 3. Find the manifest (.trex) file you downloaded above.
13 | 4. In the pop-up configuration window select the parameter you created above for the extension to manipulate.
14 | 5. Select the worksheet that holds the field you want to base your parameter on.
15 | 6. Select the field you want to base your parameter on.
16 | 7. Optional: Configure the options and formatting settings.
17 | 8. Click 'OK'.
18 |
19 | ## Download the Extension Code to Develop Locally
20 | If you want to use a locally-built version of this extension or if you want to make any of your own changes, follow these steps:
21 |
22 | 1. Make sure you have [Node.js](https://nodejs.org) and [Yarn](https://yarnpkg.com) installed.
23 | 2. Clone or download and unzip this repository. Open the command line to the `extension-data-driven-parameters-master` folder and run `yarn` to install the node modules.
24 | 3. Edit the `homepage` in the `package.json` file to the server where you are going to host the extension. For example:
25 | ```
26 | "homepage": "http://localhost:8080",
27 | ```
28 | 4. In the command line run `yarn build` to build the extension with the new homepage.
29 | 5. Copy the files in `build` to your web server at the path you specified in Step 3.
30 | 6. Update the existing or create a new manifest file (.trex) to point to the URL where you are hosting the extension with `/#/parameter` at the end. For example: `http://localhost:8080/#/parameter`.
31 |
32 | ## Support
33 | Tableau customers can contact the Tableau Support team for help.
34 |
35 | For any local build or code related questions, please post to the [Issues](https://github.com/tableau/extension-data-driven-parameters/issues) tab here for community support.
36 |
37 | ### Mac Desktop 2018.3 and lower
38 | Note: Please use arrow keys and 'Enter' to select dropdown options.
39 |
--------------------------------------------------------------------------------
/docs/2.0.0/asset-manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": {
3 | "main.css": "/extension-data-driven-parameters/2.0.0/static/css/main.a0b18684.chunk.css",
4 | "main.js": "/extension-data-driven-parameters/2.0.0/static/js/main.8c9ad036.chunk.js",
5 | "main.js.map": "/extension-data-driven-parameters/2.0.0/static/js/main.8c9ad036.chunk.js.map",
6 | "runtime~main.js": "/extension-data-driven-parameters/2.0.0/static/js/runtime~main.717e2416.js",
7 | "runtime~main.js.map": "/extension-data-driven-parameters/2.0.0/static/js/runtime~main.717e2416.js.map",
8 | "static/js/2.6e32bc5d.chunk.js": "/extension-data-driven-parameters/2.0.0/static/js/2.6e32bc5d.chunk.js",
9 | "static/js/2.6e32bc5d.chunk.js.map": "/extension-data-driven-parameters/2.0.0/static/js/2.6e32bc5d.chunk.js.map",
10 | "index.html": "/extension-data-driven-parameters/2.0.0/index.html",
11 | "precache-manifest.dc7e0c72d8caeec99a4b170eb6b8ad0f.js": "/extension-data-driven-parameters/2.0.0/precache-manifest.dc7e0c72d8caeec99a4b170eb6b8ad0f.js",
12 | "service-worker.js": "/extension-data-driven-parameters/2.0.0/service-worker.js",
13 | "static/css/main.a0b18684.chunk.css.map": "/extension-data-driven-parameters/2.0.0/static/css/main.a0b18684.chunk.css.map"
14 | }
15 | }
--------------------------------------------------------------------------------
/docs/2.0.0/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tableau/extension-data-driven-parameters/3a97c522fb3cf36bd389366ef7626066f679345f/docs/2.0.0/favicon.ico
--------------------------------------------------------------------------------
/docs/2.0.0/index.html:
--------------------------------------------------------------------------------
1 |
Data-Driven Parameters Extension
--------------------------------------------------------------------------------
/docs/2.0.0/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "Data-Driven Parameters",
3 | "name": "Data-Driven Parameters",
4 | "icons": [{
5 | "src": "favicon.ico",
6 | "sizes": "64x64 32x32 24x24 16x16",
7 | "type": "image/x-icon"
8 | }],
9 | "start_url": ".",
10 | "display": "standalone",
11 | "theme_color": "#000000",
12 | "background_color": "#ffffff"
13 | }
--------------------------------------------------------------------------------
/docs/2.0.0/precache-manifest.dc7e0c72d8caeec99a4b170eb6b8ad0f.js:
--------------------------------------------------------------------------------
1 | self.__precacheManifest = (self.__precacheManifest || []).concat([
2 | {
3 | "revision": "68867bb1532e4dba9258b6aad5151ac6",
4 | "url": "/extension-data-driven-parameters/2.0.0/index.html"
5 | },
6 | {
7 | "revision": "f91160f4b9f466811a79",
8 | "url": "/extension-data-driven-parameters/2.0.0/static/css/main.a0b18684.chunk.css"
9 | },
10 | {
11 | "revision": "45be5b04b3c14e0fb4b8",
12 | "url": "/extension-data-driven-parameters/2.0.0/static/js/2.6e32bc5d.chunk.js"
13 | },
14 | {
15 | "revision": "f91160f4b9f466811a79",
16 | "url": "/extension-data-driven-parameters/2.0.0/static/js/main.8c9ad036.chunk.js"
17 | },
18 | {
19 | "revision": "c673bd0018bb6cffcb9f",
20 | "url": "/extension-data-driven-parameters/2.0.0/static/js/runtime~main.717e2416.js"
21 | }
22 | ]);
--------------------------------------------------------------------------------
/docs/2.0.0/service-worker.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Welcome to your Workbox-powered service worker!
3 | *
4 | * You'll need to register this file in your web app and you should
5 | * disable HTTP caching for this file too.
6 | * See https://goo.gl/nhQhGp
7 | *
8 | * The rest of the code is auto-generated. Please don't update this file
9 | * directly; instead, make changes to your Workbox build configuration
10 | * and re-run your build process.
11 | * See https://goo.gl/2aRDsh
12 | */
13 |
14 | importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js");
15 |
16 | importScripts(
17 | "/extension-data-driven-parameters/2.0.0/precache-manifest.dc7e0c72d8caeec99a4b170eb6b8ad0f.js"
18 | );
19 |
20 | self.addEventListener('message', (event) => {
21 | if (event.data && event.data.type === 'SKIP_WAITING') {
22 | self.skipWaiting();
23 | }
24 | });
25 |
26 | workbox.core.clientsClaim();
27 |
28 | /**
29 | * The workboxSW.precacheAndRoute() method efficiently caches and responds to
30 | * requests for URLs in the manifest.
31 | * See https://goo.gl/S9QRab
32 | */
33 | self.__precacheManifest = [].concat(self.__precacheManifest || []);
34 | workbox.precaching.precacheAndRoute(self.__precacheManifest, {});
35 |
36 | workbox.routing.registerNavigationRoute(workbox.precaching.getCacheKeyForURL("/extension-data-driven-parameters/2.0.0/index.html"), {
37 |
38 | blacklist: [/^\/_/,/\/[^\/]+\.[^\/]+$/],
39 | });
40 |
--------------------------------------------------------------------------------
/docs/2.0.0/static/css/main.a0b18684.chunk.css:
--------------------------------------------------------------------------------
1 | body,html{font-family:Benton Sans,Arial,Helvetica,sans-serif;font-size:12px;color:rgba(0,0,0,.8);box-sizing:border-box;overflow:hidden}#container{height:100%;width:100%}.container{display:flex;flex-direction:column;justify-content:space-between;height:100%}.content{margin-left:6px}.header{font-size:16px;padding:12px 0 12px 18px;display:flex}.header,.title{color:rgba(0,0,0,.8)}.title{font-family:Benton Sans Medium,Arial,Helvetica,sans-serif;font-size:12px;margin:30px 0 18px}p{margin:0}.selected,.selector{display:flex;min-height:26px;margin-bottom:12px}.selected{margin-left:10px;justify-content:space-between}.option,.selected{align-items:center}.option{display:flex;margin-top:12px}.footer{display:flex;align-items:flex-end;margin:0 18px}.btncluster{display:flex;justify-content:flex-end;width:100%;margin-bottom:12px}.format{display:flex;margin-top:12px}.formattext{width:130px}input[type=color]{padding:0;margin-left:6px;border:1px solid #666;box-shadow:none;width:16px;height:16px;border-radius:50%;outline:0}::-webkit-color-swatch{border:none}.tooltip{position:relative;display:inline-block;margin-left:5px;padding-top:2px}.tooltip .tooltiptext{visibility:hidden;border:1px solid #d4d4d4;border-radius:1px;background:#fff;font-size:10px;padding:8px;width:200px;position:absolute;z-index:1;right:-100px;top:20px}.tooltip:hover .tooltiptext{visibility:visible}.tooltiptext ol{padding:0 8px;margin:0}.tooltiptext li{margin-top:8px}.parameter{width:100%;font-family:Benton Sans,Arial,Helvetica,sans-serif;font-size:12px;padding-left:6px;border:1px solid #cbcbcb}.parameter option{padding:2px 2px 1px;height:20px;display:flex;align-items:center}.singleParameter{width:100%;min-height:20px!important}.dropdown-select{flex:1 1;margin-left:0;width:"100%"}.delimiter-text-field>input{font-family:Benton Sans,Arial,Helvetica,sans-serif;padding-right:0;text-align:center}select::-ms-expand{visibility:hidden}body,html{margin:0;padding:0;height:100%;width:100%;color:#585858;border:0}.icontainer{font-size:18px;background:#fafafa;display:flex;justify-content:center;align-items:center;height:100%}.box{background:#fff;max-width:1250px;margin:20px;display:flex;box-shadow:2px 4px 8px rgba(102,162,222,.15)}.left{background:-webkit-gradient(linear,right top,left bottom,from(#02b3a4),to(#66a2de));background:-webkit-linear-gradient(top right,#02b3a4,#66a2de);background:linear-gradient(to bottom left,#02b3a4,#66a2de);width:450px;color:#fff;font-size:20px;font-family:Benton Sans,Arial,Helvetica,sans-serif}.left,.right{padding:40px;display:flex;align-items:center;align-content:center;justify-content:flex-start;flex-wrap:wrap}.iheader{font-size:64px;font-family:Bookman Old Style,Arial,Helvetica,sans-serif;margin:10px 0;line-height:54px}.big{font-size:28px;width:100%;margin:5px 0}a{color:#02b3a4;font-weight:700;text-decoration:none}a:hover{text-decoration:underline}.gh{font-size:16px;text-align:center;width:100%}
2 | /*# sourceMappingURL=main.a0b18684.chunk.css.map */
--------------------------------------------------------------------------------
/docs/2.0.0/static/css/main.a0b18684.chunk.css.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["style.css","home.css"],"names":[],"mappings":"AAAA,UAII,kDAAwD,CACxD,cAAe,CACf,oBAAyB,CACzB,qBAAsB,CAGtB,eACJ,CAEA,WACI,WAAY,CACZ,UACJ,CAEA,WACI,YAAa,CACb,qBAAsB,CACtB,6BAA8B,CAC9B,WACJ,CAEA,SACI,eACJ,CAEA,QACI,cAAe,CAElB,wBAA2B,CACxB,YACJ,CAEA,eALI,oBAUJ,CALA,OACI,yDAA+D,CAC/D,cAAe,CAEf,kBACJ,CAEA,EACI,QACJ,CAQA,oBALI,YAAa,CACb,eAAgB,CAChB,kBAUJ,CAPA,UACI,gBAAiB,CAGjB,6BAGJ,CAEA,kBAJI,kBAQJ,CAJA,QACI,YAAa,CAEb,eACJ,CAEA,QACI,YAAa,CACb,oBAAqB,CACxB,aACD,CAEA,YACI,YAAa,CACb,wBAAyB,CACzB,UAAW,CACX,kBACJ,CAEA,QACI,YAAa,CACb,eACJ,CAEA,YACI,WACJ,CAEA,kBAEI,SAAU,CACV,eAAgB,CAChB,qBAAyB,CACzB,eAAgB,CAChB,UAAW,CACX,WAAY,CACZ,iBAAkB,CAClB,SACJ,CAEA,uBACI,WACJ,CAEA,SACI,iBAAkB,CAClB,oBAAqB,CACrB,eAAgB,CAChB,eACJ,CAEA,sBACI,iBAAkB,CAClB,wBAAyB,CACzB,iBAAkB,CAClB,eAAgB,CAChB,cAAe,CACf,WAAY,CACZ,WAAY,CACZ,iBAAkB,CAClB,SAAU,CACV,YAAa,CACb,QACJ,CAEA,4BACI,kBACJ,CAEA,gBACI,aAAgB,CAChB,QACJ,CAEA,gBACI,cACJ,CAEA,WACI,UAAW,CACd,kDAAwD,CACxD,cAAe,CACf,gBAAgB,CAChB,wBACD,CAEA,kBACC,mBAAoB,CACpB,WAAY,CACZ,YAAY,CACZ,kBACD,CAEA,iBACI,UAAW,CACd,yBACD,CAEA,iBACI,QAAO,CACP,aAAc,CACd,YACJ,CAEA,4BACI,kDAAwD,CACxD,eAAgB,CAChB,iBACJ,CAGA,mBACI,iBACJ,CC/KA,UAEI,QAAS,CACT,SAAU,CACV,WAAY,CACZ,UAAW,CACX,aAAc,CACd,QACJ,CAEA,YACI,cAAe,CACf,kBAAmB,CACnB,YAAa,CACb,sBAAuB,CACvB,kBAAmB,CACnB,WACJ,CAEA,KACI,eAAmB,CACnB,gBAAiB,CACjB,WAAY,CACZ,YAAa,CACb,4CACJ,CAEA,MACI,mFAA6D,CAA7D,6DAA6D,CAA7D,0DAA6D,CAE7D,WAAY,CACZ,UAAc,CAMd,cAAe,CACf,kDACJ,CAEA,aAZI,YAAa,CAGb,YAAa,CACb,kBAAmB,CACnB,oBAAqB,CACrB,0BAA2B,CAC3B,cAYJ,CAEA,SACI,cAAe,CACf,wDAA8D,CAC9D,aAAgB,CAChB,gBACJ,CAEA,KACI,cAAe,CACf,UAAW,CACX,YACJ,CAEA,EACI,aAAc,CACd,eAAiB,CACjB,oBACJ,CAEA,QACI,yBACJ,CAEA,IACI,cAAe,CACf,iBAAkB,CAClB,UACJ","file":"main.a0b18684.chunk.css","sourcesContent":["html,\r\nbody {\r\n margin: 0;\r\n padding: 0;\r\n font-family: 'Benton Sans', Arial, Helvetica, sans-serif;\r\n font-size: 12px;\r\n color: rgba(0, 0, 0, 0.8);\r\n box-sizing: border-box;\r\n height: 100%;\r\n width: 100%;\r\n overflow: hidden;\r\n}\r\n\r\n#container {\r\n height: 100%;\r\n width: 100%;\r\n}\r\n\r\n.container {\r\n display: flex;\r\n flex-direction: column;\r\n justify-content: space-between;\r\n height: 100%;\r\n}\r\n\r\n.content {\r\n margin-left: 6px;\r\n}\r\n\r\n.header {\r\n font-size: 16px;\r\n color: rgba(0, 0, 0, 0.8);\r\n\tpadding: 12px 0px 12px 18px;\r\n display: flex;\r\n}\r\n\r\n.title {\r\n font-family: 'Benton Sans Medium', Arial, Helvetica, sans-serif;\r\n font-size: 12px;\r\n color: rgba(0, 0, 0, 0.8);\r\n margin: 30px 0px 18px 0px;\r\n}\r\n\r\np {\r\n margin: 0;\r\n}\r\n\r\n.selector {\r\n display: flex;\r\n min-height: 26px;\r\n margin-bottom: 12px;\r\n}\r\n\r\n.selected {\r\n margin-left: 10px;\r\n min-height: 26px;\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n margin-bottom: 12px;\r\n}\r\n\r\n.option {\r\n display: flex;\r\n align-items: center;\r\n margin-top: 12px;\r\n}\r\n\r\n.footer {\r\n display: flex;\r\n align-items: flex-end;\r\n\tmargin: 0px 18px;\r\n}\r\n\r\n.btncluster {\r\n display: flex;\r\n justify-content: flex-end;\r\n width: 100%;\r\n margin-bottom: 12px;\r\n}\r\n\r\n.format {\r\n display: flex;\r\n margin-top: 12px;\r\n}\r\n\r\n.formattext {\r\n width: 130px;\r\n}\r\n\r\ninput[type=\"color\"] {\r\n /* background-color: #fff; */\r\n padding: 0;\r\n margin-left: 6px;\r\n border: 1px solid #666666;\r\n box-shadow: none;\r\n width: 16px;\r\n height: 16px;\r\n border-radius: 50%;\r\n outline: 0;\r\n}\r\n\r\n::-webkit-color-swatch {\r\n border: none;\r\n}\r\n\r\n.tooltip {\r\n position: relative;\r\n display: inline-block;\r\n margin-left: 5px;\r\n padding-top: 2px;\r\n}\r\n\r\n.tooltip .tooltiptext {\r\n visibility: hidden;\r\n border: 1px solid #D4D4D4;\r\n border-radius: 1px;\r\n background: #fff;\r\n font-size: 10px;\r\n padding: 8px;\r\n width: 200px;\r\n position: absolute;\r\n z-index: 1;\r\n right: -100px;\r\n top: 20px;\r\n}\r\n\r\n.tooltip:hover .tooltiptext {\r\n visibility: visible;\r\n}\r\n\r\n.tooltiptext ol {\r\n padding: 0px 8px;\r\n margin: 0px;\r\n}\r\n\r\n.tooltiptext li {\r\n margin-top: 8px;\r\n}\r\n\r\n.parameter {\r\n width: 100%;\r\n\tfont-family: 'Benton Sans', Arial, Helvetica, sans-serif;\r\n\tfont-size: 12px;\r\n\tpadding-left:6px;\r\n\tborder: solid 1px #CBCBCB;\r\n}\r\n\r\n.parameter option {\r\n\tpadding: 2px 2px 1px;\r\n\theight: 20px;\r\n\tdisplay:flex;\r\n\talign-items: center;\r\n}\r\n\r\n.singleParameter {\r\n width: 100%;\r\n\tmin-height: 20px !important;\r\n}\r\n\r\n.dropdown-select {\r\n flex: 1;\r\n margin-left: 0;\r\n width: '100%';\r\n}\r\n\r\n.delimiter-text-field > input {\r\n font-family: 'Benton Sans', Arial, Helvetica, sans-serif;\r\n padding-right: 0;\r\n text-align: center;\r\n}\r\n\r\n/* Internet Explorer 10+ */\r\nselect::-ms-expand {\r\n visibility: hidden;\r\n}","html,\r\nbody {\r\n margin: 0;\r\n padding: 0;\r\n height: 100%;\r\n width: 100%;\r\n color: #585858;\r\n border: 0;\r\n}\r\n\r\n.icontainer {\r\n font-size: 18px;\r\n background: #FAFAFA;\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n height: 100%;\r\n}\r\n\r\n.box {\r\n background: #ffffff;\r\n max-width: 1250px;\r\n margin: 20px;\r\n display: flex;\r\n box-shadow: 2px 4px 8px rgba(102, 162, 222, 0.15);\r\n}\r\n\r\n.left {\r\n background: linear-gradient(to bottom left, #02B3A4, #66A2DE);\r\n padding: 40px;\r\n width: 450px;\r\n color: #ffffff;\r\n display: flex;\r\n align-items: center;\r\n align-content: center;\r\n justify-content: flex-start;\r\n flex-wrap: wrap;\r\n font-size: 20px;\r\n font-family: 'Benton Sans', Arial, Helvetica, sans-serif;\r\n}\r\n\r\n.right {\r\n padding: 40px;\r\n display: flex;\r\n align-items: center;\r\n align-content: center;\r\n justify-content: flex-start;\r\n flex-wrap: wrap;\r\n}\r\n\r\n.iheader {\r\n font-size: 64px;\r\n font-family: 'Bookman Old Style', Arial, Helvetica, sans-serif;\r\n margin: 10px 0px;\r\n line-height: 54px;\r\n}\r\n\r\n.big {\r\n font-size: 28px;\r\n width: 100%;\r\n margin: 5px 0px;\r\n}\r\n\r\na {\r\n color: #02B3A4;\r\n font-weight: bold;\r\n text-decoration: none;\r\n}\r\n\r\na:hover {\r\n text-decoration: underline;\r\n}\r\n\r\n.gh {\r\n font-size: 16px;\r\n text-align: center;\r\n width: 100%;\r\n}"]}
--------------------------------------------------------------------------------
/docs/2.0.0/static/js/runtime~main.717e2416.js:
--------------------------------------------------------------------------------
1 | !function(e){function r(r){for(var n,i,a=r[0],f=r[1],l=r[2],c=0,s=[];cData-Driven Parameters Extension
--------------------------------------------------------------------------------
/docs/2.1.0/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "Data-Driven Parameters",
3 | "name": "Data-Driven Parameters",
4 | "icons": [{
5 | "src": "favicon.ico",
6 | "sizes": "64x64 32x32 24x24 16x16",
7 | "type": "image/x-icon"
8 | }],
9 | "start_url": ".",
10 | "display": "standalone",
11 | "theme_color": "#000000",
12 | "background_color": "#ffffff"
13 | }
--------------------------------------------------------------------------------
/docs/2.1.0/precache-manifest.03cf0849ed10715b922211b8056357c4.js:
--------------------------------------------------------------------------------
1 | self.__precacheManifest = (self.__precacheManifest || []).concat([
2 | {
3 | "revision": "1748eeffbc5479b3e125d90193768b2f",
4 | "url": "/extension-data-driven-parameters/2.1.0/index.html"
5 | },
6 | {
7 | "revision": "5a1eccd829a83105b24e",
8 | "url": "/extension-data-driven-parameters/2.1.0/static/css/main.673a05ca.chunk.css"
9 | },
10 | {
11 | "revision": "09254fd0a08a7b9bf518",
12 | "url": "/extension-data-driven-parameters/2.1.0/static/js/2.51c5d46f.chunk.js"
13 | },
14 | {
15 | "revision": "5a1eccd829a83105b24e",
16 | "url": "/extension-data-driven-parameters/2.1.0/static/js/main.bb588e6f.chunk.js"
17 | },
18 | {
19 | "revision": "e8b8459bbc586125acd5",
20 | "url": "/extension-data-driven-parameters/2.1.0/static/js/runtime~main.0d9ba244.js"
21 | }
22 | ]);
--------------------------------------------------------------------------------
/docs/2.1.0/service-worker.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Welcome to your Workbox-powered service worker!
3 | *
4 | * You'll need to register this file in your web app and you should
5 | * disable HTTP caching for this file too.
6 | * See https://goo.gl/nhQhGp
7 | *
8 | * The rest of the code is auto-generated. Please don't update this file
9 | * directly; instead, make changes to your Workbox build configuration
10 | * and re-run your build process.
11 | * See https://goo.gl/2aRDsh
12 | */
13 |
14 | importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js");
15 |
16 | importScripts(
17 | "/extension-data-driven-parameters/2.1.0/precache-manifest.03cf0849ed10715b922211b8056357c4.js"
18 | );
19 |
20 | self.addEventListener('message', (event) => {
21 | if (event.data && event.data.type === 'SKIP_WAITING') {
22 | self.skipWaiting();
23 | }
24 | });
25 |
26 | workbox.core.clientsClaim();
27 |
28 | /**
29 | * The workboxSW.precacheAndRoute() method efficiently caches and responds to
30 | * requests for URLs in the manifest.
31 | * See https://goo.gl/S9QRab
32 | */
33 | self.__precacheManifest = [].concat(self.__precacheManifest || []);
34 | workbox.precaching.precacheAndRoute(self.__precacheManifest, {});
35 |
36 | workbox.routing.registerNavigationRoute(workbox.precaching.getCacheKeyForURL("/extension-data-driven-parameters/2.1.0/index.html"), {
37 |
38 | blacklist: [/^\/_/,/\/[^/]+\.[^/]+$/],
39 | });
40 |
--------------------------------------------------------------------------------
/docs/2.1.0/static/css/main.673a05ca.chunk.css:
--------------------------------------------------------------------------------
1 | body,html{font-family:Benton Sans,Arial,Helvetica,sans-serif;font-size:12px;color:rgba(0,0,0,.8);box-sizing:border-box;overflow:hidden}#container{height:100%;width:100%}.container{display:flex;flex-direction:column;justify-content:space-between;height:100%}.content{margin-left:6px}.header{font-size:16px;padding:12px 0 12px 18px;display:flex}.header,.title{color:rgba(0,0,0,.8)}.title{font-family:Benton Sans Medium,Arial,Helvetica,sans-serif;font-size:12px;margin:30px 0 18px}p{margin:0}.selected,.selector{display:flex;min-height:26px;margin-bottom:12px}.selected{margin-left:10px;justify-content:space-between}.option,.selected{align-items:center}.option{display:flex;margin-top:12px}.footer{display:flex;align-items:flex-end;margin:0 18px}.btncluster{display:flex;justify-content:flex-end;width:100%;margin-bottom:12px}.format{display:flex;margin-top:12px}.formattext{width:130px}input[type=color]{padding:0;margin-left:6px;border:1px solid #666;box-shadow:none;width:16px;height:16px;border-radius:50%;outline:0}::-webkit-color-swatch{border:none}.tooltip{position:relative;display:inline-block;margin-left:5px;padding-top:2px}.tooltip .tooltiptext{visibility:hidden;border:1px solid #d4d4d4;border-radius:1px;background:#fff;font-size:10px;padding:8px;width:200px;position:absolute;z-index:1;right:-100px;top:20px}.tooltip:hover .tooltiptext{visibility:visible}.tooltiptext ol{padding:0 8px;margin:0}.tooltiptext li{margin-top:8px}.parameter{width:100%;font-family:Benton Sans,Arial,Helvetica,sans-serif;font-size:12px;padding-left:6px;border:1px solid #cbcbcb}.parameter option{padding:2px 2px 1px;height:20px;display:flex;align-items:center}.singleParameter{width:100%;min-height:20px!important}.dropdown-select{flex:1 1;margin-left:0;width:"100%"}.delimiter-text-field>input{font-family:Benton Sans,Arial,Helvetica,sans-serif;padding-right:0;text-align:center}select::-ms-expand{visibility:hidden}body,html{margin:0;padding:0;height:100%;width:100%;color:#585858;border:0}.icontainer{font-size:18px;background:#fafafa;display:flex;justify-content:center;align-items:center;height:100%}.box{background:#fff;max-width:1250px;margin:20px;display:flex;box-shadow:2px 4px 8px rgba(102,162,222,.15)}.left{background:-webkit-gradient(linear,right top,left bottom,from(#02b3a4),to(#66a2de));background:linear-gradient(to bottom left,#02b3a4,#66a2de);width:450px;color:#fff;font-size:20px;font-family:Benton Sans,Arial,Helvetica,sans-serif}.left,.right{padding:40px;display:flex;align-items:center;align-content:center;justify-content:flex-start;flex-wrap:wrap}.iheader{font-size:64px;font-family:Bookman Old Style,Arial,Helvetica,sans-serif;margin:10px 0;line-height:54px}.big{font-size:28px;width:100%;margin:5px 0}a{color:#02b3a4;font-weight:700;text-decoration:none}a:hover{text-decoration:underline}.gh{font-size:16px;text-align:center;width:100%}
2 | /*# sourceMappingURL=main.673a05ca.chunk.css.map */
--------------------------------------------------------------------------------
/docs/2.1.0/static/css/main.673a05ca.chunk.css.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["style.css","home.css"],"names":[],"mappings":"AAAA,UAII,kDAAwD,CACxD,cAAe,CACf,oBAAyB,CACzB,qBAAsB,CAGtB,eACJ,CAEA,WACI,WAAY,CACZ,UACJ,CAEA,WACI,YAAa,CACb,qBAAsB,CACtB,6BAA8B,CAC9B,WACJ,CAEA,SACI,eACJ,CAEA,QACI,cAAe,CAElB,wBAA2B,CACxB,YACJ,CAEA,eALI,oBAUJ,CALA,OACI,yDAA+D,CAC/D,cAAe,CAEf,kBACJ,CAEA,EACI,QACJ,CAQA,oBALI,YAAa,CACb,eAAgB,CAChB,kBAUJ,CAPA,UACI,gBAAiB,CAGjB,6BAGJ,CAEA,kBAJI,kBAQJ,CAJA,QACI,YAAa,CAEb,eACJ,CAEA,QACI,YAAa,CACb,oBAAqB,CACxB,aACD,CAEA,YACI,YAAa,CACb,wBAAyB,CACzB,UAAW,CACX,kBACJ,CAEA,QACI,YAAa,CACb,eACJ,CAEA,YACI,WACJ,CAEA,kBAEI,SAAU,CACV,eAAgB,CAChB,qBAAyB,CACzB,eAAgB,CAChB,UAAW,CACX,WAAY,CACZ,iBAAkB,CAClB,SACJ,CAEA,uBACI,WACJ,CAEA,SACI,iBAAkB,CAClB,oBAAqB,CACrB,eAAgB,CAChB,eACJ,CAEA,sBACI,iBAAkB,CAClB,wBAAyB,CACzB,iBAAkB,CAClB,eAAgB,CAChB,cAAe,CACf,WAAY,CACZ,WAAY,CACZ,iBAAkB,CAClB,SAAU,CACV,YAAa,CACb,QACJ,CAEA,4BACI,kBACJ,CAEA,gBACI,aAAgB,CAChB,QACJ,CAEA,gBACI,cACJ,CAEA,WACI,UAAW,CACd,kDAAwD,CACxD,cAAe,CACf,gBAAgB,CAChB,wBACD,CAEA,kBACC,mBAAoB,CACpB,WAAY,CACZ,YAAY,CACZ,kBACD,CAEA,iBACI,UAAW,CACd,yBACD,CAEA,iBACI,QAAO,CACP,aAAc,CACd,YACJ,CAEA,4BACI,kDAAwD,CACxD,eAAgB,CAChB,iBACJ,CAGA,mBACI,iBACJ,CC/KA,UAEI,QAAS,CACT,SAAU,CACV,WAAY,CACZ,UAAW,CACX,aAAc,CACd,QACJ,CAEA,YACI,cAAe,CACf,kBAAmB,CACnB,YAAa,CACb,sBAAuB,CACvB,kBAAmB,CACnB,WACJ,CAEA,KACI,eAAmB,CACnB,gBAAiB,CACjB,WAAY,CACZ,YAAa,CACb,4CACJ,CAEA,MACI,mFAA6D,CAA7D,0DAA6D,CAE7D,WAAY,CACZ,UAAc,CAMd,cAAe,CACf,kDACJ,CAEA,aAZI,YAAa,CAGb,YAAa,CACb,kBAAmB,CACnB,oBAAqB,CACrB,0BAA2B,CAC3B,cAYJ,CAEA,SACI,cAAe,CACf,wDAA8D,CAC9D,aAAgB,CAChB,gBACJ,CAEA,KACI,cAAe,CACf,UAAW,CACX,YACJ,CAEA,EACI,aAAc,CACd,eAAiB,CACjB,oBACJ,CAEA,QACI,yBACJ,CAEA,IACI,cAAe,CACf,iBAAkB,CAClB,UACJ","file":"main.673a05ca.chunk.css","sourcesContent":["html,\r\nbody {\r\n margin: 0;\r\n padding: 0;\r\n font-family: 'Benton Sans', Arial, Helvetica, sans-serif;\r\n font-size: 12px;\r\n color: rgba(0, 0, 0, 0.8);\r\n box-sizing: border-box;\r\n height: 100%;\r\n width: 100%;\r\n overflow: hidden;\r\n}\r\n\r\n#container {\r\n height: 100%;\r\n width: 100%;\r\n}\r\n\r\n.container {\r\n display: flex;\r\n flex-direction: column;\r\n justify-content: space-between;\r\n height: 100%;\r\n}\r\n\r\n.content {\r\n margin-left: 6px;\r\n}\r\n\r\n.header {\r\n font-size: 16px;\r\n color: rgba(0, 0, 0, 0.8);\r\n\tpadding: 12px 0px 12px 18px;\r\n display: flex;\r\n}\r\n\r\n.title {\r\n font-family: 'Benton Sans Medium', Arial, Helvetica, sans-serif;\r\n font-size: 12px;\r\n color: rgba(0, 0, 0, 0.8);\r\n margin: 30px 0px 18px 0px;\r\n}\r\n\r\np {\r\n margin: 0;\r\n}\r\n\r\n.selector {\r\n display: flex;\r\n min-height: 26px;\r\n margin-bottom: 12px;\r\n}\r\n\r\n.selected {\r\n margin-left: 10px;\r\n min-height: 26px;\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n margin-bottom: 12px;\r\n}\r\n\r\n.option {\r\n display: flex;\r\n align-items: center;\r\n margin-top: 12px;\r\n}\r\n\r\n.footer {\r\n display: flex;\r\n align-items: flex-end;\r\n\tmargin: 0px 18px;\r\n}\r\n\r\n.btncluster {\r\n display: flex;\r\n justify-content: flex-end;\r\n width: 100%;\r\n margin-bottom: 12px;\r\n}\r\n\r\n.format {\r\n display: flex;\r\n margin-top: 12px;\r\n}\r\n\r\n.formattext {\r\n width: 130px;\r\n}\r\n\r\ninput[type=\"color\"] {\r\n /* background-color: #fff; */\r\n padding: 0;\r\n margin-left: 6px;\r\n border: 1px solid #666666;\r\n box-shadow: none;\r\n width: 16px;\r\n height: 16px;\r\n border-radius: 50%;\r\n outline: 0;\r\n}\r\n\r\n::-webkit-color-swatch {\r\n border: none;\r\n}\r\n\r\n.tooltip {\r\n position: relative;\r\n display: inline-block;\r\n margin-left: 5px;\r\n padding-top: 2px;\r\n}\r\n\r\n.tooltip .tooltiptext {\r\n visibility: hidden;\r\n border: 1px solid #D4D4D4;\r\n border-radius: 1px;\r\n background: #fff;\r\n font-size: 10px;\r\n padding: 8px;\r\n width: 200px;\r\n position: absolute;\r\n z-index: 1;\r\n right: -100px;\r\n top: 20px;\r\n}\r\n\r\n.tooltip:hover .tooltiptext {\r\n visibility: visible;\r\n}\r\n\r\n.tooltiptext ol {\r\n padding: 0px 8px;\r\n margin: 0px;\r\n}\r\n\r\n.tooltiptext li {\r\n margin-top: 8px;\r\n}\r\n\r\n.parameter {\r\n width: 100%;\r\n\tfont-family: 'Benton Sans', Arial, Helvetica, sans-serif;\r\n\tfont-size: 12px;\r\n\tpadding-left:6px;\r\n\tborder: solid 1px #CBCBCB;\r\n}\r\n\r\n.parameter option {\r\n\tpadding: 2px 2px 1px;\r\n\theight: 20px;\r\n\tdisplay:flex;\r\n\talign-items: center;\r\n}\r\n\r\n.singleParameter {\r\n width: 100%;\r\n\tmin-height: 20px !important;\r\n}\r\n\r\n.dropdown-select {\r\n flex: 1;\r\n margin-left: 0;\r\n width: '100%';\r\n}\r\n\r\n.delimiter-text-field > input {\r\n font-family: 'Benton Sans', Arial, Helvetica, sans-serif;\r\n padding-right: 0;\r\n text-align: center;\r\n}\r\n\r\n/* Internet Explorer 10+ */\r\nselect::-ms-expand {\r\n visibility: hidden;\r\n}","html,\r\nbody {\r\n margin: 0;\r\n padding: 0;\r\n height: 100%;\r\n width: 100%;\r\n color: #585858;\r\n border: 0;\r\n}\r\n\r\n.icontainer {\r\n font-size: 18px;\r\n background: #FAFAFA;\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n height: 100%;\r\n}\r\n\r\n.box {\r\n background: #ffffff;\r\n max-width: 1250px;\r\n margin: 20px;\r\n display: flex;\r\n box-shadow: 2px 4px 8px rgba(102, 162, 222, 0.15);\r\n}\r\n\r\n.left {\r\n background: linear-gradient(to bottom left, #02B3A4, #66A2DE);\r\n padding: 40px;\r\n width: 450px;\r\n color: #ffffff;\r\n display: flex;\r\n align-items: center;\r\n align-content: center;\r\n justify-content: flex-start;\r\n flex-wrap: wrap;\r\n font-size: 20px;\r\n font-family: 'Benton Sans', Arial, Helvetica, sans-serif;\r\n}\r\n\r\n.right {\r\n padding: 40px;\r\n display: flex;\r\n align-items: center;\r\n align-content: center;\r\n justify-content: flex-start;\r\n flex-wrap: wrap;\r\n}\r\n\r\n.iheader {\r\n font-size: 64px;\r\n font-family: 'Bookman Old Style', Arial, Helvetica, sans-serif;\r\n margin: 10px 0px;\r\n line-height: 54px;\r\n}\r\n\r\n.big {\r\n font-size: 28px;\r\n width: 100%;\r\n margin: 5px 0px;\r\n}\r\n\r\na {\r\n color: #02B3A4;\r\n font-weight: bold;\r\n text-decoration: none;\r\n}\r\n\r\na:hover {\r\n text-decoration: underline;\r\n}\r\n\r\n.gh {\r\n font-size: 16px;\r\n text-align: center;\r\n width: 100%;\r\n}"]}
--------------------------------------------------------------------------------
/docs/2.1.0/static/js/runtime~main.0d9ba244.js:
--------------------------------------------------------------------------------
1 | !function(e){function r(r){for(var n,i,a=r[0],f=r[1],l=r[2],c=0,s=[];cData-Driven Parameters Extension
--------------------------------------------------------------------------------
/docs/2.latest/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "Data-Driven Parameters",
3 | "name": "Data-Driven Parameters",
4 | "icons": [{
5 | "src": "favicon.ico",
6 | "sizes": "64x64 32x32 24x24 16x16",
7 | "type": "image/x-icon"
8 | }],
9 | "start_url": ".",
10 | "display": "standalone",
11 | "theme_color": "#000000",
12 | "background_color": "#ffffff"
13 | }
--------------------------------------------------------------------------------
/docs/2.latest/precache-manifest.d75aafc2866f2a41c3713ec81c2e13c8.js:
--------------------------------------------------------------------------------
1 | self.__precacheManifest = (self.__precacheManifest || []).concat([
2 | {
3 | "revision": "088fb8c76e828a8f268a7df1720d7021",
4 | "url": "/extension-data-driven-parameters/2.latest/index.html"
5 | },
6 | {
7 | "revision": "fac8b5bc0a696e7a392e",
8 | "url": "/extension-data-driven-parameters/2.latest/static/css/main.673a05ca.chunk.css"
9 | },
10 | {
11 | "revision": "09254fd0a08a7b9bf518",
12 | "url": "/extension-data-driven-parameters/2.latest/static/js/2.51c5d46f.chunk.js"
13 | },
14 | {
15 | "revision": "fac8b5bc0a696e7a392e",
16 | "url": "/extension-data-driven-parameters/2.latest/static/js/main.3aea75ac.chunk.js"
17 | },
18 | {
19 | "revision": "1c7dd2cc5b7c2c522bac",
20 | "url": "/extension-data-driven-parameters/2.latest/static/js/runtime~main.e725b044.js"
21 | }
22 | ]);
--------------------------------------------------------------------------------
/docs/2.latest/service-worker.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Welcome to your Workbox-powered service worker!
3 | *
4 | * You'll need to register this file in your web app and you should
5 | * disable HTTP caching for this file too.
6 | * See https://goo.gl/nhQhGp
7 | *
8 | * The rest of the code is auto-generated. Please don't update this file
9 | * directly; instead, make changes to your Workbox build configuration
10 | * and re-run your build process.
11 | * See https://goo.gl/2aRDsh
12 | */
13 |
14 | importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js");
15 |
16 | importScripts(
17 | "/extension-data-driven-parameters/2.latest/precache-manifest.d75aafc2866f2a41c3713ec81c2e13c8.js"
18 | );
19 |
20 | self.addEventListener('message', (event) => {
21 | if (event.data && event.data.type === 'SKIP_WAITING') {
22 | self.skipWaiting();
23 | }
24 | });
25 |
26 | workbox.core.clientsClaim();
27 |
28 | /**
29 | * The workboxSW.precacheAndRoute() method efficiently caches and responds to
30 | * requests for URLs in the manifest.
31 | * See https://goo.gl/S9QRab
32 | */
33 | self.__precacheManifest = [].concat(self.__precacheManifest || []);
34 | workbox.precaching.precacheAndRoute(self.__precacheManifest, {});
35 |
36 | workbox.routing.registerNavigationRoute(workbox.precaching.getCacheKeyForURL("/extension-data-driven-parameters/2.latest/index.html"), {
37 |
38 | blacklist: [/^\/_/,/\/[^/]+\.[^/]+$/],
39 | });
40 |
--------------------------------------------------------------------------------
/docs/2.latest/static/css/main.673a05ca.chunk.css:
--------------------------------------------------------------------------------
1 | body,html{font-family:Benton Sans,Arial,Helvetica,sans-serif;font-size:12px;color:rgba(0,0,0,.8);box-sizing:border-box;overflow:hidden}#container{height:100%;width:100%}.container{display:flex;flex-direction:column;justify-content:space-between;height:100%}.content{margin-left:6px}.header{font-size:16px;padding:12px 0 12px 18px;display:flex}.header,.title{color:rgba(0,0,0,.8)}.title{font-family:Benton Sans Medium,Arial,Helvetica,sans-serif;font-size:12px;margin:30px 0 18px}p{margin:0}.selected,.selector{display:flex;min-height:26px;margin-bottom:12px}.selected{margin-left:10px;justify-content:space-between}.option,.selected{align-items:center}.option{display:flex;margin-top:12px}.footer{display:flex;align-items:flex-end;margin:0 18px}.btncluster{display:flex;justify-content:flex-end;width:100%;margin-bottom:12px}.format{display:flex;margin-top:12px}.formattext{width:130px}input[type=color]{padding:0;margin-left:6px;border:1px solid #666;box-shadow:none;width:16px;height:16px;border-radius:50%;outline:0}::-webkit-color-swatch{border:none}.tooltip{position:relative;display:inline-block;margin-left:5px;padding-top:2px}.tooltip .tooltiptext{visibility:hidden;border:1px solid #d4d4d4;border-radius:1px;background:#fff;font-size:10px;padding:8px;width:200px;position:absolute;z-index:1;right:-100px;top:20px}.tooltip:hover .tooltiptext{visibility:visible}.tooltiptext ol{padding:0 8px;margin:0}.tooltiptext li{margin-top:8px}.parameter{width:100%;font-family:Benton Sans,Arial,Helvetica,sans-serif;font-size:12px;padding-left:6px;border:1px solid #cbcbcb}.parameter option{padding:2px 2px 1px;height:20px;display:flex;align-items:center}.singleParameter{width:100%;min-height:20px!important}.dropdown-select{flex:1 1;margin-left:0;width:"100%"}.delimiter-text-field>input{font-family:Benton Sans,Arial,Helvetica,sans-serif;padding-right:0;text-align:center}select::-ms-expand{visibility:hidden}body,html{margin:0;padding:0;height:100%;width:100%;color:#585858;border:0}.icontainer{font-size:18px;background:#fafafa;display:flex;justify-content:center;align-items:center;height:100%}.box{background:#fff;max-width:1250px;margin:20px;display:flex;box-shadow:2px 4px 8px rgba(102,162,222,.15)}.left{background:-webkit-gradient(linear,right top,left bottom,from(#02b3a4),to(#66a2de));background:linear-gradient(to bottom left,#02b3a4,#66a2de);width:450px;color:#fff;font-size:20px;font-family:Benton Sans,Arial,Helvetica,sans-serif}.left,.right{padding:40px;display:flex;align-items:center;align-content:center;justify-content:flex-start;flex-wrap:wrap}.iheader{font-size:64px;font-family:Bookman Old Style,Arial,Helvetica,sans-serif;margin:10px 0;line-height:54px}.big{font-size:28px;width:100%;margin:5px 0}a{color:#02b3a4;font-weight:700;text-decoration:none}a:hover{text-decoration:underline}.gh{font-size:16px;text-align:center;width:100%}
2 | /*# sourceMappingURL=main.673a05ca.chunk.css.map */
--------------------------------------------------------------------------------
/docs/2.latest/static/css/main.673a05ca.chunk.css.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["style.css","home.css"],"names":[],"mappings":"AAAA,UAII,kDAAwD,CACxD,cAAe,CACf,oBAAyB,CACzB,qBAAsB,CAGtB,eACJ,CAEA,WACI,WAAY,CACZ,UACJ,CAEA,WACI,YAAa,CACb,qBAAsB,CACtB,6BAA8B,CAC9B,WACJ,CAEA,SACI,eACJ,CAEA,QACI,cAAe,CAElB,wBAA2B,CACxB,YACJ,CAEA,eALI,oBAUJ,CALA,OACI,yDAA+D,CAC/D,cAAe,CAEf,kBACJ,CAEA,EACI,QACJ,CAQA,oBALI,YAAa,CACb,eAAgB,CAChB,kBAUJ,CAPA,UACI,gBAAiB,CAGjB,6BAGJ,CAEA,kBAJI,kBAQJ,CAJA,QACI,YAAa,CAEb,eACJ,CAEA,QACI,YAAa,CACb,oBAAqB,CACxB,aACD,CAEA,YACI,YAAa,CACb,wBAAyB,CACzB,UAAW,CACX,kBACJ,CAEA,QACI,YAAa,CACb,eACJ,CAEA,YACI,WACJ,CAEA,kBAEI,SAAU,CACV,eAAgB,CAChB,qBAAyB,CACzB,eAAgB,CAChB,UAAW,CACX,WAAY,CACZ,iBAAkB,CAClB,SACJ,CAEA,uBACI,WACJ,CAEA,SACI,iBAAkB,CAClB,oBAAqB,CACrB,eAAgB,CAChB,eACJ,CAEA,sBACI,iBAAkB,CAClB,wBAAyB,CACzB,iBAAkB,CAClB,eAAgB,CAChB,cAAe,CACf,WAAY,CACZ,WAAY,CACZ,iBAAkB,CAClB,SAAU,CACV,YAAa,CACb,QACJ,CAEA,4BACI,kBACJ,CAEA,gBACI,aAAgB,CAChB,QACJ,CAEA,gBACI,cACJ,CAEA,WACI,UAAW,CACd,kDAAwD,CACxD,cAAe,CACf,gBAAgB,CAChB,wBACD,CAEA,kBACC,mBAAoB,CACpB,WAAY,CACZ,YAAY,CACZ,kBACD,CAEA,iBACI,UAAW,CACd,yBACD,CAEA,iBACI,QAAO,CACP,aAAc,CACd,YACJ,CAEA,4BACI,kDAAwD,CACxD,eAAgB,CAChB,iBACJ,CAGA,mBACI,iBACJ,CC/KA,UAEI,QAAS,CACT,SAAU,CACV,WAAY,CACZ,UAAW,CACX,aAAc,CACd,QACJ,CAEA,YACI,cAAe,CACf,kBAAmB,CACnB,YAAa,CACb,sBAAuB,CACvB,kBAAmB,CACnB,WACJ,CAEA,KACI,eAAmB,CACnB,gBAAiB,CACjB,WAAY,CACZ,YAAa,CACb,4CACJ,CAEA,MACI,mFAA6D,CAA7D,0DAA6D,CAE7D,WAAY,CACZ,UAAc,CAMd,cAAe,CACf,kDACJ,CAEA,aAZI,YAAa,CAGb,YAAa,CACb,kBAAmB,CACnB,oBAAqB,CACrB,0BAA2B,CAC3B,cAYJ,CAEA,SACI,cAAe,CACf,wDAA8D,CAC9D,aAAgB,CAChB,gBACJ,CAEA,KACI,cAAe,CACf,UAAW,CACX,YACJ,CAEA,EACI,aAAc,CACd,eAAiB,CACjB,oBACJ,CAEA,QACI,yBACJ,CAEA,IACI,cAAe,CACf,iBAAkB,CAClB,UACJ","file":"main.673a05ca.chunk.css","sourcesContent":["html,\r\nbody {\r\n margin: 0;\r\n padding: 0;\r\n font-family: 'Benton Sans', Arial, Helvetica, sans-serif;\r\n font-size: 12px;\r\n color: rgba(0, 0, 0, 0.8);\r\n box-sizing: border-box;\r\n height: 100%;\r\n width: 100%;\r\n overflow: hidden;\r\n}\r\n\r\n#container {\r\n height: 100%;\r\n width: 100%;\r\n}\r\n\r\n.container {\r\n display: flex;\r\n flex-direction: column;\r\n justify-content: space-between;\r\n height: 100%;\r\n}\r\n\r\n.content {\r\n margin-left: 6px;\r\n}\r\n\r\n.header {\r\n font-size: 16px;\r\n color: rgba(0, 0, 0, 0.8);\r\n\tpadding: 12px 0px 12px 18px;\r\n display: flex;\r\n}\r\n\r\n.title {\r\n font-family: 'Benton Sans Medium', Arial, Helvetica, sans-serif;\r\n font-size: 12px;\r\n color: rgba(0, 0, 0, 0.8);\r\n margin: 30px 0px 18px 0px;\r\n}\r\n\r\np {\r\n margin: 0;\r\n}\r\n\r\n.selector {\r\n display: flex;\r\n min-height: 26px;\r\n margin-bottom: 12px;\r\n}\r\n\r\n.selected {\r\n margin-left: 10px;\r\n min-height: 26px;\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n margin-bottom: 12px;\r\n}\r\n\r\n.option {\r\n display: flex;\r\n align-items: center;\r\n margin-top: 12px;\r\n}\r\n\r\n.footer {\r\n display: flex;\r\n align-items: flex-end;\r\n\tmargin: 0px 18px;\r\n}\r\n\r\n.btncluster {\r\n display: flex;\r\n justify-content: flex-end;\r\n width: 100%;\r\n margin-bottom: 12px;\r\n}\r\n\r\n.format {\r\n display: flex;\r\n margin-top: 12px;\r\n}\r\n\r\n.formattext {\r\n width: 130px;\r\n}\r\n\r\ninput[type=\"color\"] {\r\n /* background-color: #fff; */\r\n padding: 0;\r\n margin-left: 6px;\r\n border: 1px solid #666666;\r\n box-shadow: none;\r\n width: 16px;\r\n height: 16px;\r\n border-radius: 50%;\r\n outline: 0;\r\n}\r\n\r\n::-webkit-color-swatch {\r\n border: none;\r\n}\r\n\r\n.tooltip {\r\n position: relative;\r\n display: inline-block;\r\n margin-left: 5px;\r\n padding-top: 2px;\r\n}\r\n\r\n.tooltip .tooltiptext {\r\n visibility: hidden;\r\n border: 1px solid #D4D4D4;\r\n border-radius: 1px;\r\n background: #fff;\r\n font-size: 10px;\r\n padding: 8px;\r\n width: 200px;\r\n position: absolute;\r\n z-index: 1;\r\n right: -100px;\r\n top: 20px;\r\n}\r\n\r\n.tooltip:hover .tooltiptext {\r\n visibility: visible;\r\n}\r\n\r\n.tooltiptext ol {\r\n padding: 0px 8px;\r\n margin: 0px;\r\n}\r\n\r\n.tooltiptext li {\r\n margin-top: 8px;\r\n}\r\n\r\n.parameter {\r\n width: 100%;\r\n\tfont-family: 'Benton Sans', Arial, Helvetica, sans-serif;\r\n\tfont-size: 12px;\r\n\tpadding-left:6px;\r\n\tborder: solid 1px #CBCBCB;\r\n}\r\n\r\n.parameter option {\r\n\tpadding: 2px 2px 1px;\r\n\theight: 20px;\r\n\tdisplay:flex;\r\n\talign-items: center;\r\n}\r\n\r\n.singleParameter {\r\n width: 100%;\r\n\tmin-height: 20px !important;\r\n}\r\n\r\n.dropdown-select {\r\n flex: 1;\r\n margin-left: 0;\r\n width: '100%';\r\n}\r\n\r\n.delimiter-text-field > input {\r\n font-family: 'Benton Sans', Arial, Helvetica, sans-serif;\r\n padding-right: 0;\r\n text-align: center;\r\n}\r\n\r\n/* Internet Explorer 10+ */\r\nselect::-ms-expand {\r\n visibility: hidden;\r\n}","html,\r\nbody {\r\n margin: 0;\r\n padding: 0;\r\n height: 100%;\r\n width: 100%;\r\n color: #585858;\r\n border: 0;\r\n}\r\n\r\n.icontainer {\r\n font-size: 18px;\r\n background: #FAFAFA;\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n height: 100%;\r\n}\r\n\r\n.box {\r\n background: #ffffff;\r\n max-width: 1250px;\r\n margin: 20px;\r\n display: flex;\r\n box-shadow: 2px 4px 8px rgba(102, 162, 222, 0.15);\r\n}\r\n\r\n.left {\r\n background: linear-gradient(to bottom left, #02B3A4, #66A2DE);\r\n padding: 40px;\r\n width: 450px;\r\n color: #ffffff;\r\n display: flex;\r\n align-items: center;\r\n align-content: center;\r\n justify-content: flex-start;\r\n flex-wrap: wrap;\r\n font-size: 20px;\r\n font-family: 'Benton Sans', Arial, Helvetica, sans-serif;\r\n}\r\n\r\n.right {\r\n padding: 40px;\r\n display: flex;\r\n align-items: center;\r\n align-content: center;\r\n justify-content: flex-start;\r\n flex-wrap: wrap;\r\n}\r\n\r\n.iheader {\r\n font-size: 64px;\r\n font-family: 'Bookman Old Style', Arial, Helvetica, sans-serif;\r\n margin: 10px 0px;\r\n line-height: 54px;\r\n}\r\n\r\n.big {\r\n font-size: 28px;\r\n width: 100%;\r\n margin: 5px 0px;\r\n}\r\n\r\na {\r\n color: #02B3A4;\r\n font-weight: bold;\r\n text-decoration: none;\r\n}\r\n\r\na:hover {\r\n text-decoration: underline;\r\n}\r\n\r\n.gh {\r\n font-size: 16px;\r\n text-align: center;\r\n width: 100%;\r\n}"]}
--------------------------------------------------------------------------------
/docs/2.latest/static/js/runtime~main.e725b044.js:
--------------------------------------------------------------------------------
1 | !function(e){function r(r){for(var n,a,i=r[0],l=r[1],f=r[2],c=0,s=[];cData-Driven Parameters Extension
--------------------------------------------------------------------------------
/docs/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "Data-Driven Parameters",
3 | "name": "Data-Driven Parameters",
4 | "icons": [{
5 | "src": "favicon.ico",
6 | "sizes": "64x64 32x32 24x24 16x16",
7 | "type": "image/x-icon"
8 | }],
9 | "start_url": ".",
10 | "display": "standalone",
11 | "theme_color": "#000000",
12 | "background_color": "#ffffff"
13 | }
--------------------------------------------------------------------------------
/docs/precache-manifest.8f5c5c66632ab1c8eb2b9ab4c458256a.js:
--------------------------------------------------------------------------------
1 | self.__precacheManifest = (self.__precacheManifest || []).concat([
2 | {
3 | "revision": "cf10014de9c1b3deba70f406fa002a1e",
4 | "url": "/extension-data-driven-parameters/index.html"
5 | },
6 | {
7 | "revision": "25bb9a99b7d45da3060b",
8 | "url": "/extension-data-driven-parameters/static/css/main.cb967471.chunk.css"
9 | },
10 | {
11 | "revision": "4c8bd9850eaae52f864b",
12 | "url": "/extension-data-driven-parameters/static/js/2.bbca4fae.chunk.js"
13 | },
14 | {
15 | "revision": "25bb9a99b7d45da3060b",
16 | "url": "/extension-data-driven-parameters/static/js/main.ae08df8d.chunk.js"
17 | },
18 | {
19 | "revision": "a4a54d5146f2dbde5fc0",
20 | "url": "/extension-data-driven-parameters/static/js/runtime~main.01d56cb3.js"
21 | }
22 | ]);
--------------------------------------------------------------------------------
/docs/service-worker.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Welcome to your Workbox-powered service worker!
3 | *
4 | * You'll need to register this file in your web app and you should
5 | * disable HTTP caching for this file too.
6 | * See https://goo.gl/nhQhGp
7 | *
8 | * The rest of the code is auto-generated. Please don't update this file
9 | * directly; instead, make changes to your Workbox build configuration
10 | * and re-run your build process.
11 | * See https://goo.gl/2aRDsh
12 | */
13 |
14 | importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js");
15 |
16 | importScripts(
17 | "/extension-data-driven-parameters/precache-manifest.8f5c5c66632ab1c8eb2b9ab4c458256a.js"
18 | );
19 |
20 | self.addEventListener('message', (event) => {
21 | if (event.data && event.data.type === 'SKIP_WAITING') {
22 | self.skipWaiting();
23 | }
24 | });
25 |
26 | workbox.core.clientsClaim();
27 |
28 | /**
29 | * The workboxSW.precacheAndRoute() method efficiently caches and responds to
30 | * requests for URLs in the manifest.
31 | * See https://goo.gl/S9QRab
32 | */
33 | self.__precacheManifest = [].concat(self.__precacheManifest || []);
34 | workbox.precaching.precacheAndRoute(self.__precacheManifest, {});
35 |
36 | workbox.routing.registerNavigationRoute(workbox.precaching.getCacheKeyForURL("/extension-data-driven-parameters/index.html"), {
37 |
38 | blacklist: [/^\/_/,/\/[^\/]+\.[^\/]+$/],
39 | });
40 |
--------------------------------------------------------------------------------
/docs/static/css/main.cb967471.chunk.css:
--------------------------------------------------------------------------------
1 | body,html{font-family:Benton Sans,Arial,Helvetica,sans-serif;font-size:12px;color:rgba(0,0,0,.8);box-sizing:border-box;overflow:hidden}#container{height:100%;width:100%}.container{padding:0 18px;display:flex;flex-direction:column;justify-content:space-between;height:100%}.content{margin-left:10px}.header{font-size:16px;margin-top:12px;display:flex}.header,.title{color:rgba(0,0,0,.8)}.title{font-family:Benton Sans Medium,Arial,Helvetica,sans-serif;font-size:12px;margin:30px 0 18px}p{margin:0}.selected,.selector{display:flex;min-height:26px;margin-bottom:12px}.selected{margin-left:10px;justify-content:space-between}.option,.selected{align-items:center}.option{display:flex;margin-top:12px}.footer{display:flex;align-items:flex-end}.btncluster{display:flex;justify-content:flex-end;align-items:center;width:100%;margin-bottom:12px}.format{display:flex;margin-top:12px}.formattext{width:130px}input[type=color]{padding:0;margin-left:6px;border:1px solid #666;box-shadow:none;width:16px;height:16px;border-radius:50%;outline:0}::-webkit-color-swatch{border:none}.tooltip{position:relative;display:inline-block;margin-left:5px;padding-top:2px}.tooltip .tooltiptext{visibility:hidden;border:1px solid #d4d4d4;border-radius:1px;background:#fff;font-size:10px;padding:8px;width:200px;position:absolute;z-index:1;right:-100px;top:20px}.tooltip:hover .tooltiptext{visibility:visible}.tooltiptext ol{padding:0 8px;margin:0}.tooltiptext li{margin-top:8px}.parameter{width:100%;font-family:Benton Sans,Arial,Helvetica,sans-serif;font-size:12px;padding-left:6px;border:1px solid #cbcbcb}.parameter option{padding:2px 2px 1px;height:20px;display:flex;align-items:center}.singleParameter{width:100%}.dropdown-select{flex:1 1;margin-left:0;width:"100%"}.delimiter-text-field>input{font-family:Benton Sans,Arial,Helvetica,sans-serif;padding-right:0;text-align:center}select::-ms-expand{visibility:hidden}body,html{margin:0;padding:0;height:100%;width:100%;color:#585858;border:0}.icontainer{font-size:18px;background:#fafafa;display:flex;justify-content:center;align-items:center;height:100%}.box{background:#fff;max-width:1250px;margin:20px;display:flex;box-shadow:2px 4px 8px rgba(102,162,222,.15)}.left{background:-webkit-gradient(linear,right top,left bottom,from(#02b3a4),to(#66a2de));background:-webkit-linear-gradient(top right,#02b3a4,#66a2de);background:linear-gradient(to bottom left,#02b3a4,#66a2de);width:450px;color:#fff;font-size:20px;font-family:Benton Sans,Arial,Helvetica,sans-serif}.left,.right{padding:40px;display:flex;align-items:center;align-content:center;justify-content:flex-start;flex-wrap:wrap}.iheader{font-size:64px;font-family:Bookman Old Style,Arial,Helvetica,sans-serif;margin:10px 0;line-height:54px}.big{font-size:28px;width:100%;margin:5px 0}a{color:#02b3a4;font-weight:700;text-decoration:none}a:hover{text-decoration:underline}.gh{font-size:16px;text-align:center;width:100%}
2 | /*# sourceMappingURL=main.cb967471.chunk.css.map */
--------------------------------------------------------------------------------
/docs/static/css/main.cb967471.chunk.css.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["style.css","home.css"],"names":[],"mappings":"AAAA,UAII,kDAAwD,CACxD,cAAe,CACf,oBAAyB,CACzB,qBAAsB,CAGtB,eACJ,CAEA,WACI,WAAY,CACZ,UACJ,CAEA,WACI,cAA0B,CAC1B,YAAa,CACb,qBAAsB,CACtB,6BAA8B,CAC9B,WACJ,CAEA,SACI,gBACJ,CAEA,QACI,cAAe,CAEf,eAAgB,CAChB,YACJ,CAEA,eALI,oBAUJ,CALA,OACI,yDAA+D,CAC/D,cAAe,CAEf,kBACJ,CAEA,EACI,QACJ,CAQA,oBALI,YAAa,CACb,eAAgB,CAChB,kBAUJ,CAPA,UACI,gBAAiB,CAGjB,6BAGJ,CAEA,kBAJI,kBAQJ,CAJA,QACI,YAAa,CAEb,eACJ,CAEA,QACI,YAAa,CACb,oBACJ,CAEA,YACI,YAAa,CACb,wBAAyB,CAC5B,kBAAmB,CAChB,UAAW,CACX,kBACJ,CAEA,QACI,YAAa,CACb,eACJ,CAEA,YACI,WACJ,CAEA,kBAEI,SAAU,CACV,eAAgB,CAChB,qBAAyB,CACzB,eAAgB,CAChB,UAAW,CACX,WAAY,CACZ,iBAAkB,CAClB,SACJ,CAEA,uBACI,WACJ,CAEA,SACI,iBAAkB,CAClB,oBAAqB,CACrB,eAAgB,CAChB,eACJ,CAEA,sBACI,iBAAkB,CAClB,wBAAyB,CACzB,iBAAkB,CAClB,eAAgB,CAChB,cAAe,CACf,WAAY,CACZ,WAAY,CACZ,iBAAkB,CAClB,SAAU,CACV,YAAa,CACb,QACJ,CAEA,4BACI,kBACJ,CAEA,gBACI,aAAgB,CAChB,QACJ,CAEA,gBACI,cACJ,CAEA,WACI,UAAW,CACd,kDAAwD,CACxD,cAAe,CACf,gBAAgB,CAChB,wBACD,CAEA,kBACC,mBAAoB,CACpB,WAAY,CACZ,YAAY,CACZ,kBACD,CAEA,iBACI,UACJ,CAEA,iBACI,QAAO,CACP,aAAc,CACd,YACJ,CAEA,4BACI,kDAAwD,CACxD,eAAgB,CAChB,iBACJ,CAGA,mBACI,iBACJ,CC/KA,UAEI,QAAS,CACT,SAAU,CACV,WAAY,CACZ,UAAW,CACX,aAAc,CACd,QACJ,CAEA,YACI,cAAe,CACf,kBAAmB,CACnB,YAAa,CACb,sBAAuB,CACvB,kBAAmB,CACnB,WACJ,CAEA,KACI,eAAmB,CACnB,gBAAiB,CACjB,WAAY,CACZ,YAAa,CACb,4CACJ,CAEA,MACI,mFAA6D,CAA7D,6DAA6D,CAA7D,0DAA6D,CAE7D,WAAY,CACZ,UAAc,CAMd,cAAe,CACf,kDACJ,CAEA,aAZI,YAAa,CAGb,YAAa,CACb,kBAAmB,CACnB,oBAAqB,CACrB,0BAA2B,CAC3B,cAYJ,CAEA,SACI,cAAe,CACf,wDAA8D,CAC9D,aAAgB,CAChB,gBACJ,CAEA,KACI,cAAe,CACf,UAAW,CACX,YACJ,CAEA,EACI,aAAc,CACd,eAAiB,CACjB,oBACJ,CAEA,QACI,yBACJ,CAEA,IACI,cAAe,CACf,iBAAkB,CAClB,UACJ","file":"main.cb967471.chunk.css","sourcesContent":["html,\nbody {\n margin: 0;\n padding: 0;\n font-family: 'Benton Sans', Arial, Helvetica, sans-serif;\n font-size: 12px;\n color: rgba(0, 0, 0, 0.8);\n box-sizing: border-box;\n height: 100%;\n width: 100%;\n overflow: hidden;\n}\n\n#container {\n height: 100%;\n width: 100%;\n}\n\n.container {\n padding: 0px 18px 0px 18px;\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n height: 100%;\n}\n\n.content {\n margin-left: 10px;\n}\n\n.header {\n font-size: 16px;\n color: rgba(0, 0, 0, 0.8);\n margin-top: 12px;\n display: flex;\n}\n\n.title {\n font-family: 'Benton Sans Medium', Arial, Helvetica, sans-serif;\n font-size: 12px;\n color: rgba(0, 0, 0, 0.8);\n margin: 30px 0px 18px 0px;\n}\n\np {\n margin: 0;\n}\n\n.selector {\n display: flex;\n min-height: 26px;\n margin-bottom: 12px;\n}\n\n.selected {\n margin-left: 10px;\n min-height: 26px;\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 12px;\n}\n\n.option {\n display: flex;\n align-items: center;\n margin-top: 12px;\n}\n\n.footer {\n display: flex;\n align-items: flex-end;\n}\n\n.btncluster {\n display: flex;\n justify-content: flex-end;\n\talign-items: center;\n width: 100%;\n margin-bottom: 12px;\n}\n\n.format {\n display: flex;\n margin-top: 12px;\n}\n\n.formattext {\n width: 130px;\n}\n\ninput[type=\"color\"] {\n /* background-color: #fff; */\n padding: 0;\n margin-left: 6px;\n border: 1px solid #666666;\n box-shadow: none;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n outline: 0;\n}\n\n::-webkit-color-swatch {\n border: none;\n}\n\n.tooltip {\n position: relative;\n display: inline-block;\n margin-left: 5px;\n padding-top: 2px;\n}\n\n.tooltip .tooltiptext {\n visibility: hidden;\n border: 1px solid #D4D4D4;\n border-radius: 1px;\n background: #fff;\n font-size: 10px;\n padding: 8px;\n width: 200px;\n position: absolute;\n z-index: 1;\n right: -100px;\n top: 20px;\n}\n\n.tooltip:hover .tooltiptext {\n visibility: visible;\n}\n\n.tooltiptext ol {\n padding: 0px 8px;\n margin: 0px;\n}\n\n.tooltiptext li {\n margin-top: 8px;\n}\n\n.parameter {\n width: 100%;\n\tfont-family: 'Benton Sans', Arial, Helvetica, sans-serif;\n\tfont-size: 12px;\n\tpadding-left:6px;\n\tborder: solid 1px #CBCBCB;\n}\n\n.parameter option {\n\tpadding: 2px 2px 1px;\n\theight: 20px;\n\tdisplay:flex;\n\talign-items: center;\n}\n\n.singleParameter {\n width: 100%;\n}\n\n.dropdown-select {\n flex: 1;\n margin-left: 0;\n width: '100%';\n}\n\n.delimiter-text-field > input {\n font-family: 'Benton Sans', Arial, Helvetica, sans-serif;\n padding-right: 0;\n text-align: center;\n}\n\n/* Internet Explorer 10+ */\nselect::-ms-expand {\n visibility: hidden;\n}","html,\nbody {\n margin: 0;\n padding: 0;\n height: 100%;\n width: 100%;\n color: #585858;\n border: 0;\n}\n\n.icontainer {\n font-size: 18px;\n background: #FAFAFA;\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100%;\n}\n\n.box {\n background: #ffffff;\n max-width: 1250px;\n margin: 20px;\n display: flex;\n box-shadow: 2px 4px 8px rgba(102, 162, 222, 0.15);\n}\n\n.left {\n background: linear-gradient(to bottom left, #02B3A4, #66A2DE);\n padding: 40px;\n width: 450px;\n color: #ffffff;\n display: flex;\n align-items: center;\n align-content: center;\n justify-content: flex-start;\n flex-wrap: wrap;\n font-size: 20px;\n font-family: 'Benton Sans', Arial, Helvetica, sans-serif;\n}\n\n.right {\n padding: 40px;\n display: flex;\n align-items: center;\n align-content: center;\n justify-content: flex-start;\n flex-wrap: wrap;\n}\n\n.iheader {\n font-size: 64px;\n font-family: 'Bookman Old Style', Arial, Helvetica, sans-serif;\n margin: 10px 0px;\n line-height: 54px;\n}\n\n.big {\n font-size: 28px;\n width: 100%;\n margin: 5px 0px;\n}\n\na {\n color: #02B3A4;\n font-weight: bold;\n text-decoration: none;\n}\n\na:hover {\n text-decoration: underline;\n}\n\n.gh {\n font-size: 16px;\n text-align: center;\n width: 100%;\n}"]}
--------------------------------------------------------------------------------
/docs/static/js/main.ae08df8d.chunk.js:
--------------------------------------------------------------------------------
1 | (window.webpackJsonp=window.webpackJsonp||[]).push([[0],{133:function(e,t,a){},134:function(e,t,a){},139:function(e,t,a){"use strict";a.r(t);var n=a(13),l=a(14),i=a(16),s=a(15),r=a(17),o=(a(74),a(0)),c=a(69),u=a(18),d=a(72),m=a(1),h=function(e){return o.createElement("div",{className:"selected"},o.createElement("p",null,o.createElement("i",null,"The ",e.selecting," ",o.createElement("b",null,e.selected)," has been selected")),o.createElement(m.Button,{onClick:e.onClear,style:{visibility:e.nextConfig?"hidden":"visible",marginLeft:"12px"}},"Clear"))};h.displayName="Selected";var f=function(e){var t={className:"dropdown-select",disabled:!e.enabled,kind:"line",onChange:e.onChange,onSelect:e.onChange,value:e.selected},a={disabled:!e.enabled||""===e.selected,kind:"filledGreen",onClick:e.onClick,style:{marginLeft:"12px"}};return o.createElement("div",{className:"selector"},o.createElement(m.DropdownSelect,t,e.list.map(function(e){return o.createElement("option",{key:e},e)})),o.createElement(m.Button,a,"Set"))};f.displayName="Selector";var g,p=function(e){return o.createElement(o.Fragment,null,o.createElement("span",null,"Select a ",e.selecting),function(e){var t=e.config,a=e.enabled,n=e.list,l=e.nextConfig,i=e.onChange,s=e.onClear,r=e.onClick,c=e.selected,u=e.selecting;return t?o.createElement(h,{nextConfig:l,onClear:s,selected:c,selecting:u}):o.createElement(f,{enabled:a,list:n,onChange:i,onClick:r,selected:c})}(e))};p.displayName="Setting";var b,w,y="Loading...",v=function(e){function t(){var e,a;Object(n.a)(this,t);for(var l=arguments.length,r=new Array(l),o=0;o0?e.setState({param_enabled:!0,param_list:a,parameter:a[0]}):e.setState({param_enabled:!1,param_list:["No open input parameters found!"],parameter:"No open input parameters found!"})})}},{key:"testWSSettings",value:function(){var e=window.tableau.extensions.settings.getAll();this.state.configured?g.worksheets.find(function(t){return t.name===e.selWorksheet})?(this.setState({worksheet:e.selWorksheet,ws_config:!0,ws_enabled:!1}),this.testFieldSettings()):(this.populateWS(),this.setState({configured:!1})):this.populateWS()}},{key:"populateWS",value:function(){this.setState({worksheet:y,ws_list:[y]});var e=[],t=!0,a=!1,n=void 0;try{for(var l,i=g.worksheets[Symbol.iterator]();!(t=(l=i.next()).done);t=!0){var s=l.value;e.push(s.name)}}catch(r){a=!0,n=r}finally{try{t||null==i.return||i.return()}finally{if(a)throw n}}e.length>0?this.setState({worksheet:e[0],ws_enabled:!0,ws_list:e}):this.setState({worksheet:"No worksheets found!",ws_enabled:!1,ws_list:["No worksheets found!"]})}},{key:"testFieldSettings",value:function(){var e=this,t=window.tableau.extensions.settings.getAll();this.state.configured?g.worksheets.find(function(t){return t.name===e.state.worksheet}).getSummaryDataAsync().then(function(a){a.columns.find(function(e){return e.fieldName===t.selField})?e.setState({configured:!0,field:t.selField,field_config:!0,field_enabled:!1}):(e.populateFieldList(),e.setState({configured:!1}))}):this.populateFieldList()}},{key:"populateFieldList",value:function(){var e,t=this;this.setState({field:y,field_list:[y]}),g.findParameterAsync(this.state.parameter).then(function(a){return e=a.dataType,g.worksheets.find(function(e){return e.name===t.state.worksheet}).getSummaryDataAsync()}).then(function(a){var n=[],l=!0,i=!1,s=void 0;try{for(var r,o=a.columns[Symbol.iterator]();!(l=(r=o.next()).done);l=!0){var c=r.value;c.dataType===e&&n.push(c.fieldName)}}catch(u){i=!0,s=u}finally{try{l||null==o.return||o.return()}finally{if(i)throw s}}n.length>0?t.setState({field:n[0],field_enabled:!0,field_list:n}):t.setState({field:"No fields found that match parameter!",field_enabled:!1,field_list:["No fields found that match parameter!"]})})}},{key:"componentWillMount",value:function(){var e=this;window.tableau.extensions.initializeDialogAsync().then(function(){g=window.tableau.extensions.dashboardContent.dashboard;var t=window.tableau.extensions.settings.getAll();"true"===t.configured?(e.setState({autoUpdate:"true"===t.autoUpdate||!1,bg:t.bg||"#ffffff",configured:!0,dataType:t.dataType,delimiter:t.delimiter||"|",ignoreSelection:"true"===t.ignoreSelection||!1,includeAllValue:"true"===t.includeAllValue||!1,multiselect:"true"===t.multiselect||!1,sort:t.sort||"asc",txt:t.txt||"#000000",useFormattedValues:"true"===t.useFormattedValues||!1}),e.testParamSettings()):e.populateParamList()})}},{key:"render",value:function(){return o.createElement(o.Fragment,null,o.createElement("div",{className:"container"},o.createElement("div",null,o.createElement("div",{className:"header"},"Data-Driven Parameter Configuration",o.createElement("div",{className:"tooltip"},o.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",id:"Dialogs_x5F_Info",width:"15",height:"15",viewBox:"0 0 15 15"},o.createElement("rect",{id:"Line",x:"7",y:"6",width:"1",height:"5",fillRule:"evenodd",clipRule:"evenodd",fill:"#666766"}),o.createElement("rect",{id:"Dot_2_",x:"7",y:"4",width:"1",height:"1",fillRule:"evenodd",clipRule:"evenodd",fill:"#666766"}),o.createElement("path",{id:"Circle",d:"M7.5,1C3.9,1,1,3.9,1,7.5S3.9,14,7.5,14 S14,11.1,14,7.5S11.1,1,7.5,1z M7.5,13C4.5,13,2,10.5,2,7.5C2,4.5,4.5,2,7.5,2S13,4.5,13,7.5C13,10.5,10.5,13,7.5,13z",fillRule:"evenodd",clipRule:"evenodd",fill:"#666766"})),o.createElement("span",{className:"tooltiptext"},o.createElement("b",null,"How to Use"),o.createElement("ol",null,o.createElement("li",null,'Select a Tableau parameter to manipulate. This parameter must already exists and must allow "all" values.'),o.createElement("li",null,"Select a worksheet with the data you want to use in your parameter."),o.createElement("li",null,"Select a field to use to populate the parameter. Field data type must match the data type of parameter.")),o.createElement("br",null),o.createElement("p",null,"Note: Mac Desktop 2018.3 and lower, please use arrow keys and 'Enter' to select options")))),o.createElement("div",{className:"title",style:{marginTop:"18px"}},"Configure Parameter"),o.createElement("div",{className:"content"},o.createElement(p,{selecting:"parameter",onClick:this.setParam,onClear:this.clearParam,config:this.state.param_config,nextConfig:this.state.ws_config,selected:this.state.parameter,enabled:this.state.param_enabled&&!this.state.param_config,list:this.state.param_list,onChange:this.paramChange}),o.createElement(p,{selecting:"worksheet",onClick:this.setWS,onClear:this.clearWS,config:this.state.ws_config,nextConfig:this.state.field_config,selected:this.state.worksheet,enabled:this.state.ws_enabled,list:this.state.ws_list,onChange:this.wsChange}),o.createElement(p,{selecting:"field",onClick:this.setField,onClear:this.clearField,config:this.state.field_config,selected:this.state.field,enabled:this.state.field_enabled,list:this.state.field_list,onChange:this.fieldChange})),o.createElement("div",{className:"title"},"Options"),o.createElement("div",{className:"content"},o.createElement("div",{className:"option"},o.createElement(m.Checkbox,{checked:!this.state.ignoreSelection,onChange:this.ignoreSelectionChange,style:{flexGrow:1}},"Filter parameter list based on worksheet selections")),o.createElement("div",{className:"option"},o.createElement(m.Checkbox,{checked:this.state.useFormattedValues,onChange:this.aliasChange,style:{flexGrow:1}},"Use aliased values")),o.createElement("div",{className:"option"},o.createElement(m.Checkbox,{checked:this.state.autoUpdate,onChange:this.autoUpdateChange,style:{flexGrow:1}},"Automatically reset values on load.")),o.createElement("div",{className:"option"},"Sorting:",o.createElement(m.Radio,{checked:"asc"===this.state.sort,onChange:this.sortChange,name:"sorting",value:"asc",style:{margin:"0px 12px"}},"Ascending (A-Z)"),o.createElement(m.Radio,{checked:"desc"===this.state.sort,onChange:this.sortChange,name:"sorting",value:"desc",style:{margin:"0px 12px"}},"Descending (Z-A)")),o.createElement("div",{className:"option"},o.createElement("p",null,o.createElement("i",null,"For use with string parameters only:"))),o.createElement("div",{className:"option"},o.createElement(m.Checkbox,{disabled:"string"!==this.state.dataType,checked:this.state.includeAllValue,onChange:this.allChange,style:{flexGrow:1}},'Include "(All)" in parameter list ',o.createElement("br",null)," ",o.createElement("i",null,"Note: This is only a placeholder for calculations."))),o.createElement("div",{className:"option"},o.createElement(m.Checkbox,{disabled:"string"!==this.state.dataType,checked:this.state.multiselect,onChange:this.multiselectChange,style:{marginRight:"10px"}},"Allow for multiple selections."),o.createElement("span",{children:"Delimiter:",style:{marginRight:"5px"}}),o.createElement(m.TextField,{kind:"line",onChange:this.delimiterChange,className:"delimiter-text-field",value:this.state.delimiter,disabled:!this.state.multiselect||"string"!==this.state.dataType,maxLength:1,style:{width:20}}))),o.createElement("div",{className:"title"},"Formatting"),o.createElement("div",{className:"content"},o.createElement("div",{className:"format"},o.createElement("div",{className:"formattext"},"Background Color"),o.createElement("div",null,o.createElement("input",{type:"color",value:this.state.bg,onChange:this.bgChange,style:{backgroundColor:this.state.bg}}))),o.createElement("div",{className:"format"},o.createElement("div",{className:"formattext"},"Text Color"),o.createElement("div",null,o.createElement("input",{type:"color",value:this.state.txt,onChange:this.txtChange,style:{backgroundColor:this.state.txt}}))))),o.createElement("div",{className:"footer"},o.createElement("div",{className:"btncluster"},o.createElement(m.Button,{onClick:this.clearSettings,style:{marginRight:"auto"}},"Clear Settings"),o.createElement("a",{href:"https://extensiongallery.tableau.com/products/27",target:"_blank",rel:"noopener noreferrer"},"Version 2.0 available"),o.createElement(m.Button,{kind:"filledGreen",onClick:this.submit,disabled:!this.state.configured||!this.state.ws_config,style:{marginLeft:"12px"}},"OK")))))}}]),t}(o.Component),E=(a(133),"Parameter needs configuration");function x(e){var t=function(e){var t=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return t?{b:parseInt(t[3],16),g:parseInt(t[2],16),r:parseInt(t[1],16)}:null}(e);return t?"rgb(".concat(Math.min(Math.floor(t.r/2)+127,255),", ").concat(Math.min(Math.floor(t.g/2)+127,255),", ").concat(Math.min(Math.floor(t.b/2)+127,255),")"):"#ffffff"}var S=function(e){function t(){var e,a;Object(n.a)(this,t);for(var l=arguments.length,r=new Array(l),o=0;o0.2%",
35 | "not dead",
36 | "not op_mini all"
37 | ],
38 | "development": [
39 | "ie 11",
40 | "last 1 chrome version",
41 | "last 1 firefox version",
42 | "last 1 safari version"
43 | ]
44 | },
45 | "devDependencies": {
46 | "@types/enzyme": "^3.10.3",
47 | "enzyme": "^3.10.0",
48 | "enzyme-adapter-react-16": "^1.14.0"
49 | },
50 | "resolutions": {
51 | "ssri": "^6.0.2",
52 | "is-svg": "^4.2.2",
53 | "react-dev-utils": "^11.0.4",
54 | "immer": "^8.0.1",
55 | "node-notifier": "^8.0.1",
56 | "object-path": "^0.11.5",
57 | "node-forge": "^0.10.0",
58 | "url-parse": "^1.5.1",
59 | "hosted-git-info": "^2.8.9",
60 | "postcss": "^8.2.10",
61 | "lodash": "^4.17.21",
62 | "browserslist": "^4.16.5",
63 | "dns-packet": "^1.3.4"
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tableau/extension-data-driven-parameters/3a97c522fb3cf36bd389366ef7626066f679345f/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Data-Driven Parameters Extension
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "Data-Driven Parameters",
3 | "name": "Data-Driven Parameters",
4 | "icons": [{
5 | "src": "favicon.ico",
6 | "sizes": "64x64 32x32 24x24 16x16",
7 | "type": "image/x-icon"
8 | }],
9 | "start_url": ".",
10 | "display": "standalone",
11 | "theme_color": "#000000",
12 | "background_color": "#ffffff"
13 | }
--------------------------------------------------------------------------------
/sandboxed/DataDrivenParameters_Sandboxed.trex:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | en_US
5 |
6 | Automatically update your parameters based on your data!
7 |
8 | 0.9
9 |
10 | https://extensions.tableauusercontent.com/sandbox/data-driven-parameters/index.html
11 |
12 | iVBORw0KGgoAAAANSUhEUgAAAEYAAABGCAYAAABxLuKEAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFHGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDUgNzkuMTYzNDk5LCAyMDE4LzA4LzEzLTE2OjQwOjIyICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDE5LTAyLTA2VDE0OjE4OjQ5LTA4OjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAxOS0wMi0wNlQxNDoxOToxNS0wODowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAxOS0wMi0wNlQxNDoxOToxNS0wODowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo3ZjJhNDI0YS02YzY2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
13 |
14 |
15 |
16 |
17 |
18 |
19 | Data-Driven Parameter
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/sandboxed/DataDrivenParameters_Sandboxed_Test.trex:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | en_US
5 |
6 | Automatically update your parameters based on your data!
7 |
8 | 0.9
9 |
10 | http://localhost:8080/sandbox/data-driven-parameters/index.html
11 |
12 | iVBORw0KGgoAAAANSUhEUgAAAEYAAABGCAYAAABxLuKEAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFHGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDUgNzkuMTYzNDk5LCAyMDE4LzA4LzEzLTE2OjQwOjIyICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDE5LTAyLTA2VDE0OjE4OjQ5LTA4OjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAxOS0wMi0wNlQxNDoxOToxNS0wODowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAxOS0wMi0wNlQxNDoxOToxNS0wODowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo3ZjJhNDI0YS02YzY2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
13 |
14 |
15 |
16 |
17 |
18 |
19 | Data-Driven Parameter
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/sandboxed/config-overrides.js:
--------------------------------------------------------------------------------
1 | const multipleEntry = require('react-app-rewire-multiple-entry')(
2 | [{
3 | entry: 'src/entry_index.tsx',
4 | template: 'public/index.html',
5 | outPath: '/index.html'
6 | },
7 | {
8 | entry: 'src/entry_config.tsx',
9 | template: 'public/config.html',
10 | outPath: '/config.html'
11 | }
12 | ]
13 | );
14 |
15 | module.exports = {
16 | webpack: function (config, env) {
17 | multipleEntry.addMultiEntry(config);
18 | return config;
19 | },
20 | devServer: function (configFunction) {
21 | multipleEntry.addEntryProxy(configFunction);
22 | return configFunction;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/sandboxed/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "port": 8080,
3 | "extensions": {
4 | "data-driven-parameters": {
5 | "path": "./build"
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/sandboxed/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "data-driven-parameters",
3 | "version": "1.0.0",
4 | "private": true,
5 | "homepage": ".",
6 | "dependencies": {
7 | "@tableau/extensions-api-types": "^1.3.1",
8 | "@tableau/tabextsandbox": "^1.0.1",
9 | "@tableau/tableau-ui": "^2.2.1",
10 | "@types/jest": "^24.0.15",
11 | "@types/node": "^12.6.0",
12 | "@types/react": "^16.8.23",
13 | "@types/react-dom": "^16.8.4",
14 | "@types/react-router-dom": "^4.3.4",
15 | "react": "^16.8.6",
16 | "react-app-polyfill": "^1.0.1",
17 | "react-dom": "^16.8.6",
18 | "react-router-dom": "^5.0.1",
19 | "react-scripts": "^3.0.1",
20 | "typescript": "^3.5.2"
21 | },
22 | "scripts": {
23 | "start": "react-app-rewired start",
24 | "build": "react-app-rewired build",
25 | "test": "react-app-rewired test",
26 | "eject": "react-scripts eject"
27 | },
28 | "eslintConfig": {
29 | "extends": "react-app"
30 | },
31 | "browserslist": {
32 | "production": [
33 | ">0.2%",
34 | "not dead",
35 | "not op_mini all"
36 | ],
37 | "development": [
38 | "ie 11",
39 | "last 1 chrome version",
40 | "last 1 firefox version",
41 | "last 1 safari version"
42 | ]
43 | },
44 | "devDependencies": {
45 | "@types/enzyme": "^3.10.3",
46 | "enzyme": "^3.10.0",
47 | "enzyme-adapter-react-16": "^1.14.0",
48 | "react-app-rewire-multiple-entry": "^1.0.1",
49 | "react-app-rewired": "^2.1.3"
50 | },
51 | "resolutions": {
52 | "**/**/minimist": "^1.2.2",
53 | "ssri": "^6.0.2",
54 | "is-svg": "^4.2.2",
55 | "react-dev-utils": "^11.0.4",
56 | "immer": "^8.0.1",
57 | "node-notifier": "^8.0.1",
58 | "object-path": "^0.11.5",
59 | "node-forge": "^0.10.0",
60 | "url-parse": "^1.5.1",
61 | "hosted-git-info": "^2.8.9",
62 | "postcss": "^8.2.10",
63 | "lodash": "^4.17.21",
64 | "browserslist": "^4.16.5",
65 | "dns-packet": "^1.3.4"
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/sandboxed/public/config.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Configure Data-Driven Parameters Extension
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/sandboxed/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tableau/extension-data-driven-parameters/3a97c522fb3cf36bd389366ef7626066f679345f/sandboxed/public/favicon.ico
--------------------------------------------------------------------------------
/sandboxed/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Data-Driven Parameters Extension
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/sandboxed/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "Data-Driven Parameters",
3 | "name": "Data-Driven Parameters",
4 | "icons": [{
5 | "src": "favicon.ico",
6 | "sizes": "64x64 32x32 24x24 16x16",
7 | "type": "image/x-icon"
8 | }],
9 | "start_url": ".",
10 | "display": "standalone",
11 | "theme_color": "#000000",
12 | "background_color": "#ffffff"
13 | }
--------------------------------------------------------------------------------
/sandboxed/src/DataDrivenParameter.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import './style.css';
3 | import { Button, DropdownSelect } from '@tableau/tableau-ui';
4 | const tableau = window.tableau;
5 |
6 | let unregister = [() => { }, () => { }, () => { }, () => { }];
7 |
8 | interface State {
9 | allLabel: string,
10 | applyButton: boolean,
11 | applyButtonLabel: string,
12 | bg: string,
13 | configured: boolean,
14 | currentVal: any[],
15 | disabled: boolean,
16 | firstInit: boolean,
17 | list: any[],
18 | multiselect: boolean,
19 | }
20 |
21 | const NeedsConfiguring: any = { value: 'Parameter needs configuration', displayValue: 'Parameter needs configuration' };
22 | const Loading: any = { value: 'Loading...', displayValue: 'Loading...' };
23 |
24 | // Switches base URL based on where extension is being hosted
25 | const baseURL: string = window.location.origin.includes('localhost:3000') ? window.location.origin : '.';
26 |
27 | function fakeWhiteOverlay(hex: string) {
28 | const rgb = hexToRgb(hex);
29 | if (rgb) {
30 | return `rgb(${Math.min(Math.floor(rgb.r / 2) + 127, 255)}, ${Math.min(Math.floor(rgb.g / 2) + 127, 255)}, ${Math.min(Math.floor(rgb.b / 2) + 127, 255)})`;
31 | } else {
32 | return '#ffffff';
33 | }
34 | }
35 |
36 | function hexToRgb(hex: string) {
37 | const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
38 | return result ? {
39 | b: parseInt(result[3], 16),
40 | g: parseInt(result[2], 16),
41 | r: parseInt(result[1], 16),
42 | } : null;
43 | }
44 |
45 | class DataDrivenParameter extends React.Component {
46 | public readonly state: State = {
47 | allLabel: 'Apply',
48 | applyButton: false,
49 | applyButtonLabel: '(All)',
50 | bg: '#ffffff',
51 | configured: false,
52 | currentVal: [Loading],
53 | disabled: true,
54 | firstInit: true,
55 | list: [Loading],
56 | multiselect: false,
57 | };
58 |
59 | // Pops open the configure page
60 | public configure = (): void => {
61 | const popupUrl = `${baseURL}/config.html`;
62 | const payload = '';
63 | tableau.extensions.ui.displayDialogAsync(popupUrl, payload, { height: 610, width: 450 }).then((closePayload: string) => {
64 | this.setup();
65 | }).catch((error: any) => {
66 | if (tableau.extensions.settings.get('configured') !== 'true') {
67 | this.setState({
68 | currentVal: [NeedsConfiguring],
69 | disabled: true,
70 | list: [NeedsConfiguring],
71 | });
72 | }
73 | switch (error.errorCode) {
74 | case tableau.ErrorCodes.DialogClosedByUser:
75 | console.log('Dialog was closed by user.');
76 | break;
77 | default:
78 | console.error(error.message);
79 | }
80 | });
81 | }
82 |
83 | // Locates the parameter to update
84 | public findParameter() {
85 | const settings = tableau.extensions.settings.getAll();
86 | const dashboard = tableau.extensions.dashboardContent.dashboard;
87 | dashboard.findParameterAsync(settings.selParam).then((parameter: any) => {
88 | if (!parameter || parameter.allowableValues.type !== 'all') {
89 | this.setState({
90 | currentVal: [NeedsConfiguring],
91 | disabled: true,
92 | list: [NeedsConfiguring],
93 | });
94 | } else {
95 | this.getParamData();
96 | this.resetListeners();
97 | }
98 | });
99 | }
100 |
101 | // Gets the values from the selected field
102 | public getParamData = (): void => {
103 | const settings = tableau.extensions.settings.getAll();
104 | const dashboard = tableau.extensions.dashboardContent.dashboard;
105 | const worksheet = dashboard.worksheets.find((ws: any) => ws.name === settings.selWorksheet);
106 | if (!worksheet) {
107 | this.setState({
108 | currentVal: [NeedsConfiguring],
109 | disabled: true,
110 | list: [NeedsConfiguring],
111 | });
112 | } else {
113 | worksheet.getSummaryDataAsync({ ignoreSelection: settings.ignoreSelection === 'true' }).then((dataTable: any) => {
114 | this.populateParam(dataTable);
115 | });
116 | }
117 | }
118 |
119 | // Pulls domain of selected field
120 | public populateParam(dataTable: any) {
121 | const settings = tableau.extensions.settings.getAll();
122 | const field = dataTable.columns.find((column: any) => column.fieldName === settings.selField);
123 | this.setState({
124 | currentVal: [Loading],
125 | disabled: true,
126 | list: [Loading],
127 | });
128 |
129 | if (!field) {
130 | this.setState({
131 | currentVal: [NeedsConfiguring],
132 | disabled: true,
133 | list: [NeedsConfiguring],
134 | });
135 | } else {
136 | this.createList(field, dataTable);
137 | }
138 | }
139 |
140 | // Populate list with values from data source
141 | public createList(field: any, dataTable: any) {
142 | const settings = tableau.extensions.settings.getAll();
143 | const displayField = dataTable.columns.find((column: any) => column.fieldName === settings.displayField);
144 |
145 | let list: any[] = [];
146 | for (const row of dataTable.data) {
147 | const value = settings.useFormattedValues === 'true' ? row[field.index].formattedValue : row[field.index].value;
148 | let displayValue = value;
149 | if (displayField && settings.showDisplayValues === 'true') {
150 | displayValue = row[displayField.index].formattedValue
151 | }
152 | list.push({
153 | displayValue,
154 | value,
155 | });
156 | }
157 |
158 | // Remove duplicates
159 | list = list.filter((item, index, array) => array.indexOf(array.find(i => i.value === item.value)) === index);
160 |
161 | if (settings.dataType && (settings.dataType === 'int' || settings.dataType === 'float')) {
162 | // Convert to numbers for correct sort
163 | list = list.map((item) => ({ value: Number(item.value), displayValue: item.displayValue }))
164 | // Sort according to settings (numerical)
165 | if (settings.sort && settings.sort === 'desc') {
166 | list.sort((a, b) => b.value - a.value);
167 | } else {
168 | list.sort((a, b) => a.value - b.value);
169 | }
170 | if (settings.dataType === 'float') {
171 | list = list.map((item) => ({ value: item.value.toLocaleString(tableau.extensions.environment.locale), displayValue: item.displayValue }));
172 | }
173 | } else {
174 | // Sort according to settings
175 | if (settings.sort && settings.sort === 'desc') {
176 | list.sort((a, b) => a.value < b.value ? 1 : -1);
177 | } else {
178 | list.sort((a, b) => a.value > b.value ? 1 : -1);
179 | }
180 | }
181 |
182 | // Add '(All)' according to settings
183 | if (settings.includeAllValue === 'true') {
184 | list.unshift({ value: this.state.allLabel, displayValue: this.state.allLabel });
185 | }
186 |
187 | this.setState({
188 | list,
189 | }, this.setCurrentValue);
190 |
191 | }
192 |
193 | // Determine whether to use current param value or first value of list based on settings
194 | public setCurrentValue = (): void => {
195 | const settings = tableau.extensions.settings.getAll();
196 | const dashboard = tableau.extensions.dashboardContent.dashboard;
197 | const list = this.state.list;
198 | let currentVal: any[] = [];
199 | dashboard.findParameterAsync(settings.selParam).then((parameter: any) => {
200 | if ((this.state.firstInit && settings.autoUpdate === 'true')) {
201 | // Then push new values
202 | currentVal = [(settings.includeAllValue === 'true' ? list[1].value : list[0].value)];
203 | } else {
204 | // Then match parameter value
205 | if (settings.multiselect === 'true') {
206 | const tablist = [];
207 | for (const value of parameter.currentValue.value.split(settings.delimiter)) {
208 | if (list.find((v: any) => v.value.toString() === value || v.value === value)) {
209 | tablist.push(value);
210 | }
211 | }
212 | currentVal = tablist;
213 | } else {
214 | if (list.find((v: any) => v.value.toString() === parameter.currentValue.value || v.value === parameter.currentValue.value)) {
215 | currentVal = [parameter.currentValue.value];
216 | }
217 | }
218 | if (currentVal.length === 0) {
219 | // If no match, use first value
220 | currentVal = [(settings.includeAllValue === 'true' ? list[1].value : list[0].value)];
221 | }
222 | }
223 |
224 | parameter.changeValueAsync(settings.multiselect ? currentVal.join(settings.delimiter) : currentVal.toString()).then(console.log);
225 |
226 | this.setState({
227 | disabled: false,
228 | firstInit: false,
229 | currentVal
230 | });
231 | });
232 | }
233 |
234 | // Adds event listener to worksheet and parameter
235 | public async registerListeners() {
236 | const settings = tableau.extensions.settings.getAll();
237 | const dashboard = tableau.extensions.dashboardContent.dashboard;
238 | const worksheet = dashboard.worksheets.find((ws: any) => ws.name === settings.selWorksheet);
239 | dashboard.findParameterAsync(settings.selParam).then((parameter: any) => {
240 | if (!worksheet || !parameter) {
241 | this.setState({
242 | currentVal: [NeedsConfiguring],
243 | disabled: true,
244 | list: [NeedsConfiguring],
245 | });
246 | } else {
247 | if (!settings.updateOnSelectionFix || settings.updateOnSelectionFix === 'true') {
248 | unregister[0] = worksheet.addEventListener(tableau.TableauEventType.FilterChanged, this.getParamData);
249 | unregister[1] = worksheet.addEventListener(tableau.TableauEventType.MarkSelectionChanged, this.getParamData);
250 | }
251 | if (settings.matchParam === 'true') {
252 | unregister[2] = parameter.addEventListener(tableau.TableauEventType.ParameterChanged, this.matchListener);
253 | }
254 | if (settings.listenParam === 'true') {
255 | dashboard.findParameterAsync(settings.listenParamName).then((updateParameter: any) => {
256 | unregister[3] = updateParameter.addEventListener(tableau.TableauEventType.ParameterChanged, this.getParamData);
257 | })
258 | }
259 | }
260 | });
261 | }
262 |
263 | public matchListener = (): void => {
264 | const settings = tableau.extensions.settings.getAll();
265 | const dashboard = tableau.extensions.dashboardContent.dashboard;
266 | dashboard.findParameterAsync(settings.selParam).then((parameter: any) => {
267 | const currentVal = this.state.multiselect ? parameter.currentValue.value.split(settings.delimiter) : [parameter.currentValue.value];
268 | this.setState({
269 | currentVal,
270 | });
271 | });
272 | }
273 |
274 | public resetListeners() {
275 | for (let fn of unregister) {
276 | fn();
277 | }
278 | this.registerListeners();
279 | }
280 |
281 | // Updates the parameter based on selection in Data-Driven Parameter
282 | public updateParam = (e: any) => {
283 | const settings = tableau.extensions.settings.getAll();
284 | const dashboard = tableau.extensions.dashboardContent.dashboard;
285 | const values: any = [];
286 | let newValue: any;
287 | for (const opt of e.target.options) {
288 | if (opt.selected) {
289 | values.push(opt.value);
290 | }
291 | }
292 | this.setState({ currentVal: values });
293 | newValue = values.join(settings.delimiter);
294 | dashboard.findParameterAsync(settings.selParam).then((parameter: any) => {
295 | if (!parameter) {
296 | this.setState({
297 | currentVal: [NeedsConfiguring],
298 | disabled: true,
299 | list: [NeedsConfiguring],
300 | });
301 | } else {
302 | if (settings.applyButton === 'false') {
303 | parameter.changeValueAsync(newValue).then(console.log);
304 | }
305 | }
306 |
307 | if (settings.updateOnChange === 'true') {
308 | // Don't update list if on multi-select, ends up being confusing.
309 | if (!this.state.multiselect) {
310 | this.getParamData();
311 | }
312 | }
313 | });
314 | }
315 |
316 | public apply = (): void => {
317 | const settings = tableau.extensions.settings.getAll();
318 | const dashboard = tableau.extensions.dashboardContent.dashboard;
319 | dashboard.findParameterAsync(settings.selParam).then((parameter: any) => {
320 | parameter.changeValueAsync(this.state.currentVal.join(settings.delimiter)).then(console.log);
321 | });
322 | }
323 |
324 | public setup() {
325 | const settings = tableau.extensions.settings.getAll();
326 | document.body.style.backgroundColor = settings.bg;
327 | document.body.style.color = settings.txt;
328 | this.setState({
329 | allLabel: settings.allLabel || '(All)',
330 | applyButton: settings.applyButton === 'true' || false,
331 | applyButtonLabel: settings.applyButtonLabel || 'Apply',
332 | bg: (settings.bg ? fakeWhiteOverlay(settings.bg) : '#ffffff'),
333 | configured: true,
334 | multiselect: settings.multiselect === 'true' || false,
335 | });
336 | this.findParameter();
337 | }
338 |
339 | // Once we have mounted, we call to initialize
340 | public componentWillMount() {
341 | tableau.extensions.initializeAsync({ configure: this.configure }).then(() => {
342 | const settings = tableau.extensions.settings.getAll();
343 | if (settings.configured === 'true') {
344 | this.setup();
345 | } else {
346 | this.setState({
347 | currentVal: [NeedsConfiguring],
348 | disabled: true,
349 | list: [NeedsConfiguring],
350 | });
351 | this.configure();
352 | }
353 | });
354 | }
355 |
356 | public render() {
357 | const multi =
358 |
359 | {this.state.list.map((option: any) => ({option.displayValue} ))}
360 |
361 | {this.state.applyButtonLabel}
362 |
363 |
364 | const single =
365 |
366 | {this.state.list.map((option: any) => {option.displayValue} )}
367 |
368 |
369 |
370 | return (
371 | <>
372 | {this.state.multiselect ? multi : single}
373 | >
374 | );
375 | }
376 | }
377 |
378 | export default DataDrivenParameter;
379 |
--------------------------------------------------------------------------------
/sandboxed/src/Selected.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { Button } from '@tableau/tableau-ui';
3 |
4 | export interface SelectedProps {
5 | nextConfig?: boolean;
6 | onClear: () => void;
7 | selected: string;
8 | selecting: string;
9 | }
10 |
11 | // An individual setting that has been set
12 | export const Selected: React.SFC = (props) => {
13 | return (
14 |
15 |
The {props.selecting} {props.selected} has been selected
16 |
Clear
17 |
18 | );
19 | };
20 |
21 | Selected.displayName = 'Selected';
22 |
--------------------------------------------------------------------------------
/sandboxed/src/Selector.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { Button, ButtonProps, DropdownSelect, DropdownSelectProps } from '@tableau/tableau-ui';
3 |
4 | export interface SelectorProps {
5 | enabled: boolean;
6 | list: string[];
7 | onChange: (e: React.ChangeEvent) => void;
8 | onClick: () => void;
9 | selected: string;
10 | }
11 |
12 | // Shows if setting has not yet been configured
13 | export const Selector: React.SFC = (props) => {
14 | const dropdownSelectProps: DropdownSelectProps = {
15 | className: 'dropdown-select',
16 | disabled: !props.enabled,
17 | kind: 'line',
18 | onChange: props.onChange,
19 | onSelect: props.onChange,
20 | value: props.selected,
21 | };
22 |
23 | const buttonProps: ButtonProps = {
24 | disabled: !props.enabled || props.selected === '',
25 | kind: 'filledGreen',
26 | onClick: props.onClick,
27 | style: { marginLeft: '12px' },
28 | };
29 |
30 | return (
31 |
32 |
33 | {props.list.map(option => {option} )}
34 |
35 | Set
36 |
37 | );
38 | };
39 |
40 | Selector.displayName = 'Selector';
41 |
--------------------------------------------------------------------------------
/sandboxed/src/Setting.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { Selected } from './Selected';
3 | import { Selector } from './Selector';
4 |
5 | export interface SettingProps {
6 | config: boolean;
7 | enabled: boolean;
8 | list: string[];
9 | nextConfig?: boolean;
10 | onChange: (e: React.ChangeEvent) => void;
11 | onClear: () => void;
12 | onClick: () => void;
13 | selected: string;
14 | selecting: string;
15 | }
16 |
17 | export const Setting: React.SFC = (props) => {
18 | return (
19 |
20 | Select a {props.selecting}
21 | {renderSelectElement(props)}
22 |
23 | );
24 | };
25 |
26 | Setting.displayName = 'Setting';
27 |
28 | function renderSelectElement(props: SettingProps): JSX.Element {
29 | const { config, enabled, list, nextConfig, onChange, onClear, onClick, selected, selecting } = props;
30 |
31 | return config ? :
32 | ;
33 | }
34 |
--------------------------------------------------------------------------------
/sandboxed/src/entry_config.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import * as ReactDOM from 'react-dom';
3 | import Configure from './Configure';
4 |
5 | declare global {
6 | interface Window { tableau: any; }
7 | }
8 |
9 | ReactDOM.render( , document.getElementById('container'));
10 |
--------------------------------------------------------------------------------
/sandboxed/src/entry_index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import * as ReactDOM from 'react-dom';
3 | import DataDrivenParameter from './DataDrivenParameter';
4 |
5 | declare global {
6 | interface Window { tableau: any; }
7 | }
8 |
9 | ReactDOM.render( , document.getElementById('container'));
10 |
--------------------------------------------------------------------------------
/sandboxed/src/imgs/arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tableau/extension-data-driven-parameters/3a97c522fb3cf36bd389366ef7626066f679345f/sandboxed/src/imgs/arrow.png
--------------------------------------------------------------------------------
/sandboxed/src/index.tsx:
--------------------------------------------------------------------------------
1 | export { }
2 |
--------------------------------------------------------------------------------
/sandboxed/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/sandboxed/src/serviceWorker.ts:
--------------------------------------------------------------------------------
1 | // This optional code is used to register a service worker.
2 | // register() is not called by default.
3 |
4 | // This lets the app load faster on subsequent visits in production, and gives
5 | // it offline capabilities. However, it also means that developers (and users)
6 | // will only see deployed updates on subsequent visits to a page, after all the
7 | // existing tabs open on the page have been closed, since previously cached
8 | // resources are updated in the background.
9 |
10 | // To learn more about the benefits of this model and instructions on how to
11 | // opt-in, read https://bit.ly/CRA-PWA
12 |
13 | const isLocalhost = Boolean(
14 | window.location.hostname === 'localhost' ||
15 | // [::1] is the IPv6 localhost address.
16 | window.location.hostname === '[::1]' ||
17 | // 127.0.0.1/8 is considered localhost for IPv4.
18 | window.location.hostname.match(
19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
20 | )
21 | );
22 |
23 | type Config = {
24 | onSuccess?: (registration: ServiceWorkerRegistration) => void;
25 | onUpdate?: (registration: ServiceWorkerRegistration) => void;
26 | };
27 |
28 | export function register(config?: Config) {
29 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
30 | // The URL constructor is available in all browsers that support SW.
31 | const publicUrl = new URL(
32 | (process as { env: { [key: string]: string } }).env.PUBLIC_URL,
33 | window.location.href
34 | );
35 | if (publicUrl.origin !== window.location.origin) {
36 | // Our service worker won't work if PUBLIC_URL is on a different origin
37 | // from what our page is served on. This might happen if a CDN is used to
38 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374
39 | return;
40 | }
41 |
42 | window.addEventListener('load', () => {
43 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
44 |
45 | if (isLocalhost) {
46 | // This is running on localhost. Let's check if a service worker still exists or not.
47 | checkValidServiceWorker(swUrl, config);
48 |
49 | // Add some additional logging to localhost, pointing developers to the
50 | // service worker/PWA documentation.
51 | navigator.serviceWorker.ready.then(() => {
52 | console.log(
53 | 'This web app is being served cache-first by a service ' +
54 | 'worker. To learn more, visit https://bit.ly/CRA-PWA'
55 | );
56 | });
57 | } else {
58 | // Is not localhost. Just register service worker
59 | registerValidSW(swUrl, config);
60 | }
61 | });
62 | }
63 | }
64 |
65 | function registerValidSW(swUrl: string, config?: Config) {
66 | navigator.serviceWorker
67 | .register(swUrl)
68 | .then(registration => {
69 | registration.onupdatefound = () => {
70 | const installingWorker = registration.installing;
71 | if (installingWorker == null) {
72 | return;
73 | }
74 | installingWorker.onstatechange = () => {
75 | if (installingWorker.state === 'installed') {
76 | if (navigator.serviceWorker.controller) {
77 | // At this point, the updated precached content has been fetched,
78 | // but the previous service worker will still serve the older
79 | // content until all client tabs are closed.
80 | console.log(
81 | 'New content is available and will be used when all ' +
82 | 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
83 | );
84 |
85 | // Execute callback
86 | if (config && config.onUpdate) {
87 | config.onUpdate(registration);
88 | }
89 | } else {
90 | // At this point, everything has been precached.
91 | // It's the perfect time to display a
92 | // "Content is cached for offline use." message.
93 | console.log('Content is cached for offline use.');
94 |
95 | // Execute callback
96 | if (config && config.onSuccess) {
97 | config.onSuccess(registration);
98 | }
99 | }
100 | }
101 | };
102 | };
103 | })
104 | .catch(error => {
105 | console.error('Error during service worker registration:', error);
106 | });
107 | }
108 |
109 | function checkValidServiceWorker(swUrl: string, config?: Config) {
110 | // Check if the service worker can be found. If it can't reload the page.
111 | fetch(swUrl)
112 | .then(response => {
113 | // Ensure service worker exists, and that we really are getting a JS file.
114 | const contentType = response.headers.get('content-type');
115 | if (
116 | response.status === 404 ||
117 | (contentType != null && contentType.indexOf('javascript') === -1)
118 | ) {
119 | // No service worker found. Probably a different app. Reload the page.
120 | navigator.serviceWorker.ready.then(registration => {
121 | registration.unregister().then(() => {
122 | window.location.reload();
123 | });
124 | });
125 | } else {
126 | // Service worker found. Proceed as normal.
127 | registerValidSW(swUrl, config);
128 | }
129 | })
130 | .catch(() => {
131 | console.log(
132 | 'No internet connection found. App is running in offline mode.'
133 | );
134 | });
135 | }
136 |
137 | export function unregister() {
138 | if ('serviceWorker' in navigator) {
139 | navigator.serviceWorker.ready.then(registration => {
140 | registration.unregister();
141 | });
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/sandboxed/src/style.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | margin: 0;
4 | padding: 0;
5 | font-family: 'Benton Sans', Arial, Helvetica, sans-serif;
6 | font-size: 12px;
7 | color: rgba(0, 0, 0, 0.8);
8 | box-sizing: border-box;
9 | height: 100%;
10 | width: 100%;
11 | overflow: hidden;
12 | }
13 |
14 | #container {
15 | height: 100%;
16 | width: 100%;
17 | }
18 |
19 | .container {
20 | display: flex;
21 | flex-direction: column;
22 | justify-content: space-between;
23 | height: 100%;
24 | }
25 |
26 | .content {
27 | margin-left: 6px;
28 | }
29 |
30 | .header {
31 | font-size: 16px;
32 | color: rgba(0, 0, 0, 0.8);
33 | padding: 12px 0px 12px 18px;
34 | display: flex;
35 | }
36 |
37 | .title {
38 | font-family: 'Benton Sans Medium', Arial, Helvetica, sans-serif;
39 | font-size: 12px;
40 | color: rgba(0, 0, 0, 0.8);
41 | margin: 30px 0px 18px 0px;
42 | }
43 |
44 | p {
45 | margin: 0;
46 | }
47 |
48 | .selector {
49 | display: flex;
50 | min-height: 26px;
51 | margin-bottom: 12px;
52 | }
53 |
54 | .selected {
55 | margin-left: 10px;
56 | min-height: 26px;
57 | display: flex;
58 | justify-content: space-between;
59 | align-items: center;
60 | margin-bottom: 12px;
61 | }
62 |
63 | .option {
64 | display: flex;
65 | align-items: center;
66 | margin-top: 12px;
67 | }
68 |
69 | .footer {
70 | display: flex;
71 | align-items: flex-end;
72 | margin: 0px 18px;
73 | }
74 |
75 | .btncluster {
76 | display: flex;
77 | justify-content: flex-end;
78 | width: 100%;
79 | margin-bottom: 12px;
80 | }
81 |
82 | .format {
83 | display: flex;
84 | margin-top: 12px;
85 | }
86 |
87 | .formattext {
88 | width: 130px;
89 | }
90 |
91 | input[type="color"] {
92 | /* background-color: #fff; */
93 | padding: 0;
94 | margin-left: 6px;
95 | border: 1px solid #666666;
96 | box-shadow: none;
97 | width: 16px;
98 | height: 16px;
99 | border-radius: 50%;
100 | outline: 0;
101 | }
102 |
103 | ::-webkit-color-swatch {
104 | border: none;
105 | }
106 |
107 | .tooltip {
108 | position: relative;
109 | display: inline-block;
110 | margin-left: 5px;
111 | padding-top: 2px;
112 | }
113 |
114 | .tooltip .tooltiptext {
115 | visibility: hidden;
116 | border: 1px solid #D4D4D4;
117 | border-radius: 1px;
118 | background: #fff;
119 | font-size: 10px;
120 | padding: 8px;
121 | width: 200px;
122 | position: absolute;
123 | z-index: 1;
124 | right: -100px;
125 | top: 20px;
126 | }
127 |
128 | .tooltip:hover .tooltiptext {
129 | visibility: visible;
130 | }
131 |
132 | .tooltiptext ol {
133 | padding: 0px 8px;
134 | margin: 0px;
135 | }
136 |
137 | .tooltiptext li {
138 | margin-top: 8px;
139 | }
140 |
141 | .parameter {
142 | width: 100%;
143 | font-family: 'Benton Sans', Arial, Helvetica, sans-serif;
144 | font-size: 12px;
145 | padding-left:6px;
146 | border: solid 1px #CBCBCB;
147 | }
148 |
149 | .parameter option {
150 | padding: 2px 2px 1px;
151 | height: 20px;
152 | display:flex;
153 | align-items: center;
154 | }
155 |
156 | .singleParameter {
157 | width: 100%;
158 | min-height: 20px !important;
159 | }
160 |
161 | .dropdown-select {
162 | flex: 1;
163 | margin-left: 0;
164 | width: '100%';
165 | }
166 |
167 | .delimiter-text-field > input {
168 | font-family: 'Benton Sans', Arial, Helvetica, sans-serif;
169 | padding-right: 0;
170 | text-align: center;
171 | }
172 |
173 | /* Internet Explorer 10+ */
174 | select::-ms-expand {
175 | visibility: hidden;
176 | }
--------------------------------------------------------------------------------
/sandboxed/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "esModuleInterop": true,
12 | "allowSyntheticDefaultImports": true,
13 | "strict": true,
14 | "forceConsistentCasingInFileNames": true,
15 | "module": "esnext",
16 | "moduleResolution": "node",
17 | "resolveJsonModule": true,
18 | "isolatedModules": true,
19 | "noEmit": true,
20 | "jsx": "preserve"
21 | },
22 | "include": [
23 | "src"
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/src/DataDrivenParameter.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import './style.css';
3 | import { Button, DropdownSelect } from '@tableau/tableau-ui';
4 | const tableau = window.tableau;
5 |
6 | let unregister = [() => { }, () => { }, () => { }, () => { }];
7 |
8 | interface State {
9 | allLabel: string,
10 | applyButton: boolean,
11 | applyButtonLabel: string,
12 | bg: string,
13 | configured: boolean,
14 | currentVal: any[],
15 | disabled: boolean,
16 | firstInit: boolean,
17 | list: any[],
18 | multiselect: boolean,
19 | }
20 |
21 | const NeedsConfiguring: any = { value: 'Parameter needs configuration', displayValue: 'Parameter needs configuration' };
22 | const Loading: any = { value: 'Loading...', displayValue: 'Loading...' };
23 |
24 | function fakeWhiteOverlay(hex: string) {
25 | const rgb = hexToRgb(hex);
26 | if (rgb) {
27 | return `rgb(${Math.min(Math.floor(rgb.r / 2) + 127, 255)}, ${Math.min(Math.floor(rgb.g / 2) + 127, 255)}, ${Math.min(Math.floor(rgb.b / 2) + 127, 255)})`;
28 | } else {
29 | return '#ffffff';
30 | }
31 | }
32 |
33 | function hexToRgb(hex: string) {
34 | const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
35 | return result ? {
36 | b: parseInt(result[3], 16),
37 | g: parseInt(result[2], 16),
38 | r: parseInt(result[1], 16),
39 | } : null;
40 | }
41 |
42 | class DataDrivenParameter extends React.Component {
43 | public readonly state: State = {
44 | allLabel: 'Apply',
45 | applyButton: false,
46 | applyButtonLabel: '(All)',
47 | bg: '#ffffff',
48 | configured: false,
49 | currentVal: [Loading],
50 | disabled: true,
51 | firstInit: true,
52 | list: [Loading],
53 | multiselect: false,
54 | };
55 |
56 | // Pops open the configure page
57 | public configure = (): void => {
58 | const popupUrl = `${window.location.origin}${process.env.PUBLIC_URL}/#/config`;
59 | const payload = '';
60 | tableau.extensions.ui.displayDialogAsync(popupUrl, payload, { height: 610, width: 450 }).then((closePayload: string) => {
61 | this.setup();
62 | }).catch((error: any) => {
63 | if (tableau.extensions.settings.get('configured') !== 'true') {
64 | this.setState({
65 | currentVal: [NeedsConfiguring],
66 | disabled: true,
67 | list: [NeedsConfiguring],
68 | });
69 | }
70 | switch (error.errorCode) {
71 | case tableau.ErrorCodes.DialogClosedByUser:
72 | console.log('Dialog was closed by user.');
73 | break;
74 | default:
75 | console.error(error.message);
76 | }
77 | });
78 | }
79 |
80 | // Locates the parameter to update
81 | public findParameter() {
82 | const settings = tableau.extensions.settings.getAll();
83 | const dashboard = tableau.extensions.dashboardContent.dashboard;
84 | dashboard.findParameterAsync(settings.selParam).then((parameter: any) => {
85 | if (!parameter || parameter.allowableValues.type !== 'all') {
86 | this.setState({
87 | currentVal: [NeedsConfiguring],
88 | disabled: true,
89 | list: [NeedsConfiguring],
90 | });
91 | } else {
92 | this.getParamData();
93 | this.resetListeners();
94 | }
95 | });
96 | }
97 |
98 | // Gets the values from the selected field
99 | public getParamData = (): void => {
100 | const settings = tableau.extensions.settings.getAll();
101 | const dashboard = tableau.extensions.dashboardContent.dashboard;
102 | const worksheet = dashboard.worksheets.find((ws: any) => ws.name === settings.selWorksheet);
103 | if (!worksheet) {
104 | this.setState({
105 | currentVal: [NeedsConfiguring],
106 | disabled: true,
107 | list: [NeedsConfiguring],
108 | });
109 | } else {
110 | worksheet.getSummaryDataAsync({ ignoreSelection: settings.ignoreSelection === 'true' }).then((dataTable: any) => {
111 | this.populateParam(dataTable);
112 | });
113 | }
114 | }
115 |
116 | // Pulls domain of selected field
117 | public populateParam(dataTable: any) {
118 | const settings = tableau.extensions.settings.getAll();
119 | const field = dataTable.columns.find((column: any) => column.fieldName === settings.selField);
120 | this.setState({
121 | currentVal: [Loading],
122 | disabled: true,
123 | list: [Loading],
124 | });
125 |
126 | if (!field) {
127 | this.setState({
128 | currentVal: [NeedsConfiguring],
129 | disabled: true,
130 | list: [NeedsConfiguring],
131 | });
132 | } else {
133 | this.createList(field, dataTable);
134 | }
135 | }
136 |
137 | // Populate list with values from data source
138 | public createList(field: any, dataTable: any) {
139 | const settings = tableau.extensions.settings.getAll();
140 | const displayField = dataTable.columns.find((column: any) => column.fieldName === settings.displayField);
141 |
142 | let list: any[] = [];
143 | for (const row of dataTable.data) {
144 | const value = settings.useFormattedValues === 'true' ? row[field.index].formattedValue : row[field.index].value;
145 | let displayValue = value;
146 | if (displayField && settings.showDisplayValues === 'true') {
147 | displayValue = row[displayField.index].formattedValue
148 | }
149 | list.push({
150 | displayValue,
151 | value,
152 | });
153 | }
154 |
155 | // Remove duplicates
156 | list = list.filter((item, index, array) => array.indexOf(array.find(i => i.value === item.value)) === index);
157 |
158 | if (settings.dataType && (settings.dataType === 'int' || settings.dataType === 'float')) {
159 | // Convert to numbers for correct sort
160 | list = list.map((item) => ({ value: Number(item.value), displayValue: item.displayValue }))
161 | // Sort according to settings (numerical)
162 | if (settings.sort && settings.sort === 'desc') {
163 | list.sort((a, b) => b.value - a.value);
164 | } else {
165 | list.sort((a, b) => a.value - b.value);
166 | }
167 | if (settings.dataType === 'float') {
168 | list = list.map((item) => ({ value: item.value.toLocaleString(tableau.extensions.environment.locale), displayValue: item.displayValue }));
169 | }
170 | } else {
171 | // Sort according to settings
172 | if (settings.sort && settings.sort === 'desc') {
173 | list.sort((a, b) => a.value < b.value ? 1 : -1);
174 | } else {
175 | list.sort((a, b) => a.value > b.value ? 1 : -1);
176 | }
177 | }
178 |
179 | // Add '(All)' according to settings
180 | if (settings.includeAllValue === 'true') {
181 | list.unshift({ value: this.state.allLabel, displayValue: this.state.allLabel });
182 | }
183 |
184 | this.setState({
185 | list,
186 | }, this.setCurrentValue);
187 |
188 | }
189 |
190 | // Determine whether to use current param value or first value of list based on settings
191 | public setCurrentValue = (): void => {
192 | const settings = tableau.extensions.settings.getAll();
193 | const dashboard = tableau.extensions.dashboardContent.dashboard;
194 | const list = this.state.list;
195 | let currentVal: any[] = [];
196 | dashboard.findParameterAsync(settings.selParam).then((parameter: any) => {
197 | if ((this.state.firstInit && settings.autoUpdate === 'true')) {
198 | // Then push new values
199 | currentVal = [(settings.includeAllValue === 'true' ? list[1].value : list[0].value)];
200 | } else {
201 | // Then match parameter value
202 | if (settings.multiselect === 'true') {
203 | const tablist = [];
204 | for (const value of parameter.currentValue.value.split(settings.delimiter)) {
205 | if (list.find((v: any) => v.value.toString() === value || v.value === value)) {
206 | tablist.push(value);
207 | }
208 | }
209 | currentVal = tablist;
210 | } else {
211 | if (list.find((v: any) => v.value.toString() === parameter.currentValue.value || v.value === parameter.currentValue.value)) {
212 | currentVal = [parameter.currentValue.value];
213 | }
214 | }
215 | if (currentVal.length === 0) {
216 | // If no match, use first value
217 | currentVal = [(settings.includeAllValue === 'true' ? list[1].value : list[0].value)];
218 | }
219 | }
220 |
221 | parameter.changeValueAsync(settings.multiselect ? currentVal.join(settings.delimiter) : currentVal.toString()).then(console.log);
222 |
223 | this.setState({
224 | disabled: false,
225 | firstInit: false,
226 | currentVal
227 | });
228 | });
229 | }
230 |
231 | // Adds event listener to worksheet and parameter
232 | public async registerListeners() {
233 | const settings = tableau.extensions.settings.getAll();
234 | const dashboard = tableau.extensions.dashboardContent.dashboard;
235 | const worksheet = dashboard.worksheets.find((ws: any) => ws.name === settings.selWorksheet);
236 | dashboard.findParameterAsync(settings.selParam).then((parameter: any) => {
237 | if (!worksheet || !parameter) {
238 | this.setState({
239 | currentVal: [NeedsConfiguring],
240 | disabled: true,
241 | list: [NeedsConfiguring],
242 | });
243 | } else {
244 | if (!settings.updateOnSelectionFix || settings.updateOnSelectionFix === 'true') {
245 | unregister[0] = worksheet.addEventListener(tableau.TableauEventType.FilterChanged, this.getParamData);
246 | unregister[1] = worksheet.addEventListener(tableau.TableauEventType.MarkSelectionChanged, this.getParamData);
247 | }
248 | if (settings.matchParam === 'true') {
249 | unregister[2] = parameter.addEventListener(tableau.TableauEventType.ParameterChanged, this.matchListener);
250 | }
251 | if (settings.listenParam === 'true') {
252 | dashboard.findParameterAsync(settings.listenParamName).then((updateParameter: any) => {
253 | unregister[3] = updateParameter.addEventListener(tableau.TableauEventType.ParameterChanged, this.getParamData);
254 | })
255 | }
256 | }
257 | });
258 | }
259 |
260 | public matchListener = (): void => {
261 | const settings = tableau.extensions.settings.getAll();
262 | const dashboard = tableau.extensions.dashboardContent.dashboard;
263 | dashboard.findParameterAsync(settings.selParam).then((parameter: any) => {
264 | const currentVal = this.state.multiselect ? parameter.currentValue.value.split(settings.delimiter) : [parameter.currentValue.value];
265 | this.setState({
266 | currentVal,
267 | });
268 | });
269 | }
270 |
271 | public resetListeners() {
272 | for (let fn of unregister) {
273 | fn();
274 | }
275 | this.registerListeners();
276 | }
277 |
278 | // Updates the parameter based on selection in Data-Driven Parameter
279 | public updateParam = (e: any) => {
280 | const settings = tableau.extensions.settings.getAll();
281 | const dashboard = tableau.extensions.dashboardContent.dashboard;
282 | const values: any = [];
283 | let newValue: any;
284 | for (const opt of e.target.options) {
285 | if (opt.selected) {
286 | values.push(opt.value);
287 | }
288 | }
289 | this.setState({ currentVal: values });
290 | newValue = values.join(settings.delimiter);
291 | dashboard.findParameterAsync(settings.selParam).then((parameter: any) => {
292 | if (!parameter) {
293 | this.setState({
294 | currentVal: [NeedsConfiguring],
295 | disabled: true,
296 | list: [NeedsConfiguring],
297 | });
298 | } else {
299 | if (settings.applyButton === 'false') {
300 | parameter.changeValueAsync(newValue).then(console.log);
301 | }
302 | }
303 |
304 | if (settings.updateOnChange === 'true') {
305 | // Don't update list if on multi-select, ends up being confusing.
306 | if (!this.state.multiselect) {
307 | this.getParamData();
308 | }
309 | }
310 | });
311 | }
312 |
313 | public apply = (): void => {
314 | const settings = tableau.extensions.settings.getAll();
315 | const dashboard = tableau.extensions.dashboardContent.dashboard;
316 | dashboard.findParameterAsync(settings.selParam).then((parameter: any) => {
317 | parameter.changeValueAsync(this.state.currentVal.join(settings.delimiter)).then(console.log);
318 | });
319 | }
320 |
321 | public setup() {
322 | const settings = tableau.extensions.settings.getAll();
323 | document.body.style.backgroundColor = settings.bg;
324 | document.body.style.color = settings.txt;
325 | this.setState({
326 | allLabel: settings.allLabel || '(All)',
327 | applyButton: settings.applyButton === 'true' || false,
328 | applyButtonLabel: settings.applyButtonLabel || 'Apply',
329 | bg: (settings.bg ? fakeWhiteOverlay(settings.bg) : '#ffffff'),
330 | configured: true,
331 | multiselect: settings.multiselect === 'true' || false,
332 | });
333 | this.findParameter();
334 | }
335 |
336 | // Once we have mounted, we call to initialize
337 | public componentWillMount() {
338 | tableau.extensions.initializeAsync({ configure: this.configure }).then(() => {
339 | const settings = tableau.extensions.settings.getAll();
340 | if (settings.configured === 'true') {
341 | this.setup();
342 | } else {
343 | this.setState({
344 | currentVal: [NeedsConfiguring],
345 | disabled: true,
346 | list: [NeedsConfiguring],
347 | });
348 | this.configure();
349 | }
350 | });
351 | }
352 |
353 | public render() {
354 | const multi =
355 |
356 | {this.state.list.map((option: any) => ({option.displayValue} ))}
357 |
358 | {this.state.applyButtonLabel}
359 |
360 |
361 | const single =
362 |
363 | {this.state.list.map((option: any) => {option.displayValue} )}
364 |
365 |
366 |
367 | return (
368 | <>
369 | {this.state.multiselect ? multi : single}
370 | >
371 | );
372 | }
373 | }
374 |
375 | export default DataDrivenParameter;
376 |
--------------------------------------------------------------------------------
/src/Home.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import './home.css';
3 |
4 | class Home extends React.Component {
5 | public render() {
6 | return (
7 |
8 |
9 |
10 |
11 |
Data-Driven Parameters
12 | Automatically update your parameters based on your data!
13 |
14 |
15 |
What is it?
16 |
This extension allows you to add a parameter to a Tableau dashboard whose domain is based on your data. Added a new product line? No longer do you need to manually edit the parameter to update it, with this extension your parameter values
17 | update automatically!
18 |
Using the Extension
19 |
20 | Create an open input (All) parameter with a data type matching the field you want to use to populate it.
21 | Drag in a new Extension object to your dashboard.
22 | Find the manifest (.trex) file you downloaded above.
23 | Select the parameter you created above for the extension to manipulate.
24 | Select the worksheet that holds the field you want to base your parameter on.
25 | Select the field you want to base your parameter on.
26 | Optional: Configure your text and background colors.
27 | Click 'OK'.
28 |
29 |
Note: You can add as many instances of this extension as you like!
30 |
34 |
35 |
36 |
37 |
38 | );
39 | }
40 | }
41 |
42 | export default Home;
--------------------------------------------------------------------------------
/src/Selected.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { Button } from '@tableau/tableau-ui';
3 |
4 | export interface SelectedProps {
5 | nextConfig?: boolean;
6 | onClear: () => void;
7 | selected: string;
8 | selecting: string;
9 | }
10 |
11 | // An individual setting that has been set
12 | export const Selected: React.SFC = (props) => {
13 | return (
14 |
15 |
The {props.selecting} {props.selected} has been selected
16 |
Clear
17 |
18 | );
19 | };
20 |
21 | Selected.displayName = 'Selected';
22 |
--------------------------------------------------------------------------------
/src/Selector.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { Button, ButtonProps, DropdownSelect, DropdownSelectProps } from '@tableau/tableau-ui';
3 |
4 | export interface SelectorProps {
5 | enabled: boolean;
6 | list: string[];
7 | onChange: (e: React.ChangeEvent) => void;
8 | onClick: () => void;
9 | selected: string;
10 | }
11 |
12 | // Shows if setting has not yet been configured
13 | export const Selector: React.SFC = (props) => {
14 | const dropdownSelectProps: DropdownSelectProps = {
15 | className: 'dropdown-select',
16 | disabled: !props.enabled,
17 | kind: 'line',
18 | onChange: props.onChange,
19 | onSelect: props.onChange,
20 | value: props.selected,
21 | };
22 |
23 | const buttonProps: ButtonProps = {
24 | disabled: !props.enabled || props.selected === '',
25 | kind: 'filledGreen',
26 | onClick: props.onClick,
27 | style: { marginLeft: '12px' },
28 | };
29 |
30 | return (
31 |
32 |
33 | {props.list.map(option => {option} )}
34 |
35 | Set
36 |
37 | );
38 | };
39 |
40 | Selector.displayName = 'Selector';
41 |
--------------------------------------------------------------------------------
/src/Setting.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { Selected } from './Selected';
3 | import { Selector } from './Selector';
4 |
5 | export interface SettingProps {
6 | config: boolean;
7 | enabled: boolean;
8 | list: string[];
9 | nextConfig?: boolean;
10 | onChange: (e: React.ChangeEvent) => void;
11 | onClear: () => void;
12 | onClick: () => void;
13 | selected: string;
14 | selecting: string;
15 | }
16 |
17 | export const Setting: React.SFC = (props) => {
18 | return (
19 |
20 | Select a {props.selecting}
21 | {renderSelectElement(props)}
22 |
23 | );
24 | };
25 |
26 | Setting.displayName = 'Setting';
27 |
28 | function renderSelectElement(props: SettingProps): JSX.Element {
29 | const { config, enabled, list, nextConfig, onChange, onClear, onClick, selected, selecting } = props;
30 |
31 | return config ? :
32 | ;
33 | }
34 |
--------------------------------------------------------------------------------
/src/home.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | margin: 0;
4 | padding: 0;
5 | height: 100%;
6 | width: 100%;
7 | color: #585858;
8 | border: 0;
9 | }
10 |
11 | .icontainer {
12 | font-size: 18px;
13 | background: #FAFAFA;
14 | display: flex;
15 | justify-content: center;
16 | align-items: center;
17 | height: 100%;
18 | }
19 |
20 | .box {
21 | background: #ffffff;
22 | max-width: 1250px;
23 | margin: 20px;
24 | display: flex;
25 | box-shadow: 2px 4px 8px rgba(102, 162, 222, 0.15);
26 | }
27 |
28 | .left {
29 | background: linear-gradient(to bottom left, #02B3A4, #66A2DE);
30 | padding: 40px;
31 | width: 450px;
32 | color: #ffffff;
33 | display: flex;
34 | align-items: center;
35 | align-content: center;
36 | justify-content: flex-start;
37 | flex-wrap: wrap;
38 | font-size: 20px;
39 | font-family: 'Benton Sans', Arial, Helvetica, sans-serif;
40 | }
41 |
42 | .right {
43 | padding: 40px;
44 | display: flex;
45 | align-items: center;
46 | align-content: center;
47 | justify-content: flex-start;
48 | flex-wrap: wrap;
49 | }
50 |
51 | .iheader {
52 | font-size: 64px;
53 | font-family: 'Bookman Old Style', Arial, Helvetica, sans-serif;
54 | margin: 10px 0px;
55 | line-height: 54px;
56 | }
57 |
58 | .big {
59 | font-size: 28px;
60 | width: 100%;
61 | margin: 5px 0px;
62 | }
63 |
64 | a {
65 | color: #02B3A4;
66 | font-weight: bold;
67 | text-decoration: none;
68 | }
69 |
70 | a:hover {
71 | text-decoration: underline;
72 | }
73 |
74 | .gh {
75 | font-size: 16px;
76 | text-align: center;
77 | width: 100%;
78 | }
--------------------------------------------------------------------------------
/src/imgs/arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tableau/extension-data-driven-parameters/3a97c522fb3cf36bd389366ef7626066f679345f/src/imgs/arrow.png
--------------------------------------------------------------------------------
/src/index.tsx:
--------------------------------------------------------------------------------
1 | import 'react-app-polyfill/ie11';
2 | import * as React from 'react';
3 | import * as ReactDOM from 'react-dom';
4 | import { HashRouter, Route } from 'react-router-dom';
5 | import Configure from './Configure';
6 | import DataDrivenParameter from './DataDrivenParameter';
7 | import Home from './Home';
8 |
9 | declare global {
10 | interface Window { tableau: any; }
11 | }
12 |
13 | const PrimaryLayout = () => (
14 |
15 |
16 |
17 |
18 |
19 | )
20 |
21 | class App extends React.Component {
22 | public render() {
23 | return (
24 |
25 |
26 |
27 | )
28 | }
29 | }
30 |
31 | ReactDOM.render( , document.getElementById('container'));
32 |
--------------------------------------------------------------------------------
/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/src/serviceWorker.ts:
--------------------------------------------------------------------------------
1 | // This optional code is used to register a service worker.
2 | // register() is not called by default.
3 |
4 | // This lets the app load faster on subsequent visits in production, and gives
5 | // it offline capabilities. However, it also means that developers (and users)
6 | // will only see deployed updates on subsequent visits to a page, after all the
7 | // existing tabs open on the page have been closed, since previously cached
8 | // resources are updated in the background.
9 |
10 | // To learn more about the benefits of this model and instructions on how to
11 | // opt-in, read https://bit.ly/CRA-PWA
12 |
13 | const isLocalhost = Boolean(
14 | window.location.hostname === 'localhost' ||
15 | // [::1] is the IPv6 localhost address.
16 | window.location.hostname === '[::1]' ||
17 | // 127.0.0.1/8 is considered localhost for IPv4.
18 | window.location.hostname.match(
19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
20 | )
21 | );
22 |
23 | type Config = {
24 | onSuccess?: (registration: ServiceWorkerRegistration) => void;
25 | onUpdate?: (registration: ServiceWorkerRegistration) => void;
26 | };
27 |
28 | export function register(config?: Config) {
29 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
30 | // The URL constructor is available in all browsers that support SW.
31 | const publicUrl = new URL(
32 | (process as { env: { [key: string]: string } }).env.PUBLIC_URL,
33 | window.location.href
34 | );
35 | if (publicUrl.origin !== window.location.origin) {
36 | // Our service worker won't work if PUBLIC_URL is on a different origin
37 | // from what our page is served on. This might happen if a CDN is used to
38 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374
39 | return;
40 | }
41 |
42 | window.addEventListener('load', () => {
43 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
44 |
45 | if (isLocalhost) {
46 | // This is running on localhost. Let's check if a service worker still exists or not.
47 | checkValidServiceWorker(swUrl, config);
48 |
49 | // Add some additional logging to localhost, pointing developers to the
50 | // service worker/PWA documentation.
51 | navigator.serviceWorker.ready.then(() => {
52 | console.log(
53 | 'This web app is being served cache-first by a service ' +
54 | 'worker. To learn more, visit https://bit.ly/CRA-PWA'
55 | );
56 | });
57 | } else {
58 | // Is not localhost. Just register service worker
59 | registerValidSW(swUrl, config);
60 | }
61 | });
62 | }
63 | }
64 |
65 | function registerValidSW(swUrl: string, config?: Config) {
66 | navigator.serviceWorker
67 | .register(swUrl)
68 | .then(registration => {
69 | registration.onupdatefound = () => {
70 | const installingWorker = registration.installing;
71 | if (installingWorker == null) {
72 | return;
73 | }
74 | installingWorker.onstatechange = () => {
75 | if (installingWorker.state === 'installed') {
76 | if (navigator.serviceWorker.controller) {
77 | // At this point, the updated precached content has been fetched,
78 | // but the previous service worker will still serve the older
79 | // content until all client tabs are closed.
80 | console.log(
81 | 'New content is available and will be used when all ' +
82 | 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
83 | );
84 |
85 | // Execute callback
86 | if (config && config.onUpdate) {
87 | config.onUpdate(registration);
88 | }
89 | } else {
90 | // At this point, everything has been precached.
91 | // It's the perfect time to display a
92 | // "Content is cached for offline use." message.
93 | console.log('Content is cached for offline use.');
94 |
95 | // Execute callback
96 | if (config && config.onSuccess) {
97 | config.onSuccess(registration);
98 | }
99 | }
100 | }
101 | };
102 | };
103 | })
104 | .catch(error => {
105 | console.error('Error during service worker registration:', error);
106 | });
107 | }
108 |
109 | function checkValidServiceWorker(swUrl: string, config?: Config) {
110 | // Check if the service worker can be found. If it can't reload the page.
111 | fetch(swUrl)
112 | .then(response => {
113 | // Ensure service worker exists, and that we really are getting a JS file.
114 | const contentType = response.headers.get('content-type');
115 | if (
116 | response.status === 404 ||
117 | (contentType != null && contentType.indexOf('javascript') === -1)
118 | ) {
119 | // No service worker found. Probably a different app. Reload the page.
120 | navigator.serviceWorker.ready.then(registration => {
121 | registration.unregister().then(() => {
122 | window.location.reload();
123 | });
124 | });
125 | } else {
126 | // Service worker found. Proceed as normal.
127 | registerValidSW(swUrl, config);
128 | }
129 | })
130 | .catch(() => {
131 | console.log(
132 | 'No internet connection found. App is running in offline mode.'
133 | );
134 | });
135 | }
136 |
137 | export function unregister() {
138 | if ('serviceWorker' in navigator) {
139 | navigator.serviceWorker.ready.then(registration => {
140 | registration.unregister();
141 | });
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/src/style.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | margin: 0;
4 | padding: 0;
5 | font-family: 'Benton Sans', Arial, Helvetica, sans-serif;
6 | font-size: 12px;
7 | color: rgba(0, 0, 0, 0.8);
8 | box-sizing: border-box;
9 | height: 100%;
10 | width: 100%;
11 | overflow: hidden;
12 | }
13 |
14 | #container {
15 | height: 100%;
16 | width: 100%;
17 | }
18 |
19 | .container {
20 | display: flex;
21 | flex-direction: column;
22 | justify-content: space-between;
23 | height: 100%;
24 | }
25 |
26 | .content {
27 | margin-left: 6px;
28 | }
29 |
30 | .header {
31 | font-size: 16px;
32 | color: rgba(0, 0, 0, 0.8);
33 | padding: 12px 0px 12px 18px;
34 | display: flex;
35 | }
36 |
37 | .title {
38 | font-family: 'Benton Sans Medium', Arial, Helvetica, sans-serif;
39 | font-size: 12px;
40 | color: rgba(0, 0, 0, 0.8);
41 | margin: 30px 0px 18px 0px;
42 | }
43 |
44 | p {
45 | margin: 0;
46 | }
47 |
48 | .selector {
49 | display: flex;
50 | min-height: 26px;
51 | margin-bottom: 12px;
52 | }
53 |
54 | .selected {
55 | margin-left: 10px;
56 | min-height: 26px;
57 | display: flex;
58 | justify-content: space-between;
59 | align-items: center;
60 | margin-bottom: 12px;
61 | }
62 |
63 | .option {
64 | display: flex;
65 | align-items: center;
66 | margin-top: 12px;
67 | }
68 |
69 | .footer {
70 | display: flex;
71 | align-items: flex-end;
72 | margin: 0px 18px;
73 | }
74 |
75 | .btncluster {
76 | display: flex;
77 | justify-content: flex-end;
78 | width: 100%;
79 | margin-bottom: 12px;
80 | }
81 |
82 | .format {
83 | display: flex;
84 | margin-top: 12px;
85 | }
86 |
87 | .formattext {
88 | width: 130px;
89 | }
90 |
91 | input[type="color"] {
92 | /* background-color: #fff; */
93 | padding: 0;
94 | margin-left: 6px;
95 | border: 1px solid #666666;
96 | box-shadow: none;
97 | width: 16px;
98 | height: 16px;
99 | border-radius: 50%;
100 | outline: 0;
101 | }
102 |
103 | ::-webkit-color-swatch {
104 | border: none;
105 | }
106 |
107 | .tooltip {
108 | position: relative;
109 | display: inline-block;
110 | margin-left: 5px;
111 | padding-top: 2px;
112 | }
113 |
114 | .tooltip .tooltiptext {
115 | visibility: hidden;
116 | border: 1px solid #D4D4D4;
117 | border-radius: 1px;
118 | background: #fff;
119 | font-size: 10px;
120 | padding: 8px;
121 | width: 200px;
122 | position: absolute;
123 | z-index: 1;
124 | right: -100px;
125 | top: 20px;
126 | }
127 |
128 | .tooltip:hover .tooltiptext {
129 | visibility: visible;
130 | }
131 |
132 | .tooltiptext ol {
133 | padding: 0px 8px;
134 | margin: 0px;
135 | }
136 |
137 | .tooltiptext li {
138 | margin-top: 8px;
139 | }
140 |
141 | .parameter {
142 | width: 100%;
143 | font-family: 'Benton Sans', Arial, Helvetica, sans-serif;
144 | font-size: 12px;
145 | padding-left:6px;
146 | border: solid 1px #CBCBCB;
147 | }
148 |
149 | .parameter option {
150 | padding: 2px 2px 1px;
151 | height: 20px;
152 | display:flex;
153 | align-items: center;
154 | }
155 |
156 | .singleParameter {
157 | width: 100%;
158 | min-height: 20px !important;
159 | }
160 |
161 | .dropdown-select {
162 | flex: 1;
163 | margin-left: 0;
164 | width: '100%';
165 | }
166 |
167 | .delimiter-text-field > input {
168 | font-family: 'Benton Sans', Arial, Helvetica, sans-serif;
169 | padding-right: 0;
170 | text-align: center;
171 | }
172 |
173 | /* Internet Explorer 10+ */
174 | select::-ms-expand {
175 | visibility: hidden;
176 | }
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "esModuleInterop": true,
12 | "allowSyntheticDefaultImports": true,
13 | "strict": true,
14 | "forceConsistentCasingInFileNames": true,
15 | "module": "esnext",
16 | "moduleResolution": "node",
17 | "resolveJsonModule": true,
18 | "isolatedModules": true,
19 | "noEmit": true,
20 | "jsx": "preserve"
21 | },
22 | "jsRules": {
23 | "no-console": false
24 | },
25 | "include": [
26 | "src"
27 | ]
28 | }
29 |
--------------------------------------------------------------------------------