web components not deployed in vaadin flow production - vaadin

I'm using vaadin flow 23.2 and I've built a couple of web components.
The web components work fine in my development environment however they don't appear to work when I deploy them to production.
The most obvious sign is that in development the tags have a shadow DOM where in production there is no shadow dom.
I should perhaps mention that this components are only used client side.
I have a server side component for each web-component but the server side component isn't being used to create the component.
Instead the components are rendered by sending raw html to the browser.
This is the code for one of the components:
import { css, html, LitElement } from 'lit';
import { property } from 'lit/decorators.js';
export class HintBlock extends LitElement {
#property()
colour = 'green';
static styles =
css`
.red {
border-left: 4px solid red;
padding: 10px;
margin: 10px;
}
.green {
border-left: 4px solid green;
padding: 10px;
margin: 10px;
}
.blue {
border-left: 4px solid blue;
padding: 10px;
margin: 10px;
}
.orange {
border-left: 4px solid orange;
padding: 10px;
margin: 10px;
}
`;
render() {
return html`
<div class=${this.colour}>
<slot></slot>
</div>
`;
}
}
customElements.define('hint-block', HintBlock);
The unused server side component:
package dev.onepub.components;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.dependency.JsModule;
/**
* Server side for HintBlock Web Component
* #author bsutton
*
*/
#Tag("hint-block")
#JsModule("./components/hint-block/hint-block.ts")
public class WCHintBlock extends Component {
static Logger logger = LogManager.getLogger();
private static final long serialVersionUID = 1L;
public WCHintBlock(String content) {
this.setContent(content);
}
private void setContent(String content) {
getElement().setProperty("content", content);
}
}
On my development system the block is rendered as:
On production the same block is rendered as:
Do I need to perform some action to have the custom web components included in the production build?
I though the #JsModule and #Tag annotations were sufficient?

If you are using the web component indirectly, e.g. in your other templates, you need to add some hint for Vaadin's build plugin to pick the component. One way to do this is to add #Uses annotation in the view class where it is used or main layout.
#Uses(WCHintBlock.class)
It is actually irrelevant where it is as it is used build time. However those two locations are probably making most sense semantically.
I have covered the case also in my blog post about creating custom components.

Related

How to Save a page assembled using GrapeJS to a database using ASP.NET MVC

Well, I am developing my own Content Management System using ASP.NET MVC and for a page builder I've decided to use GrapeJS. Now, since this is new to me, I can't seem to find a way to save the pages I would have assembled using GrapeJS. I have used the gjs-preset-webpage GrapeJS plugin and the only JavaScript for the assembling area I have is as shown below:
<script type="text/javascript">
var editor = grapesjs.init({
height: '100%',
showOffsets: 1,
noticeOnUnload: 0,
storageManager: { autoload: 0 },
container: '#gjs',
fromElement: true,
plugins: ['gjs-preset-webpage'],
pluginsOpts: {
'gjs-preset-webpage': {}
}
});
</script>
The HTML I've used is as follows as well:
<div id="gjs" style="height:0px; overflow:hidden">
<div class="panel">
<h1 class="welcome">Welcome to</h1>
<div class="big-title">
<svg class="logo" viewBox="0 0 100 100">
<path d="M40 5l-12.9 7.4 -12.9 7.4c-1.4 0.8-2.7 2.3-3.7 3.9 -0.9 1.6-1.5 3.5-1.5 5.1v14.9 14.9c0 1.7 0.6 3.5 1.5 5.1 0.9 1.6 2.2 3.1 3.7 3.9l12.9 7.4 12.9 7.4c1.4 0.8 3.3 1.2 5.2 1.2 1.9 0 3.8-0.4 5.2-1.2l12.9-7.4 12.9-7.4c1.4-0.8 2.7-2.2 3.7-3.9 0.9-1.6 1.5-3.5 1.5-5.1v-14.9 -12.7c0-4.6-3.8-6-6.8-4.2l-28 16.2" />
</svg>
<span>GrapesJS</span>
</div>
<div class="description">
This is a demo content from index.html. For the development, you shouldn't edit this file, instead you can
copy and rename it to _index.html, on next server start the new file will be served, and it will be ignored by git.
</div>
</div>
<style>
.panel {
width: 90%;
max-width: 700px;
border-radius: 3px;
padding: 30px 20px;
margin: 150px auto 0px;
background-color: #d983a6;
box-shadow: 0px 3px 10px 0px rgba(0,0,0,0.25);
color: rgba(255,255,255,0.75);
font: caption;
font-weight: 100;
}
.welcome {
text-align: center;
font-weight: 100;
margin: 0px;
}
.logo {
width: 70px;
height: 70px;
vertical-align: middle;
}
.logo path {
pointer-events: none;
fill: none;
stroke-linecap: round;
stroke-width: 7;
stroke: #fff
}
.big-title {
text-align: center;
font-size: 3.5rem;
margin: 15px 0;
}
.description {
text-align: justify;
font-size: 1rem;
line-height: 1.5rem;
}
</style>
</div>
Now that I have embedded it into my project and can assembled pages using it, I can't seem to find how to save or where would the assembled page be to be saved. Can anyone help me?
You need a endpoint to allow grapes' storage manager to send your site current status information. I save the json and html just in case, but I think json is enough. Well then you setup your storage manager.
const editor = grapesjs.init({
storageManager:{
type: 'remote',
autosave: true, // Store data automatically
urlStore: 'YOUR_ENDPOINT_URL',
}
});
You will get a call to your endpoint every time something changes with the following parameterts:
gjs-assets: Assets array
gjs-components: Object with markup definition of your site
gjs-styles: Object with styles definition
gjs-html: your site HTML
gjs-css: your CSS
Just be sure to inject this definitions when initialising grapes as well:
const editor = grapesjs.init({
components: "YOUR_STORED_COMPONENTS_HERE",
style: "YOUR_STORED_CSS_HERE",
storageManager:{
type: 'remote',
autosave: true, // Store data automatically
urlStore: 'YOUR_ENDPOINT_URL',
}
});
For further information: Docs

position: fixed is not working in iOS when loading Angular site inside iframe in Ionic 3

Brief Description on what we are trying to achieve
We are developing an Angular application. We developed it for both Web and Mobile using same code base. Mobile version contains lot of features such as Push Notifications, SMS Subscriptions etc. We are hoping to publish mobile version to App store and Play store. We are using simple Ionic 3 app to build it to Android and iOS.
Ionic 3 application contains only one page in which we are loading our Angular Web Site inside an iframe.
HTML of Ionic page
<ion-content>
<iframe class= 'webPage' [src]="iframeSrc" webkitAllowFullScreen mozallowfullscreen allowFullScreen>
</iframe>
</ion-content>
TS of Ionic page
export class HomePage {
iframeSrc: any;
sanitizer: DomSanitizer;
url: string = 'https://angular-load-ionic-iframe.stackblitz.io';
constructor( sanitizer: DomSanitizer ) {
this.sanitizer = sanitizer;
this.iframeSrc = this.sanitizer.bypassSecurityTrustResourceUrl(this.url);
}
}
Find The Github Repository of Ionic 3 app Here.
I have created StackBlitz Angular project which similar to My Angular application. Find it Here.
My Issue
In my application, app-header and app-footer need to be fixed to
ViewPort and other content should be able to scroll. I successfully
achieved this for Android But in iOS, app-header and app-footer
are not fixed to ViewPort and those are scrolling with other content
when I load my Angular application inside an iframe in Ionic app.
header.component.html
<header>
<div class="main">
<h3>Countries</h3>
</div>
</header>
header.component.css
.main {
background-color: #46454A;
color: rgba(255,255,255,.6);
padding:5px 50px;
}
header{
position: fixed;
z-index: 10;
top: 0;
width: 100%;
}
footer.component.html
<footer class="footer">
<h3>This is footer</h3>
</footer>
footer.component.css
.footer{
position: fixed;
bottom: 0;
width: 100%;
background-color:#47454b;
}
h3 {
color: white;
padding:0px 50px;
}
I couldn't figure out Is it CSS issue with iOS or Is it occurred as I load angular web site inside iframe. Struggling for one day but still no success. If anyone can help me to fix this issue highly appreciated and If someone need more details about this feel free to comment.
put this css in your style.css
body {
margin: 0px;
}
h3 {
color: white;
padding:0px 50px;
}
my-app{
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
}
app-header,app-home,app-footer{
position: absolute;
left: 0;
width: 100%;
}
app-header,app-footer{
text-align: center;
color: white;
height: 50px;
background-color:#47454b;
}
app-header{
top:0;
}
app-footer{
bottom:0;
}
app-home {
top: 50px;
bottom: 50px;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
remove all css of header.component.css and footer.component.css
here is stackblitz link https://stackblitz.com/edit/angular-load-ionic-iframe-knkgq4?file=src%2Fstyles.css
Have you tried just setting the entire app mode / platform style to md via the app config? If you are able to solve this problem on Android then perhaps adopting Android styles globally for the iOS version will solve it for that platform too?
// app.module.ts
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { FormsModule } from '#angular/forms';
import { IonicModule } from '#ionic/angular';
import { AppComponent } from './app.component';
import { HeaderComponent } from './header/header.component';
import { FooterComponent } from './footer/footer.component';
import { HomeComponent } from './home/home.component';
#NgModule({
imports: [
BrowserModule, FormsModule,
IonicModule.forRoot({
mode: 'md'
}),
],
declarations: [ AppComponent, HeaderComponent, FooterComponent, HomeComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Im not familiar with ionic and your angular setup but: there is a similar position fixed bug in safari Browsers.
The problem is: you cant position fixed Elements that are direct Children of the body tag.
The solution is: wrapping the content in another div. And putting every inside it.
Maybe you can try to put your Header and footer element inside an extra div so the footer isnt a direct child of the body tag.
Not tried, but worth a try:
style.css
body {
margin: 0px;
position: sticky;
z-index: -1;
width: 100%;
}
home.component.html
<div style="display: block;">
<div class="container" *ngFor="let country of countries">
<div class="code"><strong>Code:</strong> {{country.countryCode}}</div>
<div class="name"><strong>Name:</strong> {{country.countryName}}</div>
</div>
</div>
footer.component.css
.footer{
position: fixed;
bottom: 0;
width: 100%;
background-color:#47454b;
z-index:99;
}
h3 {
color: white;
padding:0px 50px;
}
I had similar issues in IE with sticky footer and header, this does the trick for me. You said that you are using iframes, but could not find some in your fork, only div-wrapped content... if you include the iframe, you can try to apply a relative positioning for the iframe like
position: relative;
to avoid collision with the header and footer. Hope this helps.

How to create an (image) Header logo with MVC(4)

I'm struggling with an Razor syntax with MVC (4), hoping to find someone who can help me with a nice and working solution.
I want a clickable logo(image) and created the following code. This works except of two things. I don't see the image display and secondly, when in an other controller, the routing goes wrong (http4 error).
This is how i've done it now:
Razor:
<h1>#Html.ActionLink("siteHeader", "Index", null, new { #class = "site-logo"})</h1>
OR
<h1>#Html.ActionLink("siteHeader", "Index", "Home", new { #class = "site-logo"})</h1>
e.g. when in a different controller (account/shoppingcart/etc.) and clicking the logo, it results in a 404.
CSS:
/Site HeaderLogo/
a.site-logo {
background: url(images/Solosoft.png) no-repeat top left;
display: block;
width: 100px;
height: 100px;
text-indent: -9999px; /*hides the link text*/
}
Thanks in advance.
Try this:
#Html.ActionLink("siteHeader", "Index", "Home", null, new { #class = "site-logo"})
This is:
public static MvcHtmlString ActionLink(
this HtmlHelper htmlHelper,
string linkText,
string actionName,
string controllerName,
Object routeValues,
Object htmlAttributes
)
Link: msdn
I got the problem cause!
theres nothing wrong with our coding, the thing is theres a class that overrides our image set
theres this lines in Site.css
.site-title a, .site-title a:hover, .site-title a:active {
*background: none;* <=comment this out and the bg will show or remove the .site-title a
color: #c8c8c8;
outline: none;
text-decoration: none;
}
hope it helps
What wizzardz said is correct. Background style in custom css file is overridden by styles in site.css.
Try this, !important - used to give priority to styles to appear in webpage.
In your custom.css page,
a.site-logo {
background: url(images/Solosoft.png) no-repeat top left **!important**;
display: block;
width: 100px;
height: 100px;
text-indent: -9999px; /*hides the link text*/
}
No need to change anything in site.css

How to create a printable Twitter-Bootstrap page

I'm using Twitter-Bootstrap and I need to be able to print the page the way it looks on the browser. I'm able to print other pages made with Twitter-Bootstrap just fine but I can't seem to print my page that uses purely Twitter-Bootstrap. Am I missing a tag somewhere?
Official TB page when printed:
My page when printed:
What my page actually looks like:
Bootstrap 3.2 update: (current release)
Current stable Bootstrap version is 3.2.0.
With version 3.2 visible-print deprecated, so you should use like this:
Class Browser Print
-------------------------------------------------
.visible-print-block Hidden Visible (as block)
.visible-print-inline Hidden Visible (as inline)
.visible-print-inline-block Hidden Visible (as inline-block)
.hidden-print Visible Hidden
Bootstrap 3 update:
Print classes are now in documents: http://getbootstrap.com/css/#responsive-utilities-print
Similar to the regular responsive classes,
use these for toggling content for print.
Class Browser Print
----------------------------------------
.visible-print Hidden Visible
.hidden-print Visible Hidden
Bootstrap 2.3.1 version:
After adding bootstrap.css file into your HTML,
Find the parts that you don't want to print and add hidden-print class into tags.
Because css file includes this:
#media print {
.visible-print { display: inherit !important; }
.hidden-print { display: none !important; }
}
Be sure to have a stylesheet assigned for printing.
It could be a separate stylesheet:
<link rel="stylesheet" type="text/css" media="print" href="print.css">
or one you share for all devices:
<link rel="stylesheet" type="text/css" href="bootstrap.min.css"> # Note there's no media attribute
Then, you can write your styles for printers in the separate stylesheets or in the shared one using media queries:
#media print {
/* Your styles here */
}
Replace every col-md- with col-xs-
eg: replace every col-md-6 to col-xs-6.
This is the thing that worked for me to get me rid of this problem you can see what you have to replace.
There's a section of #media print code in the css file (Bootstrap 3.3.1 [UPDATE:] to 3.3.5), this strips virtually all the styling, so you get fairly bland print-outs even when it is working.
For now I've had to resort to stripping out the #media print section from bootstrap.css - which I'm really not happy about but my users want direct screen-grabs so this'll have to do for now. If anyone knows how to suppress it without changes to the bootstrap files I'd be very interested.
Here's the 'offending' code block, starts at line #192:
#media print {
*,
*:before,enter code here
*:after {
color: #000 !important;
text-shadow: none !important;
background: transparent !important;
-webkit-box-shadow: none !important;
box-shadow: none !important;
}
a,
a:visited {
text-decoration: underline;
}
a[href]:after {
content: " (" attr(href) ")";
}
abbr[title]:after {
content: " (" attr(title) ")";
}
a[href^="#"]:after,
a[href^="javascript:"]:after {
content: "";
}
pre,
blockquote {
border: 1px solid #999;
page-break-inside: avoid;
}
thead {
display: table-header-group;
}
tr,
img {
page-break-inside: avoid;
}
img {
max-width: 100% !important;
}
p,
h2,
h3 {
orphans: 3;
widows: 3;
}
h2,
h3 {
page-break-after: avoid;
}
select {
background: #fff !important;
}
.navbar {
display: none;
}
.btn > .caret,
.dropup > .btn > .caret {
border-top-color: #000 !important;
}
.label {
border: 1px solid #000;
}
.table {
border-collapse: collapse !important;
}
.table td,
.table th {
background-color: #fff !important;
}
.table-bordered th,
.table-bordered td {
border: 1px solid #ddd !important;
}
}
Best option I found was http://html2canvas.hertzen.com/
http://jsfiddle.net/nurbsurf/1235emen/
html2canvas(document.body, {
onrendered: function(canvas) {
$("#page").hide();
document.body.appendChild(canvas);
window.print();
$('canvas').remove();
$("#page").show();
}
});
In case someone is looking for a solution for Bootstrap v2.X.X here. I am leaving the solution I was using. This is not fully tested on all browsers however it could be a good start.
1) make sure the media attribute of bootstrap-responsive.css is screen.
<link href="/css/bootstrap-responsive.min.css" rel="stylesheet" media="screen" />
2) create a print.css and make sure its media attribute print
<link href="/css/print.css" rel="stylesheet" media="print" />
3) inside print.css, add the "width" of your website in html & body
html,
body {
width: 1200px !important;
}
4.) reproduce the necessary media query classes in print.css because they were inside bootstrap-responsive.css and we have disabled it when printing.
.hidden{display:none;visibility:hidden}
.visible-phone{display:none!important}
.visible-tablet{display:none!important}
.hidden-desktop{display:none!important}
.visible-desktop{display:inherit!important}
Here is full version of print.css:
html,
body {
width: 1200px !important;
}
.hidden{display:none;visibility:hidden}
.visible-phone{display:none!important}
.visible-tablet{display:none!important}
.hidden-desktop{display:none!important}
.visible-desktop{display:inherit!important}
2 things FYI -
For now, they've added a few toggle classes. See what's available in the latest stable release - print toggles in responsive-utilities.less
New and improved solution coming in Bootstrap 3.0 - they're adding a separate print.less file. See separate print.less
To make print view look like tablet or desktop include bootstrap as .less, not as .css and then you can overwrite bootstrap responsive classes in the end of bootstrap_variables file for example like this:
#container-sm: 1200px;
#container-md: 1200px;
#container-lg: 1200px;
#screen-sm: 0;
Don't worry about putting this variables in the end of the file. LESS supports lazy loading of variables so they will be applied.
If you want to keep columns on A4 print (which is around 540px) this is a good idea
#media print {
.make-grid(print-A4);
}
.make-print-A4-column(#columns) {
#media print {
float: left;
width: percentage((#columns / #grid-columns));
}
}
You can use it like this:
<div class="col-sm-4 col-print-A4-4">

How to DRY Sass code using variables?

I have a design that uses colors to identify sections of the site. I have put a file with the color variables defined, since they can change and it is difficult to track them down through the CSS files.
$people: #D50000;
$galleries: #D500AA;
$projects: #D5BA00;
//etc...
The name of my classes matches those of the variables. For example, the navigation menu is something like:
<ul>
<li class="people">People</div>
<li class="galleries">Galleries</div>
<li class="projects">Projects</div>
<!-- etc... ->
</ul>
and I find myself writing SASS like
#nav {
ul {
li.people { border-left: 5px solid $people; }
li.galleries { border-left: 5px solid $galleries; }
li.projects { border-left: 5px solid $projects; }
}
}
which I'd like to DRY up. I have tried to use mixins, but I don't know how to tell SASS to lookup a variable named after the argument I pass (variable indirection). I have something like:
#mixin menu-states($resource) {
li.#{$resource} a { // This works
border-left: 7px solid $#{$resource}; // But this doesn't...
}
}
Does anybody have a suggestion on how to DRY this? Thanks.
this code works for me
#mixin test($resource: "red"){
$updated: unquote($resource);
li.#{$updated} a{
border-left: 7px solid $updated;
}
}
You cant do that, however you can pass in 2 variables, one for the class and another for the color to the mixin.

Resources