<style include="settings-shared">
:host {
--cr-toggle-margin-inline-start: 16px;
--cr-toggle-width: 34px;
}
cr-toggle {
margin-inline-start: var(--cr-toggle-margin-inline-start);
width: var(--cr-toggle-width);
}
.column-title {
color: var(--cr-secondary-text-color);
}
.label-column {
align-items: center;
display: flex;
flex: 1;
flex-grow: 3;
}
.label-text {
flex-grow: 3;
word-break: break-all;
}
.no-ports-text {
padding-inline-start: 24px;
/* TODO(crbug.com/41391957): Update with proper number of pixels when
formal UI spec is received. */
}
.interface-ip {
padding-inline-start: 24px;
}
#addPort {
padding-top: 10px;
}
#errorIcon {
display: inline-block;
margin-inline-end: 8px;
}
#protocolText {
color: var(--cros-text-color-disabled);
margin-inline-start: 8px;
}
#portForwardingListContainerId {
border-top: var(--cr-separator-line);
}
#portForwardingDescription {
flex-grow: 3;
}
</style>
<div id="addPort" class="settings-box first">
<div
id="portForwardingDescription">
$i18n{crostiniPortForwardingDescription}
</div>
<cr-button on-click="onAddPortClick_"
aria-label="$i18n{crostiniPortForwardingAddPortButtonDescription}"
aria-describedby="i18n{portForwardingDescription}">
$i18n{crostiniPortForwardingAddPortButton}
</cr-button>
<template is="dom-if" if="[[allPorts_.length]]" restamp>
<cr-icon-button id="showRemoveAllPortsMenu"
class="icon-more-vert"
title="$i18n{moreActions}"
on-click="onShowRemoveAllPortsMenuClick_"
aria-label="$i18n{moreActions}">
</cr-icon-button>
</template>
</div>
<template is="dom-if" if="[[activeInterface_]]" restamp>
<div id="interface-ip" class="settings-box continuation">
[[activeInterface_]]: [[activeIpAddress_]]
</div>
</template>
<template is="dom-if" if="[[!allPorts_.length]]" restamp>
<div id="no-ports-text"
class="settings-box continuation">
$i18n{crostiniPortForwardingNoPorts}
</div>
</template>
<template is="dom-if" if="[[allPorts_.length]]" restamp>
<template is="dom-repeat" items="[[allContainers_]]"
as="containerInfo" index-as="cidx" mutable-data>
<template is="dom-if"
if="[[hasContainerPorts_(allPorts_, containerInfo.id)]]" restamp>
<h2 id="portForwardingListContainerId"
hidden="[[!showContainerId_(allPorts_, containerInfo.id)]]"
class="settings-box first">
[[containerLabel_(containerInfo.id)]]
</h2>
<div class="list-frame vertical-list" id="portForwardingListCard">
<div class="list-item">
<div id="portForwardingListPortNumber"
class="start column-title"
aria-hidden="true">
$i18n{crostiniPortForwardingListPortNumber}
</div>
<div id="portForwardingListPortLabel"
class="column-title label-column"
aria-hidden="true">
$i18n{crostiniPortForwardingListLabel}
</div>
</div>
<template is="dom-repeat" items="[[allPorts_]]"
filter="[[byContainerId_(containerInfo.id)]]" mutable-data>
<div class="list-item">
<div id="crostiniPort[[cidx]]-[[index]]"
class="start"
aria-hidden="true">
[[item.port_number]]
<span id="protocolText">
<template is="dom-if" if="[[!item.protocol_type]]" restamp>
$i18n{crostiniPortForwardingTCP}
</template>
<template is="dom-if" if="[[item.protocol_type]]" restamp>
$i18n{crostiniPortForwardingUDP}
</template>
</span>
</div>
<div class="label-column" aria-hidden="true">
<div id="crostiniPortLabel[[cidx]]-[[index]]"
class="label-text"
aria-hidden="true">
[[item.label]]
</div>
<cr-toggle
id="toggleActivationButton[[cidx]]-[[index]]"
checked="[[item.is_active]]"
data-port-number$="[[item.port_number]]"
data-protocol-type$="[[item.protocol_type]]"
data-container-id="[[item.container_id]]"
on-change="onPortActivationChange_"
aria-label="$i18n{crostiniPortForwardingToggleAriaLabel}"
aria-describedby$="crostiniPort[[cidx]]-[[index]]
crostiniPortLabel[[cidx]]-[[index]]"
disabled="[[!containerInfo.ipv4]]">
</cr-toggle>
<cr-icon-button
id="removeSinglePortButton[[cidx]]-[[index]]"
class="icon-clear"
title="$i18n{moreActions}"
on-click="onRemoveSinglePortClick_"
data-port-number$="[[item.port_number]]"
data-protocol-type$="[[item.protocol_type]]"
data-container-id="[[item.container_id]]"
aria-label=
"$i18n{crostiniPortForwardingShowMoreActionsAriaLabel}"
aria-describedby$="crostiniPort[[cidx]]-[[index]]
crostiniPortLabel[[cidx]]-[[index]]">
</cr-icon-button>
</div>
</div>
</template>
</div>
</template>
</template>
</template>
<template is="dom-if" if="[[showAddPortDialog_]]" restamp>
<settings-crostini-add-port-dialog
on-close="onAddPortDialogClose_"
all-ports="[[allPorts_]]"
all-containers="[[allContainers_]]">
</settings-crostini-add-port-dialog>
</template>
<cr-lazy-render id="removeAllPortsMenu">
<template>
<cr-action-menu class="complex" role-description="$i18n{menu}">
<button id="removeAllPortsButton"
class="dropdown-item"
role="menuitem"
on-click="onRemoveAllPortsClick_"
aria-label="$i18n{crostiniPortForwardingRemoveAllPortsAriaLabel}">
$i18n{crostiniPortForwardingRemoveAllPorts}
</button>
</cr-action-menu>
</template>
</cr-lazy-render>
<cr-toast id="errorToast" duration="3000">
<div class="error-message" id="errorMessage">
<iron-icon id="errorIcon" icon="cr:error-outline"></iron-icon>
$i18n{crostiniPortForwardingActivatePortError}
</div>
</cr-toast>