517 lines
22 KiB
Plaintext
517 lines
22 KiB
Plaintext
.grid
|
|
.panel.panel-default
|
|
p.page-title
|
|
i.xo-icon-vm(ng-if="isVMWorking(VM)", class="xo-color-pending", tooltip="{{VM.power_state}} and {{values(VM.current_operations)[0]}}")
|
|
i.xo-icon-vm(class="xo-color-{{VM.power_state | lowercase}}",ng-if="!isVMWorking(VM)", tooltip="{{VM.power_state}}")
|
|
| {{VM.name_label}}
|
|
.grid
|
|
.panel.panel-default
|
|
.panel-heading.panel-title
|
|
i.fa.fa-cogs(style="color: #e25440;")
|
|
| General
|
|
span.quick-edit(tooltip="Edit General settings", ng-click="vmSettings.$show()")
|
|
i.fa.fa-edit.fa-fw
|
|
.panel-body
|
|
form(editable-form="", name="vmSettings", onbeforesave="saveVM($data)")
|
|
dl.dl-horizontal
|
|
dt Name
|
|
dd
|
|
span(editable-text="VM.name_label", e-name="name_label", e-form="vmSettings")
|
|
| {{VM.name_label}}
|
|
dt Description
|
|
dd
|
|
span(editable-text="VM.name_description", e-name="name_description", e-form="vmSettings")
|
|
| {{VM.name_description}}
|
|
dt(ng-if="VM.power_state == ('Running' || 'Paused')") Running on:
|
|
dt(ng-if="VM.power_state == ('Halted')") Resident on:
|
|
dd(ng-repeat="container in [VM.$container] | resolve")
|
|
span(ng-if = 'container.type === "host"')
|
|
a(xo-sref="hosts_view({id: container.UUID})")
|
|
| {{container.name_label}}
|
|
small
|
|
span(ng-if="(container.poolRef | resolve).name_label")
|
|
| (
|
|
a(ui-sref="pools_view({id: (container.poolRef | resolve).UUID})") {{(container.poolRef | resolve).name_label}}
|
|
| )
|
|
a(
|
|
ng-if = 'container.type === "pool"'
|
|
xo-sref="pools_view({id: container.UUID})"
|
|
)
|
|
| {{container.name_label}}
|
|
dt(ng-if="VM.addresses") Address
|
|
dd(ng-repeat="IP in VM.addresses") {{IP}}
|
|
span(ng-if="(VM.poolRef | resolve).HA_enabled")
|
|
dt HA
|
|
dd
|
|
span(
|
|
editable-checkbox="VM.high_availability"
|
|
e-name="high_availability"
|
|
e-form="vmSettings"
|
|
)
|
|
| {{VM.high_availability}}
|
|
dt Tags
|
|
dd
|
|
dt vCPUs
|
|
dd
|
|
span(
|
|
editable-text="VM.CPUs.number"
|
|
e-name="CPUs"
|
|
e-form="vmSettings"
|
|
)
|
|
| {{VM.CPUs.number}}
|
|
dt RAM
|
|
dd
|
|
span(
|
|
editable-text="memorySize"
|
|
e-name="memory"
|
|
e-form="vmSettings"
|
|
)
|
|
| {{memorySize}}
|
|
dt UUID
|
|
dd {{VM.UUID}}
|
|
.btn-form(ng-show="vmSettings.$visible")
|
|
p.center
|
|
button.btn.btn-default(
|
|
type="button"
|
|
ng-disabled="vmSettings.$waiting"
|
|
ng-click="vmSettings.$cancel()"
|
|
)
|
|
i.fa.fa-times
|
|
| Cancel
|
|
|
|
|
button.btn.btn-primary(
|
|
type="submit"
|
|
ng-disabled="vmSettings.$waiting"
|
|
)
|
|
i.fa.fa-save
|
|
| Save
|
|
|
|
.panel.panel-default
|
|
.panel-heading.panel-title
|
|
i.xo-icon-stats(style="color: #e25440;")
|
|
| Stats
|
|
.grid
|
|
.grid-cell
|
|
p.stat-name vCPUs
|
|
p.center.big {{VM.CPUs.number}}
|
|
.grid-cell
|
|
p.stat-name RAM
|
|
p.center.big {{VM.memory.size | bytesToSize}}
|
|
.grid-cell
|
|
p.stat-name Disks
|
|
p.center.big {{VM.$VBDs.length || 0}}
|
|
br
|
|
.grid
|
|
.grid-cell(ng-if="VM.os_version.distro")
|
|
p.stat-name OS:
|
|
p.center.big
|
|
i(class="xo-icon-{{osType(VM.os_version.distro)}}",tooltip="{{VM.os_version.name}}", style="color: black;")
|
|
.grid-cell
|
|
p.stat-name Xen tools:
|
|
p.center
|
|
span(ng-if="VM.PV_drivers", style="color:green;") Installed
|
|
span(ng-if="!VM.PV_drivers") NOT installed
|
|
|
|
//- Action panel
|
|
.grid
|
|
.panel.panel-default
|
|
.panel-heading.panel-title
|
|
i.fa.fa-flash(style="color: #e25440;")
|
|
| Actions
|
|
.panel-body.text-center
|
|
.grid
|
|
.grid-cell.btn-group(ng-if="VM.power_state == ('Running' || 'Paused')")
|
|
button.btn(tooltip="Stop VM", type="button", style="width: 90%", xo-click="stopVM(VM.UUID)")
|
|
i.fa.fa-stop.fa-2x.fa-fw
|
|
.grid-cell.btn-group(ng-if="VM.power_state == ('Running')")
|
|
button.btn(tooltip="Suspend VM", type="button", style="width: 90%", xo-click="suspendVM(VM.UUID)")
|
|
i.fa.fa-pause.fa-2x.fa-fw
|
|
.grid-cell.btn-group(ng-if="VM.power_state == ('Suspended')")
|
|
button.btn(tooltip="Resume VM", type="button", style="width: 90%", xo-click="resumeVM(VM.UUID)")
|
|
i.fa.fa-play.fa-2x.fa-fw
|
|
.grid-cell.btn-group(ng-if="VM.power_state == ('Halted')")
|
|
button.btn(tooltip="Start VM", type="button", style="width: 90%", xo-click="startVM(VM.UUID)")
|
|
i.fa.fa-play.fa-2x.fa-fw
|
|
.grid-cell.btn-group(ng-if="VM.power_state == ('Running' || 'Paused')")
|
|
button.btn(tooltip="Reboot VM", type="button", style="width: 90%", xo-click="rebootVM(VM.UUID)")
|
|
i.fa.fa-refresh.fa-2x.fa-fw
|
|
.grid-cell.btn-group.dropdown(
|
|
ng-if="VM.power_state == ('Running' || 'Paused')"
|
|
dropdown
|
|
)
|
|
button.btn.dropdown-toggle(
|
|
dropdown-toggle
|
|
tooltip="Migrate VM"
|
|
type="button"
|
|
style="width: 90%"
|
|
)
|
|
i.fa.fa-share.fa-2x.fa-fw
|
|
<span class="caret"></span>
|
|
ul.dropdown-menu.left(role="menu")
|
|
li(ng-repeat="host in hosts | orderBy:natural('name_label') track by host.UUID")
|
|
a(ng-click="migrateVM(VM.UUID, host.UUID)")
|
|
i.xo-icon-host.fa-fw
|
|
| To {{host.name_label}}
|
|
.grid-cell.btn-group(ng-if="VM.power_state == ('Running' || 'Paused')")
|
|
button.btn(tooltip="Force Reboot", type="button", style="width: 90%", xo-click="force_rebootVM(VM.UUID)")
|
|
i.fa.fa-flash.fa-2x.fa-fw
|
|
.grid-cell.btn-group(ng-if="VM.power_state == ('Running' || 'Paused')")
|
|
button.btn(tooltip="Force Shutdown", type="button", style="width: 90%", xo-click="force_stopVM(VM.UUID)")
|
|
i.fa.fa-power-off.fa-2x.fa-fw
|
|
.grid-cell.btn-group
|
|
button.btn(tooltip="Delete VM", type="button", style="width: 90%", xo-click="destroyVM(VM.UUID)")
|
|
i.fa.fa-trash-o.fa-2x.fa-fw
|
|
.grid-cell.btn-group.dropdown(
|
|
ng-if="VM.power_state == ('Halted')"
|
|
dropdown
|
|
)
|
|
button.btn.dropdown-toggle(
|
|
dropdown-toggle
|
|
tooltip="Create a clone"
|
|
style="width: 90%"
|
|
type="button"
|
|
)
|
|
i.fa.fa-files-o.fa-2x.fa-fw
|
|
<span class="caret"></span>
|
|
ul.dropdown-menu.left(role="menu")
|
|
li
|
|
a(ng-click="cloneVM(VM.UUID,VM.name_label,false)")
|
|
i.fa.fa-code-fork.fa-fw
|
|
| Fast clone
|
|
li
|
|
a(ng-click="cloneVM(VM.UUID,VM.name_label,true)")
|
|
i.xo-icon-sr.fa-fw
|
|
| Full disk copy
|
|
.grid-cell.btn-group
|
|
button.btn(tooltip="Convert to template", type="button", style="width: 90%", xo-click="convertVM(VM.UUID)")
|
|
i.fa.fa-thumb-tack.fa-2x.fa-fw
|
|
.grid-cell.btn-group
|
|
button.btn(tooltip="Create a snapshot", style="width: 90%", type="button", xo-click="snapshotVM(VM.UUID,VM.name_label)")
|
|
i.xo-icon-snapshot.fa-2x.fa-fw
|
|
.grid-cell.btn-group
|
|
button.btn(tooltip="Export the VM", style="width: 90%", type="button", xo-click="exportVM(VM.UUID)")
|
|
i.fa.fa-download.fa-2x.fa-fw
|
|
.grid-cell.btn-group(style="margin-bottom: 0.5em")
|
|
button.btn(tooltip="VM Console", type="button", style="width: 90%", xo-sref="consoles_view({id: VM.UUID})")
|
|
i.xo-icon-console.fa-2x.fa-fw
|
|
//- Disk panel
|
|
.grid
|
|
.panel.panel-default
|
|
.panel-heading.panel-title
|
|
i.xo-icon-sr(style="color: #e25440;")
|
|
| Disk
|
|
span.quick-edit(
|
|
ng-if="!disksForm.$visible"
|
|
tooltip="Edit disks"
|
|
ng-click="disksForm.$show()"
|
|
)
|
|
i.fa.fa-edit.fa-fw
|
|
span.quick-edit(
|
|
ng-if="disksForm.$visible"
|
|
tooltip="Cancel Edition"
|
|
ng-click="disksForm.$cancel()"
|
|
)
|
|
i.fa.fa-undo.fa-fw
|
|
.panel-body
|
|
form(name = "disksForm", editable-form = '', onbeforesave = 'saveDisks($data)')
|
|
table.table.table-hover
|
|
tr
|
|
th Name
|
|
th Description
|
|
th Size
|
|
th SR
|
|
th Status
|
|
th(ng-show="disksForm.$visible")
|
|
//- FIXME: ng-init seems to disrupt the implicit $watch.
|
|
tr(ng-repeat = 'VDI in VDIs track by VDI.UUID')
|
|
td
|
|
span(
|
|
editable-text="VDI.name_label"
|
|
e-name = '{{VDI.UUID}}/name_label'
|
|
)
|
|
| {{VDI.name_label}}
|
|
td
|
|
span(
|
|
editable-text="VDI.name_description"
|
|
e-name = '{{VDI.UUID}}/name_description'
|
|
)
|
|
| {{VDI.name_description}}
|
|
td
|
|
//- FIXME: should be editable, but the server needs first
|
|
//- to accept a human readable string.
|
|
| {{VDI.size | bytesToSize}}
|
|
td
|
|
span(
|
|
editable-select="(VDI.$SR | resolve).ref"
|
|
e-ng-options="SR.ref as (SR.name_label + ' (' + (SR.size - SR.usage | bytesToSize) + ' free)') for SR in writable_SRs"
|
|
e-name = '{{VDI.UUID}}/$SR'
|
|
)
|
|
//- Are SR editable? will trigger moving VDI to the new SR
|
|
a(xo-sref="SRs_view({id: (VDI.$SR | resolve).UUID})")
|
|
| {{(VDI.$SR | resolve).name_label}}
|
|
td(ng-if="isConnected(VDI)")
|
|
span.label.label-success Connected
|
|
span.pull-right.btn-group.quick-buttons
|
|
a(
|
|
tooltip="Disconnect this disk"
|
|
xo-click="disconnectVBD(VDI)"
|
|
)
|
|
i.fa.fa-unlink.fa-lg
|
|
td(ng-if="!isConnected(VDI)")
|
|
span.label.label-default Disconnected
|
|
span.pull-right.btn-group.quick-buttons
|
|
a(
|
|
tooltip="Plug this disk"
|
|
ng-if="VM.power_state == ('Running' || 'Paused')"
|
|
xo-click="connectVBD(VDI)"
|
|
)
|
|
i.fa.fa-plug.fa-lg
|
|
a(
|
|
tooltip="Forget this disk"
|
|
xo-click="deleteVBD(VDI)"
|
|
)
|
|
i.fa.fa-ban.fa-lg
|
|
a(
|
|
tooltip="Remove this disk"
|
|
xo-click="deleteDisk(VDI.UUID)"
|
|
)
|
|
i.fa.fa-trash-o.fa-lg
|
|
td(ng-show="disksForm.$visible")
|
|
.btn-group
|
|
button.btn.btn-default(
|
|
type="button"
|
|
ng-click="moveDisk($index, -1)"
|
|
ng-disabled="$first"
|
|
title="Move this disk up"
|
|
)
|
|
i.fa.fa-chevron-up
|
|
button.btn.btn-default(
|
|
type="button"
|
|
ng-click="moveDisk($index, 1)"
|
|
ng-disabled="$last"
|
|
title="Move this disk down"
|
|
)
|
|
i.fa.fa-chevron-down
|
|
//- TODO: Ability to create new VDIs.
|
|
.btn-form(ng-show="disksForm.$visible")
|
|
p.center
|
|
button.btn.btn-default(
|
|
type="reset"
|
|
ng-disabled="disksForm.$waiting"
|
|
ng-click="disksForm.$cancel()"
|
|
)
|
|
i.fa.fa-times
|
|
| Cancel
|
|
|
|
|
button.btn.btn-primary(
|
|
type="submit"
|
|
ng-disabled="disksForm.$waiting"
|
|
)
|
|
i.fa.fa-save
|
|
| Save
|
|
.grid
|
|
.col-md-4
|
|
iso-device(ng-if = 'VM && isoDeviceData', vm = 'VM', isos = 'isoDeviceData')
|
|
.col-md-8.text-right
|
|
div
|
|
button.btn(type="button", ng-class = '{"btn-success": adding, "btn-primary": !adding}', ng-disabled="disksForm.$waiting", ng-click="adding = !adding;creatingVdi = false")
|
|
i.fa.fa-plus(ng-if = '!adding')
|
|
i.fa.fa-minus(ng-if = 'adding')
|
|
| Attach Disk
|
|
|
|
|
button.btn(type="button", ng-class = '{"btn-success": creatingVdi, "btn-primary": !creatingVdi}', ng-disabled="disksForm.$waiting", ng-click="creatingVdi = !creatingVdi;adding = false")
|
|
i.fa.fa-plus(ng-if = '!creatingVdi')
|
|
i.fa.fa-minus(ng-if = 'creatingVdi')
|
|
| New Disk
|
|
br
|
|
form.form-inline#addDiskForm(ng-if = 'adding', name = 'addForm', ng-submit = 'addVdi(vdiToAdd.vdi, vdiReadOnly, vdiBootable)')
|
|
fieldset(ng-attr-disabled = '{{ addWaiting ? true : undefined }}')
|
|
.form-group
|
|
select#vdiToAdd.form-control(ng-model = 'vdiToAdd', ng-options = 'vdi.label group by vdi.sr for vdi in VDIOpts', required)
|
|
option(value = '', disabled) -- Choose disk --
|
|
|
|
|
.form-group(ng-if = 'vdiToAdd')
|
|
//- .form-group
|
|
label(for = 'vdiPosition') Position
|
|
select#vdiPosition.form-control(ng-model = '$parent.vdiPos', ng-options = 'vPos for vPos in vdiFreePos', required)
|
|
option(value = '', disabled) --
|
|
|
|
|
.checkbox
|
|
label
|
|
input(type='checkbox', ng-model = '$parent.$parent.vdiBootable')
|
|
| Bootable
|
|
.checkbox
|
|
label
|
|
input(ng-if = '!isFreeForWriting(vdiToAdd.vdi)', type='checkbox', ng-model = '$parent.$parent.vdiReadOnly', ng-checked = 'true', ng-disabled = 'true')
|
|
input(ng-if = 'isFreeForWriting(vdiToAdd.vdi)', type='checkbox', ng-model = '$parent.$parent.vdiReadOnly')
|
|
| Read-only
|
|
.form-group
|
|
button.btn.btn-primary(type = 'submit', ng-disabled="disksForm.$waiting")
|
|
| Add
|
|
span(ng-if = 'addWaiting')
|
|
|
|
|
i.fa.fa-spin.fa-circle-o-notch
|
|
br
|
|
form.form-inline#createDiskForm(ng-if = 'creatingVdi', name = 'createForm', ng-submit = 'createVdi(newDiskName, newDiskSize, newDiskSR, newDiskBootable, newDiskReadonly)')
|
|
fieldset(ng-attr-disabled = '{{ createWaiting ? true : undefined }}')
|
|
.form-group
|
|
//- label(for = 'newDiskName') Name
|
|
input#newDiskName.form-control(type = 'text', ng-model = 'newDiskName', placeholder = 'Disk Name', required)
|
|
|
|
|
.form-group
|
|
//- label(for = 'newDiskSize') Size
|
|
input#newDiskSize.form-control(type = 'text', ng-model = 'newDiskSize', required, placeholder = 'Size e.g 128MB, 8GB, 2TB...')
|
|
|
|
|
.form-group
|
|
//- label(for = 'newDiskSR') SR
|
|
select.form-control(ng-model = 'newDiskSR', required, ng-options="SR.ref as (SR.name_label + ' (' + (SR.size - SR.usage | bytesToSize) + ' free)') for SR in writable_SRs")
|
|
option(value = '', disabled) Choose your SR
|
|
|
|
|
br
|
|
br
|
|
.checkbox
|
|
label
|
|
input(type='checkbox', ng-model = 'newDiskBootable')
|
|
| Bootable
|
|
.checkbox
|
|
label
|
|
input(type='checkbox', ng-model = 'newDiskReadonly')
|
|
| Read-only
|
|
//- .form-group
|
|
label(for = 'diskPosition') Position
|
|
select#diskPosition.form-control(ng-model = 'newDiskPosition', ng-options = 'vPos for vPos in vdiFreePos', required)
|
|
option(value = '', disabled) --
|
|
|
|
|
br
|
|
br
|
|
.form-group
|
|
button.btn.btn-primary(type = 'submit', ng-disabled="disksForm.$waiting")
|
|
i.fa.fa-plus-square
|
|
| Create
|
|
span(ng-if = 'createWaiting')
|
|
|
|
|
i.fa.fa-spin.fa-circle-o-notch
|
|
br
|
|
|
|
//- TODO: add interface in this panel
|
|
.grid
|
|
.panel.panel-default
|
|
.panel-heading.panel-title
|
|
i.xo-icon-network(style="color: #e25440;")
|
|
| Interface
|
|
.panel-body
|
|
table.table.table-hover
|
|
th Device
|
|
th MAC
|
|
th MTU
|
|
th Network
|
|
th Link status
|
|
tr(ng-repeat="VIF in VM.VIFs | resolve | orderBy:natural('device') track by VIF.UUID")
|
|
td VIF \#{{VIF.device}}
|
|
td
|
|
| {{VIF.MAC}}
|
|
td
|
|
| {{VIF.MTU}}
|
|
td
|
|
| {{(VIF.$network | resolve).name_label}}
|
|
td(ng-if="VIF.attached")
|
|
span.label.label-success Connected
|
|
span.pull-right.btn-group.quick-buttons
|
|
a(tooltip="Disconnect this interface", ng-if="VM.power_state == ('Running' || 'Paused')", xo-click="disconnectVIF(VIF.UUID)")
|
|
i.fa.fa-unlink.fa-lg
|
|
td(ng-if="!VIF.attached")
|
|
span.label.label-default Disconnected
|
|
span.pull-right.btn-group.quick-buttons
|
|
a(tooltip="Connect this interface", xo-click="connectVIF(VIF.UUID)")
|
|
i.fa.fa-link.fa-lg
|
|
a(tooltip="Remove this interface", xo-click="deleteVIF(VIF.UUID)")
|
|
i.fa.fa-trash-o.fa-lg
|
|
.text-right
|
|
button.btn(type="button", ng-class = '{"btn-success": creatingVif, "btn-primary": !creatingVif}', ng-click="creatingVif = !creatingVif")
|
|
i.fa.fa-plus(ng-if = '!creatingVif')
|
|
i.fa.fa-minus(ng-if = 'creatingVif')
|
|
| Create Interface
|
|
br
|
|
form.form-inline.text-right#createInterfaceForm(ng-if = 'creatingVif', name = 'createInterfaceForm', ng-submit = 'createInterface(newInterfaceNetwork, newInterfaceMTU, autoMac, newInterfaceMAC)')
|
|
fieldset(ng-attr-disabled = '{{ createVifWaiting ? true : undefined }}')
|
|
.form-group
|
|
label(for = 'newVifNetwork') Network
|
|
select.form-control(ng-model = 'newInterfaceNetwork', ng-change = 'updateMTU(newInterfaceNetwork)', required, ng-options='network.name_label for network in networks')
|
|
option(value = '', disabled) --
|
|
|
|
|
.form-group
|
|
fieldset(ng-attr-disabled = '{{ autoMac ? true : undefined }}')
|
|
label.control-label(for = 'newInterfaceMAC') MAC address
|
|
input#newInterfaceMAC.form-control(ng-class = '{hidden: autoMac}', type = 'text', ng-model = 'newInterfaceMAC', ng-required = '!autoMac')
|
|
|
|
|
.checkbox
|
|
label
|
|
input(type='checkbox', ng-model = 'autoMac')
|
|
| Auto-generate
|
|
|
|
|
.form-group
|
|
label(for = 'newInterfaceMTU') MTU
|
|
input#newInterfaceMTU.form-control(type = 'text', ng-model = 'newInterfaceMTU', required)
|
|
|
|
|
.form-group
|
|
button.btn.btn-primary(type = 'submit')
|
|
i.fa.fa-plus-square
|
|
| Create
|
|
span(ng-if = 'createVifWaiting')
|
|
|
|
|
i.fa.fa-spin.fa-circle-o-notch
|
|
br
|
|
//- Snap panel
|
|
.grid
|
|
form(editable-form="", name="vmSnap", oncancel="cancel()").panel.panel-default
|
|
.panel-heading.panel-title
|
|
i.xo-icon-snapshot(style="color: #e25440;")
|
|
| Snapshots
|
|
span.quick-edit(tooltip="Edit snapshots", ng-click="vmSnap.$show()")
|
|
i.fa.fa-edit.fa-fw
|
|
.panel-body
|
|
p.center(ng-if="!VM.snapshots.length") No snapshots
|
|
table.table.table-hover(ng-if="VM.snapshots.length")
|
|
th Date
|
|
th Name
|
|
tr(ng-repeat="snapshot in VM.snapshots | resolve | orderBy:'-snapshot_time' track by snapshot.UUID")
|
|
td {{snapshot.snapshot_time*1e3 | date:"medium"}}
|
|
td
|
|
span(editable-text="snapshot.name_label", e-name="name_label", e-form="vmSnap", onbeforesave="saveSnapshot(snapshot.UUID, $data)")
|
|
| {{snapshot.name_label}}
|
|
span.pull-right.btn-group.quick-buttons
|
|
a(tooltip="Export this snapshot", type="button", xo-click="exportVM(snapshot.UUID)")
|
|
i.fa.fa-upload.fa-lg
|
|
a(tooltip="Revert VM to this snapshot", xo-click="revertSnapshot(snapshot.UUID)")
|
|
i.fa.fa-undo.fa-lg
|
|
a(tooltip="Remove this snapshot", xo-click="deleteSnapshot(snapshot.UUID)")
|
|
i.fa.fa-trash-o.fa-lg
|
|
.btn-form(ng-show="vmSnap.$visible")
|
|
p.center
|
|
button.btn.btn-default(type="button", ng-disabled="vmSnap.$waiting", ng-click="vmSnap.$cancel()")
|
|
i.fa.fa-times
|
|
| Cancel
|
|
|
|
|
button.btn.btn-primary(type="submit", ng-disabled="vmSnap.$waiting", ng-click="saveChanges()")
|
|
i.fa.fa-save
|
|
| Save
|
|
//- Logs panel
|
|
.panel.panel-default
|
|
.panel-heading.panel-title
|
|
i.fa.fa-comments(style="color: #e25440;")
|
|
| Logs
|
|
span.quick-edit(ng-if="VM.messages.length", tooltip="Remove all logs", xo-click="deleteAllLog()")
|
|
i.fa.fa-trash-o.fa-fw
|
|
.panel-body
|
|
p.center(ng-if="!VM.messages.length") No recent logs
|
|
table.table.table-hover(ng-if="VM.messages.length")
|
|
th Date
|
|
th Name
|
|
tr(ng-repeat="message in VM.messages | resolve | orderBy:'-time' track by message.UUID")
|
|
td {{message.time*1e3 | date:"medium"}}
|
|
td
|
|
| {{message.name}}
|
|
span.pull-right.btn-group.quick-buttons
|
|
a(xo-click="deleteLog(message.UUID)")
|
|
i.fa.fa-trash-o.fa-lg(tooltip="Remove this log entry")
|