script#program-view-template(type="text/x-template") .program-page // ----- Modal dialogs ----- message(:show.sync="showGcodeMessage") h3(slot="header") Processing New File div(slot="body") h3 Please wait.. p Simulating GCode to check for errors, calculate ETA and generate 3D view. div(slot="footer") label Simulating {{(toolpath_progress || 0) | percent}} message(:show.sync="GCodeNotFound") h3(slot="header") File not found div(slot="body") p It seems like the file you selected cannot be found. Try uploading again. div(slot="footer") button.pure-button.button-error(@click="GCodeNotFound=false") OK message(:show.sync="uploading_files") h3(slot="header") Files uploading div(slot="body") h3 Please wait... p p The files are currently being uploaded. p Do not close the window. div(slot="footer") message.error-message(:show.sync="deleteGCode") h3(slot="header") Select files to delete: div(slot="body") input.search-bar(type="text", v-model="search_query", placeholder="Search Files...") .container .folders h3 Folders div(v-for="(index, folder) in state.gcode_list", :key="index", @click="populateFiles(index)", class="folder-item", :class="{ selected: index === selected_folder_index }") {{ folder.name }} .files h3 Files label.file-item(v-for="item in gcode_filtered_files", :key="item") input(type="checkbox", :value="item", v-model="selected_items_to_delete") | {{ item }} div(slot="footer") button.pure-button(@click="cancel_delete", style="height:50px") Cancel button.pure-button.button-success(@click="delete_current", style="height:50px") .fa.fa-trash |  Selected message(:show.sync="create_folder") h3(slot="header") Enter folder name: div(slot="body") input.input-name(type="text", minlength="1", maxlength="15", style="margin-top:1rem;margin-bottom:2rem;", id="folder-name", v-model="folder_name", @keypress="edited_folder_name") div(slot="footer") button.pure-button(@click="cancel_new_folder") Cancel button.pure-button.button-success(@click="create_new_folder", :disabled="!edited") Create message(:show.sync="confirmDelete") h3(slot="header") Delete Folder? div(slot="body") p Are you sure to delete the folder? div(slot="footer") button.pure-button(@click="confirmDelete=false") Cancel button.pure-button.button-error(@click="delete_folder") Folder only button.pure-button.button-success(@click="delete_folder_and_files") Folder and files .program-card // Action bar (RUN / STOP / Upload / Download / Delete) .action-bar button.action-btn.run(:class="{'attention': is_holding}", @click="start_pause", :disabled="!state.selected", :title="is_running ? 'Pause program.' : 'Start program.'") .fa.fa-play.ico(v-if="!is_running") .fa.fa-pause.ico(v-else) span {{is_running ? 'PAUSE' : 'RUN'}} button.action-btn.stop(@click="stop", title="Stop program.") .fa.fa-stop.ico span STOP button.action-btn(@click="open_folder", :disabled="!is_ready", title="Upload a new GCode folder.") .fa.fa-folder-plus.ico span UPLOAD FOLDER form.gcode-folder-input.file-upload input#folderInput(type="file", @change="upload_folder", :disabled="!is_ready", webkitdirectory, directory) button.action-btn(@click="open_file", :disabled="!is_ready", title="Upload a new GCode program.") .fa.fa-file-arrow-up.ico span UPLOAD FILE form.gcode-file-input.file-upload input(type="file", @change="upload_file", :disabled="!is_ready", accept=".nc,.ngc,.gcode,.gc", multiple) a(:href="state.selected ? '/api/file/' + state.selected : '#'", download, :class="{disabled: !state.selected}", title="Download the selected GCode program.") button.action-btn(:disabled="!state.selected") .fa.fa-file-arrow-down.ico span DOWNLOAD FILE button.action-btn.danger(@click="deleteGCode = true", :disabled="!state.selected || !is_ready", title="Delete current GCode program.") .fa.fa-trash.ico span DELETE // File / folder selectors .file-bar button.file-btn(@click="create_folder=true", :disabled="!is_ready") .fa.fa-folder-plus |  Create Folder button.file-btn(@click="confirmDelete=true", :disabled="!is_ready") .fa.fa-folder-minus |  Delete Folder select.file-select(title="Select previously uploaded GCode folder.", v-model="state.folder", @change="reset_gcode", :disabled="!is_ready") option(selected, value="default") Default folder option(v-for="file in gcode_folders", :value="file") {{file}} select.file-select.primary(title="Select previously uploaded GCode programs.", v-model="state.selected", @change="load", :disabled="!is_ready") option(value="") (no file) option(v-for="file in gcode_files", :value="file") {{file}} button.file-btn(@click="toggle_sorting", :disabled="!is_ready") .fa.fa-arrow-down-wide-short |  {{files_sortby}} // Body: gcode listing on the left, 3D viewer on the right. // The 3D path-viewer is suppressed when the UI is loaded by // the Pi's onboard kiosk browser — the VideoCore IV cannot // run three.js at a usable frame rate. Off-Pi clients still // see the full split. .program-body(:class="{'no-preview': is_kiosk}") gcode-viewer path-viewer(v-if="!is_kiosk", :toolpath="toolpath", :state="state", :config="config") .progress-bar(v-if="toolpath_progress && toolpath_progress < 1", title="Simulating GCode to check for errors, calculate ETA and generate 3D view.") div(:style="'width:' + (toolpath_progress || 0) * 100 + '%'") label Simulating {{(toolpath_progress || 0) | percent}}