Merge remote-tracking branch 'origin/develop' into develop

This commit is contained in:
Samuele Locatelli
2020-09-23 18:06:18 +02:00
19 changed files with 521 additions and 105 deletions
@@ -309,7 +309,7 @@
margin-right: 20px;
.fa-arrow-up,
.fa-arrow-down {
.fa-arrow-down {
font-size: 24px;
}
@@ -890,7 +890,7 @@
.axes:last-child {
margin-bottom: 16px;
}
.tabs {
min-height: 30px;
width: 100%;
@@ -937,7 +937,7 @@
border-radius: 2px;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.4);
.label-container{
.label-container {
display: flex;
justify-content: space-around;
font-weight: 600;
@@ -962,6 +962,63 @@
}
.card-folder-path {
.context-menu {
position: relative;
width: 40px;
.context-area {
top: 50px;
display: none;
background-color: #fff;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.4);
position: absolute;
width: 300px;
left: -150px + 24px;
padding-inline-start: 0;
padding-inline-end: 0;
&.show {
display: block !important;
z-index: 10;
}
li {
list-style-type: none;
height: 62px;
border-bottom: 1px solid rgba(0, 0, 0, 0.5);
color: #545454;
display: flex;
align-items: center;
justify-content: flex-start;
padding: 0 28px;
font-weight: 500;
font-size: 18px;
cursor: pointer;
&:last-of-type {
border-bottom: none;
}
}
&:before {
content: "";
position: absolute;
top: -15px;
left: calc(~'50% - 8px');
display: block;
width: 0;
height: 0;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
border-bottom: 15px solid #fff;
}
}
}
width: auto;
height: 64px;
display: flex;
@@ -1555,7 +1612,7 @@
padding-right: 8px;
font-size: 20px;
text-align: left;
padding-left: 8px;
padding-left: 8px;
}
}
@@ -1930,7 +1987,7 @@
background-color: @color-clear-blue-30;
color: #002680;
.not-exist{
.not-exist {
color: #d0021b !important;
}
@@ -6104,4 +6161,4 @@
}
}
}
} */
} */
@@ -10742,6 +10742,53 @@ footer .container button.big:before {
margin: 4px 0 4px 5px;
cursor: pointer;
}
.card-folder-path .context-menu {
position: relative;
width: 40px;
}
.card-folder-path .context-menu .context-area {
top: 50px;
display: none;
background-color: #fff;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.4);
position: absolute;
width: 300px;
left: -126px;
padding-inline-start: 0;
padding-inline-end: 0;
}
.card-folder-path .context-menu .context-area.show {
display: block !important;
z-index: 10;
}
.card-folder-path .context-menu .context-area li {
list-style-type: none;
height: 62px;
border-bottom: 1px solid rgba(0, 0, 0, 0.5);
color: #545454;
display: flex;
align-items: center;
justify-content: flex-start;
padding: 0 28px;
font-weight: 500;
font-size: 18px;
cursor: pointer;
}
.card-folder-path .context-menu .context-area li:last-of-type {
border-bottom: none;
}
.card-folder-path .context-menu .context-area:before {
content: "";
position: absolute;
top: -15px;
left: calc(50% - 8px);
display: block;
width: 0;
height: 0;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
border-bottom: 15px solid #fff;
}
.card-folder-path:not(.disabled):active {
background-color: rgba(0, 0, 0, 0.4);
box-shadow: none;
+7 -7
View File
@@ -67,11 +67,11 @@ export default class app extends Vue {
mounted() {
let ms = messageService;
window.oncontextmenu = function (event) {
event.preventDefault();
event.stopPropagation();
return false;
};
// window.oncontextmenu = function (event) {
// event.preventDefault();
// event.stopPropagation();
// return false;
// };
// if cms is connected
if (typeof cmsClient != "undefined")
@@ -88,7 +88,7 @@ export default class app extends Vue {
ms.subscribeToChannel("hide-modal-login", args => {
this.applyBlur = false;
this.prioritizeWindowsButtons1 = false;
this.prioritizeWindowsButtons1 = false;
});
ms.subscribeToChannel("hide-modal", args => {
@@ -102,7 +102,7 @@ export default class app extends Vue {
ms.subscribeToChannel("hide-modal-nc-called", args => {
this.applyBlurNc = false;
this.prioritizeWindowsButtons2 = false;
this.prioritizeWindowsButtons2 = false;
});
ms.subscribeToChannel("show-modal-internal", args => {
@@ -0,0 +1,28 @@
import Component from "vue-class-component";
import Vue from "vue";
import { Prop } from "vue-property-decorator";
import PrintProcesso from "@/app_modules_thermo/processo/components/printProcesso";
@Component({})
export default class AxisInfo extends Vue {
@Prop()
id: number;
@Prop({ default: 'axes' })
name: string;
@Prop({ default: 'axes-quote' })
quoteLabel: string;
@Prop({ default: 'axes-speed' })
speedLabel: string;
get axis() {
return null;
}
}
@@ -0,0 +1,47 @@
<template>
<div class="axis-info">
<table>
<thead>
<tr>
<th></th>
<th width="200">{{name | localize(name)}}</th>
</tr>
</thead>
<tbody>
<tr>
<th>{{quoteLabel | localize(quoteLabel)}}</th>
<td>0 mm</td>
</tr>
<tr>
<th>{{speedLabel | localize(speedLabel)}}</th>
<td>0 mm/s</td>
</tr>
</tbody>
</table>
</div>
</template>
<script src="./axis-info.ts" lang="ts"></script>
<style scoped>
.axis-info {
position: absolute;
top: 0;
right: 0;
min-width: 250px;
height: 80px;
}
td {
background-color: #1791ff33;
color: #002680;
text-align: right;
}
th {
font-weight: 400;
color: #999;
}
table {
width: 100%;
}
</style>
@@ -1,16 +1,18 @@
import Vue from 'vue';
import Component from 'vue-class-component';
import { Prop } from 'vue-property-decorator';
import Slider from "@/app_modules_thermo/components/slider.vue";
import Scheda from "@/app_modules_thermo/components/scheda.vue";
import Controstamposvg from "./SVG_Components/svgcontrostampo.vue";
import Tastierino from "@/app_modules_thermo/components/tastierino.vue";
import axes from "@/app_modules_thermo/setup/components/axis-info.vue";
@Component({
name: "controstampo",
components: {
scheda: Scheda,
svgcontrostampo: Controstamposvg
svgcontrostampo: Controstamposvg,
axes
}
})
export default class Controstampo extends Vue {
@@ -98,6 +98,7 @@
<!-- <button class="btn btn-success absolute square bottom left">
<img src="assets/icons/png/w.png" />
</button>-->
<axes></axes>
</article>
</section>
</template>
@@ -1,11 +1,12 @@
import Vue from "vue";
import Component from "vue-class-component";
import { Prop } from 'vue-property-decorator';
import Slider from "@/app_modules_thermo/components/slider.vue";
import QuoteVelocitaSVG from "./SVG_Components/quote-velocita.vue";
import Tastierino from "@/app_modules_thermo/components/tastierino.vue";
@Component({ name: "discesacornice", components: { quoteVelocitaSVG: QuoteVelocitaSVG } })
import QuoteVelocitaSVG from "./SVG_Components/quote-velocita.vue";
import axes from "@/app_modules_thermo/setup/components/axis-info.vue";
@Component({ name: "discesacornice", components: { quoteVelocitaSVG: QuoteVelocitaSVG, axes } })
export default class DiscesaCornice extends Vue {
@@ -82,6 +82,7 @@
<!-- <button class="btn btn-success absolute square bottom left">
<img src="assets/icons/png/w.png" />
</button>-->
<axes></axes>
</article>
</section>
</template>
@@ -1,11 +1,10 @@
import Vue from "vue";
import Component from "vue-class-component";
import { Prop } from 'vue-property-decorator';
import Slider from "@/app_modules_thermo/components/slider.vue"
import StampoSVG from "./SVG_Components/stampo.vue";
import Tastierino from "@/app_modules_thermo/components/tastierino.vue";
import axes from "@/app_modules_thermo/setup/components/axis-info.vue";
@Component({ name: "salita-stampo", components: { stampoSVG: StampoSVG } })
@Component({ name: "salita-stampo", components: { stampoSVG: StampoSVG, axes } })
export default class DiscesaCornice extends Vue {
@@ -103,6 +103,7 @@
<!-- <button class="btn btn-success absolute square bottom left">
<img src="assets/icons/png/w.png" />
</button>-->
<axes></axes>
</article>
</section>
</template>
@@ -1,29 +1,53 @@
import { ModalHelper } from '@/components/modals';
import Vue from 'vue';
import Component from 'vue-class-component';
import {Prop} from 'vue-property-decorator';
import { Prop } from 'vue-property-decorator';
import askNameModal from "./modalAskName.vue";
import moveModal from "./modalMove.vue";
@Component({})
export default class CardFolderPath extends Vue{
@Prop({ default: "/assets/icons/_png/folder-closed-25x25.png"})
imgSource:string;
@Prop({ default: "PC"})
name:string;
@Prop({default: true})
withArrow:boolean;
@Prop({default: "FOLDER"})
iconType:string;
@Prop({default: false})
disabled:boolean;
@Prop({default: false})
selected:boolean;
@Prop({default: true})
fileExist:boolean;
onClick(){
if(!this.disabled)
this.$emit("click");
};
export default class CardFolderPath extends Vue {
@Prop({ default: "/assets/icons/_png/folder-closed-25x25.png" })
imgSource: string;
@Prop({ default: "PC" })
name: string;
@Prop({ default: true })
withArrow: boolean;
@Prop({ default: "FOLDER" })
iconType: string;
@Prop({ default: false })
disabled: boolean;
@Prop({ default: false })
selected: boolean;
@Prop({ default: true })
fileExist: boolean;
showactions: boolean = false;
onClick() {
if (!this.disabled)
this.$emit("click");
};
async renameFolder() {
let result = await ModalHelper.ShowModalAsync(askNameModal, { title: 'folder_rename', message: 'new_folder_name', name: this.name });
// funzione di rename
this.$emit("folderRename", { oldname: this.name, newname: result });
}
deleteFolder() {
ModalHelper.AskConfirm(this.$options.filters.localize("modal_delete_confirm", "Richiesta di conferma"),
this.$options.filters.localize("modal_confirm_delete_folder", "Confermi di voler cancellare la cartella?"),
async () => {
//funzione di cancellazione del file
this.$emit("folderDelete", { name: this.name });
}, () => void (0))
}
async moveFile() {
let result = await ModalHelper.ShowModalAsync(moveModal, this.name);
this.$emit("fileMove", { name: this.name, to: result });
}
}
@@ -1,23 +1,70 @@
<template>
<!-- <div class="test-container"> -->
<div class="card-folder-path" @click="onClick" :class="{'disabled': disabled, 'selected-path-drive': selected}">
<div class="card-folder-path-icon">
<i v-if="iconType=='FOLDER'" class="fa fa-folder" aria-hidden="true"></i>
<i v-if="iconType=='FILE'" class="fa fa-file-o" aria-hidden="true"></i>
<i v-if="iconType=='HD'" class="fa fa-hdd-o" aria-hidden="true"></i>
<i v-if="iconType=='USB'" class="fa fa-usb" aria-hidden="true"></i>
<i v-if="iconType=='DATABASE'" class="fa fa-database" aria-hidden="true"></i>
<i v-if="iconType=='NTW'" class="fa fa-sitemap" aria-hidden="true"></i>
<i v-if="iconType=='SPFO'" class="fa fa-star" aria-hidden="true"></i>
</div>
<div class="card-folder-path-name">
<label :class="{'not-exist': !fileExist}">{{name}}</label>
</div>
<div class="card-folder-path-arrow" v-if="withArrow">
<i class="fa fa-caret-right"></i>
</div>
</div>
<!-- </div> -->
<!-- <div class="test-container"> -->
<div
class="card-folder-path"
@click="onClick"
:class="{'disabled': disabled, 'selected-path-drive': selected}"
>
<div class="card-folder-path-icon">
<i v-if="iconType=='FOLDER'" class="fa fa-folder" aria-hidden="true"></i>
<i v-if="iconType=='FILE'" class="fa fa-file-o" aria-hidden="true"></i>
<i v-if="iconType=='HD'" class="fa fa-hdd-o" aria-hidden="true"></i>
<i v-if="iconType=='USB'" class="fa fa-usb" aria-hidden="true"></i>
<i v-if="iconType=='DATABASE'" class="fa fa-database" aria-hidden="true"></i>
<i v-if="iconType=='NTW'" class="fa fa-sitemap" aria-hidden="true"></i>
<i v-if="iconType=='SPFO'" class="fa fa-star" aria-hidden="true"></i>
</div>
<div class="card-folder-path-name">
<label :class="{'not-exist': !fileExist}">{{name}}</label>
</div>
<div class="context-menu">
<div
class="card-folder-dots"
v-if="iconType=='FILE' || iconType == 'FOLDER'"
@click.stop.prevent="showactions = !showactions"
>
<i class="fa fa-ellipsis-v"></i>
</div>
<ul class="context-area" :class="{'show': showactions}">
<li
v-if="iconType == 'FOLDER'"
@click="showactions = false; renameFolder()"
>{{'file_rename' | localize('Rinomina')}}</li>
<li
v-if="iconType == 'FOLDER'"
@click="showactions = false; deleteFolder()"
>{{'file_delete' | localize('Cancella')}}</li>
<li
v-if="iconType=='FILE'"
@click="showactions = false; moveFile()"
>{{'file_move' | localize('Sposta')}}</li>
</ul>
</div>
<div class="card-folder-path-arrow" v-if="withArrow">
<i class="fa fa-caret-right"></i>
</div>
</div>
<!-- </div> -->
</template>
<script lang="ts" src="./card-folder-path.ts"></script>
<script lang="ts" src="./card-folder-path.ts"></script>
<style scoped>
.card-folder-path {
position: relative;
}
.card-folder-dots {
position: relative;
width: 30px;
text-align: CENTER;
padding: 8px;
border: 0.5px solid #ddd;
border-radius: 3px;
margin: 0 2px;
box-sizing: border-box;
}
.card-folder-dots:hover {
}
</style>
@@ -0,0 +1,46 @@
import Vue from "vue";
import Component from "vue-class-component";
import modal from "@/components/modals/modal.vue";
import { Deferred } from "@/services";
import { Prop } from "vue-property-decorator";
import { messageService } from "@/_base";
import { Modal, ModalHelper } from "@/components/modals";
@Component({ components: { modal: Modal } })
export default class Rename extends Vue {
@Prop()
deferred: Deferred<string>;
@Prop()
value: {
title: string,
message: string,
value: string
};
finalName: string = null;
mounted() {
if (this.value && this.value.value)
this.value.value = this.value.value.replace(".rcp", "");
}
get FinalName() {
return this.finalName || this.value.value;
}
set FinalName(value: string) {
this.finalName = value;
}
save(value: string) {
this.deferred.resolve(this.FinalName + ".rcp")
ModalHelper.HideModal();
}
close() {
messageService.deleteChannel("esc_pressed");
this.deferred.reject();
ModalHelper.HideModal();
}
}
@@ -0,0 +1,22 @@
<template>
<div class="setup">
<modal type="save-as" :title="value.title | localize(value.title)">
<div slot="header-buttons">
<button class="modal-close" @click="close()">
<i class="fa fa-remove"></i>
</button>
</div>
<section>
<article>
<label>{{value.message | localize(value.message)}}</label>
<input v-model="FinalName" :placeholder="value.message | localize(value.message)" />
</article>
</section>
<footer>
<button class="btn" @click="close()">{{'cancel' | localize("Annulla")}}</button>
<button class="btn btn-success" @click="save()">{{'confirm' | localize("Conferma")}}</button>
</footer>
</modal>
</div>
</template>
<script src="./modalAskName.ts" lang="ts"></script>
@@ -0,0 +1,42 @@
import Vue from "vue";
import Component from "vue-class-component";
import modal from "@/components/modals/modal.vue";
import { Deferred } from "@/services";
import { Prop } from "vue-property-decorator";
import { messageService } from "@/_base";
import { Modal, ModalHelper } from "@/components/modals";
@Component({ components: { modal: Modal } })
export default class modalMove extends Vue {
@Prop()
deferred: Deferred<string>;
@Prop()
value: string;
recipeName: string = null;
mounted() {
if (this.value)
this.value = this.value.replace(".rcp", "");
}
get RecipeName() {
return this.recipeName || this.value;
}
set RecipeName(value: string) {
this.recipeName = value;
}
save(value: string) {
this.deferred.resolve(this.RecipeName + ".rcp")
ModalHelper.HideModal();
}
close() {
messageService.deleteChannel("esc_pressed");
this.deferred.reject();
ModalHelper.HideModal();
}
}
@@ -0,0 +1,21 @@
<template>
<div class="setup">
<modal type="save-as" :title="'modal_file_move' | localize('Sposta il file in ..')">
<div slot="header-buttons">
<button class="modal-close" @click="close()">
<i class="fa fa-remove"></i>
</button>
</div>
<section>
<article>
<ul></ul>
</article>
</section>
<footer>
<button class="btn" @click="close()">{{'cancel' | localize("Annulla")}}</button>
<button class="btn btn-success" @click="save()">{{'confirm' | localize("Conferma")}}</button>
</footer>
</modal>
</div>
</template>
<script src="./modalMove.ts" lang="ts"></script>
@@ -9,6 +9,7 @@ import * as iziToast from "izitoast";
import ZoomImage from './zoom-image.vue'
import { recipeService } from "@/services/recipeService";
import duplicateModal from "@/app_modules_thermo/save/duplicate.vue";
import askNameModal from "./cards/modalAskName.vue";
declare var cmsClient: any;
@@ -82,8 +83,8 @@ export default class ModalLoadProgram extends Vue {
return this.$store.state.process.canLoadProgram;
}
async duplicate(){
let result = await ModalHelper.ShowModalAsync(duplicateModal,{name:this.selectedFile.Name,folder:this.currentPath});
async duplicate() {
let result = await ModalHelper.ShowModalAsync(duplicateModal, { name: this.selectedFile.Name, folder: this.currentPath });
this.relaodFiles();
}
@@ -91,12 +92,14 @@ export default class ModalLoadProgram extends Vue {
if (typeof cmsClient != "undefined") {
this.driveList = JSON.parse(cmsClient.getOSdriveList());
this.recentPath = cmsClient.RECENT_FOLDER_KEY
this.navigateTo(null,"C:\\CMS\\Recipes",this.isLocalNavigation,1,1);
this.navigateTo(null, "C:\\CMS\\Recipes", this.isLocalNavigation, 1, 1);
}
this.loadClicked = false
}
async navigateTo(path: string, absolutePath: string, local: boolean, todepth: number, fromdepth: number) {
this.currentPath = absolutePath;
this.lastClickPath = absolutePath;
@@ -154,12 +157,12 @@ export default class ModalLoadProgram extends Vue {
}
async relaodFiles() {
this.selectedFile = null;
this.selectedFileMetadata = null;
var files = await this.getFilesForPath(this.currentPath, null);
// controlla se impostare il currentDrive
// Check destination depth
if (this.navigationDepth == 1) {
@@ -268,7 +271,7 @@ export default class ModalLoadProgram extends Vue {
} as FileInfo;
}
porva(){
porva() {
return this.selectedFile.PreviewBase64.replace(/&quot;/g, '\\"');
}
async fileInfo(str, isJob, fromdepth: number) {
@@ -321,7 +324,7 @@ export default class ModalLoadProgram extends Vue {
try {
this.cleanFileWatcher()
messageService.deleteChannel("esc_pressed");
} catch{ }
} catch { }
// ModalHelper.HideModal();
this.$router.back();
}
@@ -329,6 +332,11 @@ export default class ModalLoadProgram extends Vue {
reload() {
this.driveList = JSON.parse(cmsClient.getOSdriveList());
}
async createFolder() {
let result = await ModalHelper.ShowModalAsync(askNameModal, { title: 'folder_create', message: 'new_folder_name', name: "" });
// funzione di creazione del folder
}
getDate(date) {
return moment(date).format("L");
@@ -380,34 +388,32 @@ export default class ModalLoadProgram extends Vue {
this.showZoomedImage = !this.showZoomedImage;
}
duplicateprogram()
{
duplicateprogram() {
var res = cmsClient.editProgram(this.selectedFile.AbsolutePath, this.fileChanged);
}
deleteprogram()
{
deleteprogram() {
ModalHelper.AskConfirm(this.$options.filters.localize("modal_confirm_title", "Richiesta di conferma"),
this.$options.filters.localize("modal_confirm_delete_recipe", "Confermi di voler eliminare la ricetta?"),
async () => {
var res = cmsClient.deleteFile(this.selectedFile.AbsolutePath);
if (res) {
var obj = JSON.parse(res);
if (obj.error) {
(iziToast as any).error({
title: "error",
message: obj.error,
theme: "dark",
timeout: 10000,
class: "t-error",
transitionOut: "fadeOut",
})
this.$options.filters.localize("modal_confirm_delete_recipe", "Confermi di voler eliminare la ricetta?"),
async () => {
var res = cmsClient.deleteFile(this.selectedFile.AbsolutePath);
if (res) {
var obj = JSON.parse(res);
if (obj.error) {
(iziToast as any).error({
title: "error",
message: obj.error,
theme: "dark",
timeout: 10000,
class: "t-error",
transitionOut: "fadeOut",
})
}
}
}
else {
this.relaodFiles();
}
}, () => void (0))
else {
this.relaodFiles();
}
}, () => void (0))
}
@@ -37,14 +37,29 @@
:disabled="!isCnReady()"
@click="navigateTo('\\\\','\\\\', false, 1,0)"
></card-folder-path>-->
<!-- <hr /> --><!--
<card-folder-path
name="testfolder"
:iconType="'FOLDER'"
:selected="'\\\\' == currentDrive"
:disabled="!isCnReady()"
@click="navigateTo('\\\\','\\\\', false, 1,0)"
></card-folder-path>
<card-folder-path
name="testfile"
:iconType="'FILE'"
:selected="'\\\\' == currentDrive"
:disabled="!isCnReady()"
@click="navigateTo('\\\\','\\\\', false, 1,0)"
></card-folder-path>
<!-- <hr /> -->
<!--
<card-folder-path
name="Recent"
:iconType="'SPFO'"
:selected="currentDrive == recentPath"
@click="navigateTo(recentPath, recentPath, true, 1, 0)"
></card-folder-path>
<hr /> -->
<hr />-->
<card-folder-path
v-for="(val, key) in this.driveList"
:key="key"
@@ -63,6 +78,7 @@
:placeholder="'modal_load_program_search_placeholder' | localize('Cerca un programma per nome')"
/>
<i class="fa fa-2x fa-search"></i>
<i class="fa fa-2x fa-folder-o" @click="createFolder()"></i>
</div>
<div class="content scrollable">
<card-folder-path
@@ -89,6 +105,7 @@
:placeholder="'modal_load_program_search_placeholder' | localize('Cerca un programma per nome')"
/>
<i class="fa fa-2x fa-search"></i>
<i class="fa fa-2x fa-folder-o" @click="createFolder()"></i>
</div>
<div class="label-folder-empty" v-if="secondColumnData.length ==0">
<label>{{'modal_load_program_empty_folder' | localize("Cartella vuota")}}</label>
@@ -133,8 +150,15 @@
<div class="selected-item-body" v-if="!selectedFile.IsJob" :class="{blur:fileIsChanged}">
<div class="selected-item-body-image">
<div v-if="selectedFile.PreviewBase64" class="container" @click="ToggleShowZoomedImage">
<svg xmlns="http://www.w3.org/2000/svg" v-html="selectedFile.PreviewBase64" version="1.1" width="100%" height="100%" viewBox="0 0 2000 1500"></svg>
<div v-if="selectedFile.PreviewBase64" class="container" @click="ToggleShowZoomedImage">
<svg
xmlns="http://www.w3.org/2000/svg"
v-html="selectedFile.PreviewBase64"
version="1.1"
width="100%"
height="100%"
viewBox="0 0 2000 1500"
/>
<div class="eye">
<i class="fa fa-eye" aria-hidden="true"></i>
</div>
@@ -145,19 +169,19 @@
>{{'modal_load_program_lbl_img_not_found' | localize('Preview non disponibile')}}</div>
</div>
<div class="selected-item-body-description scrollable">
<div class="row" >
<div class="row">
<label class="key">{{'modal_load_program_lbl_Sheet_X' | localize('Dimensione lastra X:')}}</label>
<label>{{selectedFile.SheetX}}</label>
</div>
<div class="row" >
<div class="row">
<label class="key">{{'modal_load_program_lbl_Sheet_Y' | localize('Dimensione lastra Y:')}}</label>
<label>{{selectedFile.SheetY}}</label>
</div>
<div class="row" >
<div class="row">
<label class="key">{{'modal_load_program_lbl_Sheet_Z' | localize('Spessore lastra:')}}</label>
<label>{{selectedFile.SheetZ}}</label>
</div>
<div class="row" >
<div class="row">
<label class="key">{{'modal_load_program_lbl_notes' | localize('Note:')}}</label>
<label>{{selectedFile.Annotation}}</label>
</div>