Skip to content

Instantly share code, notes, and snippets.

@antun
Created August 21, 2019 20:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save antun/54abdc5fa82afcb3e33b04c14f6207f8 to your computer and use it in GitHub Desktop.
Save antun/54abdc5fa82afcb3e33b04c14f6207f8 to your computer and use it in GitHub Desktop.
Minimal Configure - YCC
<header class="site-header">
<!-- adding a dummy header like most sites will already have -->
<h1 class="header-title">Configure 3.134.1 <span class="configure-reference-type">YCC Test Page</span></h1>
<div class="demo-links" style="display:none">
<a href="../">other demos</a>
<a href="#">source</a>
<a href="#">download</a>
<a href="#">edit</a>
</div>
</header>
<div class="site-body">
<div class="configure-container">
<div class="info-container">
<div class="configure-product-info"></div>
<div class="configure-price"></div>
</div>
<div class="customization-container">
<div class="configure-display-container">
<div class="configure-product-display">abc</div>
<div class="configure-thumbnails-display"></div>
<div class="configure-snapshots"></div>
</div>
<div class="controls-container">
<div class="configure-accordion"></div>
<div class="configure-pager"></div>
<div class="button-container">
<div class="configure-add-to-cart-button"></div>
<div class="configure-add-to-catalog-button"></div>
<div class="configure-share-button"></div>
<div class="configure-reset-recipe-button"></div>
<div class="configure-print-button"></div>
</div>
</div>
</div>
</div>
<!-- This will be used by the print-button event listener on javascript.js -->
<div id="printable-element">
<p>Anything within this div will be used on the print template</p>
{{content}}
</div>
<!-- This is a vanilla JS template we'll use to keep template
rendering simple on this demo. You should probably use a
templating language like dust.js or _.template -->
<script id="print-friendly-template" type="text/template">
<h1>{{productName}}</h1>
<h3>Recipe <a href="{{recipeUrl}}">#{{recipeId}}</a> details</h3>
<h4 class="price">Price: {{formattedPrice}}</h4>
<h4 class="quantity">Quantity: {{quantity}}</h4>
<p class="links">URL: <a href="{{tinyUrl}}">{{tinyUrl}}</a> <a class="qr" href="{{recipeUrl}}"><img src="{{qrCode}}" /></a></p>
<p class="display"><img src="{{imageUrl}}" /></p>
<div class="recipe">
{{recipeDetails}}
</div>
</script>
<!-- This is completely optional. If this tag is not found it will be added
automatically to the bottom of the body -->
<div class="fc-tooltip-container"></div>
</div>
<script src="javascript.js" type="text/javascript"></script>
<script src="https://code.fluidretail.net/configure-ui/stable/js/configure-app.js" type="text/javascript" charset="utf-8" data-configure-global="configureApp"></script>
document.addEventListener("configureApp", function (e) {
configureReady(e.detail.configureApp);
});
function configureReady(configureApp) {
var _GET = configureApp._GET;
var params = {
facebookAppId: 805996949423760,
environment: _GET.environment || "prod",
workflow: _GET.workflow || "qa",
customer: _GET.customer || 1565,
product: _GET.product || 21929,
recipe: _GET.recipe, // Use recipe 112 to force invalid recipe handling
locale: _GET.locale || "en_US",
currency: _GET.currency
};
configureApp(params, function (err, configure) {
window.configure = configure;
if (!err) {
// No errors so we can now render the UI components
initializeComponents(configure);
//set region
// configure.run('selectValue', { 'ca': 60200, 'av': {text: 'ABC😊'} })
configure.run('selectValue', {'ca': 79684, 'av': 145028});
configure.run('selectValue', { 'ca': 60200, 'av': {text: 'ABC😊'} });
configure.run('selectValue', { 'ca': 60420, 'av': 109083});
configure.run('selectValue', { 'ca': 60823, 'av': 109083});
} else {
// An outdated recipe might have been loaded
if (err.fcErrorType === "recipe:invalid") {
handleInvalidRecipe(err.fcErrorDetails, configure);
} else {
// Unknown issues
throw err;
}
}
// Creates all UI components
function initializeComponents() {
var components = [
{
type: "addToCartButton",
showPriceOnButton: true,
saveOnSelected: false
}, {
type: "addToCatalogButton",
customDialog: false,
dialogWidth: 300,
dialogHeight: 450,
// Use beforeSave and recipePoster hooks
// to prevent polluting the DB with demo entries
beforeSave: beforeSaveOnCatalogHook,
recipePoster: recipePosterOnCatalogHook
},
{
type: "recipeImage",
arrows: false,
container: ".configure-product-display",
format: 'jpg',
view: 'Front',
width: 500
},
{
type: "resetRecipeButton"
},
/*
{
type: "thumbnailsDisplay",
slidesToShow: 3
},
*/
{
type: "price"
}, {
type: "productInfo"
}, {
type: "navFlyout",
uiSettings: {
selectorLayout: {
showName: true
},
attributeValueTooltip: {
extended: true,
position: "left",
type: "dark",
effect: "solid"
},
descriptionTooltip: {
extended: true,
content: function (caObj){
return "<h4>" + caObj.name + "</h4><p><strong>Info</strong>" +
": " + caObj.description + "</p>";
},
position: "top"
},
facetDescriptionTooltip: {
extended: false,
position: "left"
}
}
}, {
type: "button",
container: ".configure-print-button",
title: "Print",
onClick: handlePrint,
uiSettings: {
buttonTooltip: {
content: "Print this model!",
effect: "solid",
position: "top",
type: "dark"
}
}
}, {
type: "snapshots",
container: ".configure-snapshots",
uiSettings: {
snapshots: {
i18n: {
// Overriding admin defaults when using the default locale
viewButtonLabel: !_GET.locale && "View Snapshots",
hideButtonLabel: !_GET.locale && "Hide Snapshots",
callToActionContent: !_GET.locale &&
"<a href='javascript:window.takeSnapshot();'>" +
"Take a Snapshot</a><br>and review it later!"
}
}
}
}
];
configure.run("createComponents", {
container: ".configure-container",
components: components
}, function (err, componentEvents) {
if (err) {
throw err;
}
// componentEvents includes the event buses for each
// component
// Add to cart
handleAddToCart(componentEvents.addToCartButton);
});
}
function handleAddToCart(addToCartButton) {
addToCartButton.on("selected", function (el) {
configure.run("createDialog", {
type: "addToCart",
clickSource: el,
showElements: ["price", "quantity", "images", "checkout"],
height: 500
}, function (err, dialog) {
if (err) {
throw err;
}
dialog.on("saved", function (err, info) {
if (err) {
throw err;
}
window.alert("Added to cart: \n" + JSON.stringify(info, null, 2));
});
});
});
}
// ugc editor integration
function handleOpenUgcEditor(accordion) {
accordion.on("ugc:image-ready", function (data) {
if (data.isEditable) {
configure.run("createDialog", {
type: "ugcEditor",
editorWidth: 400,
editorHeight: 400,
showClose: false,
caId: data.ca.id
});
}
});
}
// Social catalog
function beforeSaveOnCatalogHook(callback) {
// This is our last chance to modify the recipe before saving it
// For example by adding a user ID from the eCommerce system
// after a login is performed
var err,
customData = {
userId: 123,
testData: "This is an example of custom data"
};
// You can also update the recipe for example to remove
// personal info that you don't want to be shared on the catalog
// The callback must be called in order to continue saving
callback(err, customData);
}
function recipePosterOnCatalogHook(endpoint, data, cb) {
var err;
// use an existing know recipe id during development and
// testing to avoid polluting the catalog
cb(err, {
id: 4736542
});
}
// Handle print request
function handlePrint() {
// We'll get common information about this URL
configure.run("getTemplateOptions",
{
purpose: "printDialog"
},
function (err, variables) {
if (err) {
throw err;
}
// Add the information that you need on the print template
// This could be avoided by using a templating language but
// we'll just use Vanilla JS for this demo.
variables.productName = variables.product.name;
variables.recipeDetails = "<ul><li>" +
variables.recipe.map(function (e) {
return e.ca.name + ": " + e.av.name;
}).join("</li><li>") + "</ul>";
variables.qrCode = "https://chart.apis.google.com/chart?chld=H|0&" +
"cht=qr&chs=200x200&chl=" +
encodeURIComponent(variables.recipeUrl);
var printOptions = {
// pageTitle: "", // By default the product name
// overrideElementCSS: ["print.css"]
};
var printableElement =
document.getElementById("printable-element");
// Use a templating language like dust or _.template
// or this simple find and replace function
function replaceVariables(markup, variables) {
var value, name;
for (name in variables) {
if (variables.hasOwnProperty(name)) {
value = variables[name];
markup =
markup.replace(
new RegExp("{{" + name + "}}", "g"),
value
);
}
}
return markup;
}
// Render the template and assign the result to {{content}}
variables.content = replaceVariables(
document.getElementById("print-friendly-template").innerHTML,
variables
);
// Include {{content}} into the DOM element used for the
// print dialog
printableElement.innerHTML = replaceVariables(
printableElement.innerHTML, variables);
// We want to make sure the image on the print dialog is loaded
// before print is called
var img = new Image();
img.onload = function () {
// Call the print element method to bring up the browser
// print dialog
configure.run("printElement", printableElement, printOptions,
function () {
// Done printing
});
};
img.src = variables.imageUrl;
});
}
// We'll show an error and will set a recipe with the fall-back values
function handleInvalidRecipe(errorDetails, configure) {
window.loadFallbackRecipe = function loadFallbackRecipe() {
configure.run("setRecipe",
errorDetails.fallbackRecipe,
function (err) {
if (err) {
throw err;
}
initializeComponents(configure);
});
};
document.querySelector(".configure-product-info").innerHTML =
getInvalidRecipeError(errorDetails);
configure.run("createComponent", {
type: "recipeImage",
container: ".configure-product-display",
width: 500
}, function (err) {
console.log('recipeImage created');
if (err) {
throw err;
}
});
}
function getInvalidRecipeError(errorDetails) {
var errorMessage = "<h2>Invalid recipe configuration</h2>" +
"<ul>";
var removed, added;
var oldConfiguration = errorDetails.recipeDocument.configuration;
for (var i = 0; errorDetails.unavailable.length > i; i += 1) {
removed = errorDetails.unavailable[i];
added = errorDetails.replacements[i];
errorMessage += "<li>" + removed.ca.name +
" value changed from " +
"<span style='text-decoration: line-through'>" +
oldConfiguration[removed.ca.alias] +
"</span>" +
" to <strong>" + added.av.name + "</strong></li>";
}
return errorMessage + "</ul>" +
"<button onclick='loadFallbackRecipe()'>Load configurator</button>";
}
window.takeSnapshot = function () {
configure.run("saveSnapshot", function (err) {
if (err) { return console.log(err); }
});
};
// Leak the configure instance to debug on the console
window.configureInstance = configure;
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
/* Demo specific styles */
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
.group:after {
content: "";
display: table;
clear: both;
}
body {
margin: 0px;
font-family: sans-serif;
font-size: 16px;
background-color: #F1F2ED;
}
.site-header {
background-color: #2B2B2B;
padding: 1em 2em;
}
.header-title {
max-width: 1128px;
margin: 0 auto;
color: #fefefe;
font-size: 18px;
line-height: 3;
text-transform: uppercase;
font-weight: bold;
display: inline-block;
}
.configure-reference-type {
color: #33B8CF;
font-weight: normal;
}
.site-body {
width: 100%;
padding: 2em;
}
.demo-links {
float: right;
display: inline-block;
line-height: 4.5;
font-size: .75em;
letter-spacing: .025em;
}
@media(max-width: 740px) {
.demo-links {
float: none;
display: block;
line-height: inherit;
}
}
.site-header a {
padding-right: 1em;
color: #33B8CF;
text-decoration: none;
opacity: .8;
}
.site-header a:hover {
text-decoration: underline;
opacity: 1;
}
/* Fluid Configure Styles */
/* CONTAINERS */
.configure-container {
max-width: 1128px;
height: 800px;
margin: 0 auto;
position: relative;
overflow: hidden;
}
.info-container {
margin-bottom: 2em;
}
.customization-container {
/*white-space: nowrap;*/
}
.configure-display-container {
position: relative;
float: left;
width: 66.66%;
padding-right: 1em;
}
@media (max-width: 740px) {
.configure-display-container {
width: 100%;
}
}
.controls-container {
float: left;
width: 33.33%;
vertical-align: top;
/*padding-right: 1em;*/
}
@media(max-width:740px) {
.controls-container {
width: 100%;
}
}
.button-container {
margin: 2em 0;
}
.configure-ui {
overflow: hidden;
height: 248px;
width: 100%;
}
/* DISPLAY CAROUSEL */
.configure-product-display {
background: #fefefe;
}
.configure-display-thumbs {
}
.configure-display-zoom {
position: relative;
top: -100px;
line-height: 3;
white-space: nowrap;
width: 75px;
background-color: #fff;
}
.carousel-dots {
bottom: 20px;
}
.carousel-id-small-display,
.carousel-id-main-display {
margin: 0;
}
.carousel-slider {
margin-bottom: 0;
}
/* ATTRIBUTE HEADER */
.fc-attribute-header {
font-size: 1rem;
}
/* PAGER */
@media (min-width: 740px) {
.fc-pager {
display: none;
}
}
.fc-pager-header {
background-color: #fff;
}
.fc-pager-pullout {
display: none;
}
.fc-pager-pulldown-item.fc-pager-pulldown-item-selected {
background-color: #efefef;
}
.fc-product-info .fc-product-name {
text-transform: uppercase;
font-size: 1.5em;
font-weight: bold;
color: #666;
}
.fc-price {
color: #B50339;
}
.fc-product-description {
display: none;
}
/* DIALOGS */
.fc-share-dialog {
padding: 20px;
}
.fc-add-to-catalog-dialog {
padding: 20px;
}
.fc-add-to-cart-dialog {
padding: 20px;
}
/* BUTTONS */
.fc-add-to-cart-button {
padding: 1em;
background: #777;
color: white;
font-weight: 300;
margin: 1em 0;
}
/* PRINT DEMO */
@media screen {
#printable-element {
display: none;
}
button.printing {
opacity: 0.2;
}
}
@media print {
body {
background-color: #fff;
}
#printable-element {
display: block;
}
h1 {
text-transform: uppercase;
font-size: 1.5em;
font-weight: bold;
color: #666;
}
.price {
color: #B50339;
}
.qr {
position: absolute;
top: 10px;
right: 10px;
}
}
/*****************************************************
Nav Flyout Specific Demo Styles
*****************************************************/
.configure-container {
position:relative;
width:90%;
max-width:1024px;
margin:0 auto;
padding:2rem 0;
}
.configure-display-container {
position:absolute;
width:100%;
max-width:76%;
margin:0 2%;
left:0;
background:#fff;
}
.configure-product-display {
max-width: 80%;
margin: 0 auto 3rem;
}
.configure-nav-flyout {
position:relative;
}
/*****************************************************
Styles for products without attribute groups
*****************************************************/
.not-using-ag .only-ag {
display: none;
}
.configure-nav-flyout .fc-nav-flyout-without-ags {
width:100%;
max-width:20%;
margin-bottom:2rem;
}
.fc-nav-flyout-without-ags.fc-nav-flyout-reveal-left {
position:absolute;
top:0;
right:0;
}
.fc-nav-flyout-without-ags.fc-nav-flyout-reveal-right {
position:absolute;
top:0;
left:0;
}
.fc-nav-flyout-without-ags .fc-nav-flyout-ca {
border-bottom:1px dotted #aaa;
background:#dadada;
}
.fc-nav-flyout-without-ags .fc-nav-flyout-ca .fc-nav-flyout-header::before {
border-left-color:#dadada !important;
}
.fc-nav-flyout-without-ags .fc-nav-flyout-ca .fc-attribute-header {
margin:0 auto;
padding:0;
text-align:center;
}
.fc-nav-flyout-without-ags .fc-nav-flyout-ca .fc-attribute-header .fc-swatch {
margin:0 auto;
display:block;
}
.fc-nav-flyout-without-ags .fc-nav-flyout-ca .fc-attribute-header-swatch-name {
display:none;
}
.fc-nav-flyout-without-ags .fc-nav-flyout-panel {
max-width:400px;
background:#dadada !important;
}
.fc-nav-flyout-without-ags .fc-nav-flyout-panel-content {
padding:1rem;
}
.fc-swatch {
background-size: 100%;
}
/*****************************************************
Styles for products with attribute groups
*****************************************************/
.using-ag .except-ag {
display: none;
}
.configure-nav-flyout .fc-nav-flyout-ag {
width: 100%;
max-width: 25%;
margin-bottom: 2rem;
margin-right: -5%;
background-color: #fff;
}
.fc-nav-flyout-ag-reveal-left {
position: absolute;
top: 0;
right: 0;
}
.fc-nav-flyout-ag-reveal-right {
position: absolute;
top: 0;
left: 0;
}
.fc-nav-flyout-ag .fc-nav-flyout-panel {
bottom: auto;
padding: 1.5em;
font-size: 0.9em;
}
.fc-nav-flyout-ag .fc-nav-flyout-header .fc-swatch {
border: 1px solid #ccc;
}
.fc-nav-flyout-ag .fc-nav-flyout-panel-header-selected-av {
display: block;
margin: 0.5rem 0.5rem 0.5rem -0.5rem;
}
.fc-nav-flyout-ag .fc-nav-flyout-panel-header-selected-av:before {
content: "";
}
.fc-nav-flyout-ag .fc-nav-flyout-panel-header-selected-av:after {
content: "";
}
.fc-nav-flyout-ag .fc-nav-flyout-active .fc-nav-flyout-panel {
min-width: 350 !important;
background-color: #ccc;
}
.fc-nav-flyout-ag .fc-nav-flyout.fc-nav-flyout-reveal-left .fc-nav-flyout-header:before {
border-left: 10px solid #ccc;
}
.fc-nav-flyout-ag .fc-nav-flyout-active {
background-color: #eee;
}
/*****************************************************
Quick Preview: Animate the flyout panel
*****************************************************/
body.preview-animate .fc-nav-flyout-ca .fc-nav-flyout-header {
z-index:1;
}
body.preview-animate .fc-nav-flyout-ca .fc-nav-flyout-panel {
display:block !important;
visibility:hidden;
opacity:0;
-webkit-transform:translateX(10%);
-moz-transform:translateX(10%);
transform:translateX(10%);
-webkit-transition:all 0.15s ease;
-moz-transition:all 0.15s ease;
transition:all 0.15s ease;
}
body.preview-animate .fc-nav-flyout-ca.fc-nav-flyout-active .fc-nav-flyout-panel {
transform:translateX(0);
visibility:visible;
opacity:1;
}
/* additional animations for the accordion for products with attribute groups */
body.preview-animate .fc-nav-flyout-ag .fc-is-open .fc-accordion-panel-body-revealer {
-webkit-transition: all 0.2s ease-in-out 0.15s;
-moz-transition: all 0.2s ease-in-out 0.15s;
transition: all 0.2s ease-in-out 0.15s;
}
body.preview-animate .fc-nav-flyout-ag .fc-is-closed .fc-accordion-panel-body-revealer {
-webkit-transition: max-height 0.1s ease-in-out;
-moz-transition: max-height 0.1s ease-in-out;
transition: max-height 0.1s ease-in-out;
}
body.preview-animate .fc-nav-flyout-ag .fc-is-open .fc-accordion-panel-body {
-webkit-transition: opacity 0.4s ease-out;
-moz-transition: opacity 0.4s ease-out;
transition: opacity 0.4s ease-out;
}
/*****************************************************
Quick Preview: Make the Nav Flyout Auto-Height
*****************************************************/
body.preview-auto-height .fc-nav-flyout-without-ags > li.fc-nav-flyout-ca {
position:relative;
}
body.preview-auto-height .fc-nav-flyout-without-ags .fc-nav-flyout-panel {
bottom:auto !important;
}
/*****************************************************
Quick Preview: Slide Configurator Over On Flyout Open
*****************************************************/
body.preview-slide .configure-display-container {
-webkit-transform:translateX(0);
-moz-transform:translateX(0);
transform:translateX(0);
-webkit-transition:all 0.15s ease;
-moz-transition:all 0.15s ease;
transition:all 0.15s ease;
}
body.preview-slide.slide-open .configure-display-container {
-webkit-transform:translateX(-260px);
-moz-transform:translateX(-260px);
transform:translateX(-260px);
}
/*****************************************************
Quick Preview: Flyout anchored
*****************************************************/
body.preview-anchored .fc-nav-flyout-ag .fc-is-open .fc-nav-flyout-active {
position: static;
}
body.preview-anchored .fc-nav-flyout-ag .fc-is-open .fc-nav-flyout-active .fc-nav-flyout-panel {
top: 0;
}
/* ADA compliance styles */
.fc-outline-target:focus {
outline-width: 5px;
}
.fc-outline-target:focus[tabindex="-1"] {
outline-color: #ccc;
}
/* USER INTERAXTION FEEDBACK */
.fc-accordion-panel-header:after,
.fc-attribute-header:after {
content: "✔";
display: none;
font-size: 1em;
border-radius: 30px;
box-shadow: 1px 1px 1px gray;
background: green;
width: 25px;
height: 25px;
color: white;
padding: 5px;
float: right;
}
.fc-accordion-panel-header:after {
margin: -5px 18px 0 0;
}
.fc-accordion-panel-header.fc-user-edited-all:after,
.fc-attribute-header.fc-user-edited-all:after {
display: inline-block; }
.fc-accordion-panel-header.fc-user-edited-some:after,
.fc-attribute-header.fc-user-edited-some:after {
display: inline-block;
opacity: 0.2; }
/*
User interaction debugging
Enable by including &debug-interaction=true on the URL
*/
.debug-interaction .fc-facet-selector-wrapper:after {
content: "";
display: none;
right: -20px;
position: relative;
color: #666; }
.debug-interaction .fc-facet-selector-wrapper.fc-user-changed-facet {
border: 2px dotted #0795ab;
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAJElEQVQYV2M0v//n/0lFFkYGJADmoEvAVSBLoGiDSaAIwowCAAlgExfb6/mjAAAAAElFTkSuQmCC") repeat; }
.debug-interaction .fc-facet-selector-wrapper.fc-user-edited-facet {
border: 2px dotted #7e16f5;
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAJElEQVQYV2M8Ne//f7MkRkYGJADmoEvAVSBLoGiDSaAIwowCABA/E2zKX04lAAAAAElFTkSuQmCC") repeat; }
.debug-interaction .fc-facet-selector-wrapper.fc-user-changed-facet:after {
display: block;
content: "sympathetically changed facet"; }
.debug-interaction .fc-facet-selector-wrapper.fc-user-edited-facet:after {
display: block;
content: "facet edited by user"; }
.debug-interaction .fc-attribute-selector:after {
content: "";
display: none;
right: -20px;
position: relative;
color: #666; }
.debug-interaction .fc-attribute-selector.fc-user-edited-all {
border: 2px solid #00ff00;
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAFCAYAAABmWJ3mAAAAKElEQVQYV2NkQAN+X8X+g4QYkcVhgpu4XzHCJZAF4TrQBcESMEF0uwANlBC2E3PniQAAAABJRU5ErkJggg==") repeat; }
.debug-interaction .fc-attribute-selector.fc-user-edited-some {
border: 2px solid #ffff00;
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAFCAYAAABmWJ3mAAAAKElEQVQYV2NkQANfH4n9BwkxIovDBLnlXjHCJZAF4TrQBcESMEF0uwBn6hHedFp5ygAAAABJRU5ErkJggg==") repeat; }
.debug-interaction .fc-attribute-selector.fc-user-changed:after {
display: block;
content: "attribute changed as a side effect"; }
.debug-interaction .fc-attribute-selector.fc-user-edited:after {
display: block;
content: "attribute changed by user"; }
.debug-interaction .fc-attribute-selector.fc-user-edited-all:after {
display: block;
content: "all attributes in this group selected"; }
.debug-interaction .fc-attribute-selector.fc-user-edited-some:after {
display: block;
content: "some attributes in this group selected"; }
<link href="https://code.fluidretail.net/configure-ui/stable/css/configure-app.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment