<link rel="stylesheet" type="text/css" href="modules/addons/dservermanager/assets/css/clientarea/advanced_v1/main.css?v={$dVersion}">
<link href='modules/addons/dservermanager/assets/css/vue-select.css?v={$dVersion}' rel='stylesheet'>
<link href='modules/addons/dservermanager/assets/css/vue-toastification.min.css?v={$dVersion}' rel='stylesheet'>
{$customCssTop}
<script src='modules/addons/dservermanager/assets/js/vue2.js?v={$dVersion}'></script>
{*<script src='modules/addons/dservermanager/assets/js/vue2-dev.js?v={$dVersion}'></script>*}
<script src='modules/addons/dservermanager/assets/js/axios.min.js?v={$dVersion}'></script>
<script src='modules/addons/dservermanager/assets/js/apexcharts.min.js?v={$dVersion}'></script>
<script src='modules/addons/dservermanager/assets/js/vue-apexcharts.min.js?v={$dVersion}'></script>
<script src='modules/addons/dservermanager/assets/js/vue-toastification.min.js?v={$dVersion}'></script>
<script src='modules/addons/dservermanager/assets/js/vue-select-2.js?v={$dVersion}'></script>
{$customJsTop}

<div class="row dservermanager-main-content" id="dServermanagerApp">
    <alert-modal ref="confirm"></alert-modal>
    <provisioning-status ref="provisioningStatus"></provisioning-status>
    <subnets-rdns-modal ref="subnetsRdnsModal" :xhr-url="xhrUrl"></subnets-rdns-modal>

    <div class="col-md-12">
        <div class="alert alert-danger" v-if="lastGetServerError !== ''" :style="$simpleStore.getLoader('initialLoader') ? 'opacity: 0.5' : 'opacity: 1.0'">
            %% lastGetServerError %%
            <br />
            <d-button class="btn btn-primary" style="margin-top: 5px;" @click.native="getAllData()" :loading="$simpleStore.getLoader('initialLoader')">
                <i v-if="!$simpleStore.getLoader('initialLoader')" :class="faIconRepo('fa-refresh')" style="margin-right: 3px;"></i>
                %% jsToLang('error.get_server_api_request_failed.button.try_again') %%
            </d-button>
        </div>
    </div>

    <div class="col-md-6">
        <div class="panel panel-default card">
            <div class="panel-heading card-header">
                <h3 class="panel-title card-title m-0">%% jsToLang('card.overview.server_status.prefix') %%
                    <span :class="getServerPowerStatus.class" v-if="!$simpleStore.getLoader('manageServerPower') && serverData.powerprovider && serverData.powerprovider.type !== ''">
                        %% getServerPowerStatus.text %%
                    </span>
                    <span class="text-success" v-if="serverData.id && (!serverData.powerprovider || serverData.powerprovider.type === '')">
                        %% jsToLang('card.overview.server_status.online') %%
                    </span>
                    <span class="text-warning" v-if="!serverData.id">
                        %% jsToLang('card.overview.server_status.unknown') %%
                    </span>
                    <span v-if="$simpleStore.getLoader('manageServerPower')">
                        <i style="margin-left: 5px;" :class="faIconRepo('fa-refresh-spin')"></i>
                    </span>
                </h3>
            </div>

            <div class="panel-body card-body text-center">
                <div>
                    <h4 class="ds-productname" style="margin:0;">{$product}</h4>

                    <div class="col-12">
                        <img v-if="osLogoPath" style="height: 90px; margin-top: 10px;" :src="osLogoPath">
                    </div>

                    <div class="col-12 ds-productcard-osname" style="margin-top: 5px;">
                        <small v-if="dCan('servers.apiOutput.param.os')">
                            <editable-field max-length="60" permission-to-edit="servers.update.param.os" :loading="$simpleStore.getLoader('updateServer_os')" @change="updateServer($event, 'os')" :text="serverData.os ? serverData.os : jsToLang('card.overview.os.unknown')"></editable-field>
                        </small>
                    </div>
                </div>
            </div>

            <div class="panel-footer card-footer text-center" v-if="serverData.cachedPowerstatus && dCan('servers.power.param.params') && serverData.powerprovider && serverData.powerprovider.type !== ''" :title="powerActionsBlocked.reason ? powerActionsBlocked.reason : ''">
                <d-button :disabled="$simpleStore.getLoader('manageServerPower') || powerActionsBlocked.blocked === 1" :loading="$simpleStore.getLoader('setPowerOff')" v-if="canExecutePowerAction('setPowerOff')" @click.native="manageServerPower('setPowerOff')" class="btn btn-danger">
                    <i v-if="!$simpleStore.getLoader('setPowerOff')" :class="faIconRepo('fa-power-off')" style="margin-right: 3px;"></i> %% jsToLang('power.button.power_off') %%
                </d-button>
                <d-button :disabled="$simpleStore.getLoader('manageServerPower') || powerActionsBlocked.blocked === 1" :loading="$simpleStore.getLoader('setPowerReset')" v-if="canExecutePowerAction('setPowerReset')" @click.native="manageServerPower('setPowerReset')" class="btn btn-warning">
                    <i v-if="!$simpleStore.getLoader('setPowerReset')" :class="faIconRepo('fa-plug')" style="margin-right: 3px;"></i> %% jsToLang('power.button.power_reset') %%
                </d-button>
                <d-button :disabled="$simpleStore.getLoader('manageServerPower') || powerActionsBlocked.blocked === 1" :loading="$simpleStore.getLoader('setPowerOn')" v-if="canExecutePowerAction('setPowerOn')" @click.native="manageServerPower('setPowerOn')" class="btn btn-success">
                    <i v-if="!$simpleStore.getLoader('setPowerOn')" :class="faIconRepo('fa-play')" style="margin-right: 3px;"></i> %% jsToLang('power.button.power_on') %%
                </d-button>
                <d-button :disabled="$simpleStore.getLoader('manageServerPower') || powerActionsBlocked.blocked === 1" :loading="$simpleStore.getLoader('setPowerCycle')" v-if="canExecutePowerAction('setPowerCycle')" @click.native="manageServerPower('setPowerCycle')" class="btn btn-primary">
                    <i v-if="!$simpleStore.getLoader('setPowerCycle')" :class="faIconRepo('fa-refresh')" style="margin-right: 3px;"></i> %% jsToLang('power.button.power_reboot') %%
                </d-button>
            </div>
        </div>
    </div>

    <div class="col-md-6" style="padding-left: 0px; padding-right: 0px;">
        <div class="col-md-12">
            <div class="panel card panel-default" style="margin-bottom: 0px;">
                <div class="panel-heading card-header">
                    <h3 class="panel-title card-title m-0">%% jsToLang('card.billing_details.title') %%</h3>
                </div>
                <div class="panel-body card-body">
                    <div class="row">
                        <div class="col-md-12">
                            <div class="row" id="productStatus" {if $bwpercent|substr:0:-1 < 75} style="margin-bottom: 7px;" {/if}>
                                <div class="col-xs-6 col-6 col-xl-5">
                                    {$LANG.clientareastatus}
                                </div>
                                <div class="col-xs-6 col-6 col-xl-7 text-right">
                                    {$status}
                                </div>
                            </div>
                            {if $firstpaymentamount neq $recurringamount}
                                <div class="row" id="firstPaymentAmount" {if $bwpercent|substr:0:-1 < 75} style="margin-bottom: 7px;" {/if}>
                                    <div class="col-xs-6 col-6">
                                        {$LANG.firstpaymentamount}
                                    </div>
                                    <div class="col-xs-6 col-6 text-right">
                                        {$firstpaymentamount}
                                    </div>
                                </div>
                            {/if}
                            {if $billingcycle != $LANG.orderpaymenttermonetime && $billingcycle != $LANG.orderfree}
                                <div class="row" id="recurringAmount" {if $bwpercent|substr:0:-1 < 75} style="margin-bottom: 7px;" {/if}>
                                    <div class="col-xs-6 col-6">
                                        {$LANG.recurringamount}
                                    </div>
                                    <div class="col-xs-6 col-6 text-right">
                                        {$recurringamount}
                                    </div>
                                </div>
                            {/if}
                            <div class="row" id="billingCycle" {if $bwpercent|substr:0:-1 < 75} style="margin-bottom: 7px;" {/if}>
                                <div class="col-xs-6 col-6">
                                    {$LANG.orderbillingcycle}
                                </div>
                                <div class="col-xs-6 col-6 text-right">
                                    {$billingcycle}
                                </div>
                            </div>
                            <div class="row" id="paymentMethod" {if $bwpercent|substr:0:-1 < 75} style="margin-bottom: 7px;" {/if}>
                                <div class="col-xs-6 col-6">
                                    {$LANG.orderpaymentmethod}
                                </div>
                                <div class="col-xs-6 col-6 text-right">
                                    {$paymentmethod}
                                </div>
                            </div>

                            <div class="row" id="registrationDate" {if $bwpercent|substr:0:-1 < 75} style="margin-bottom: 7px;" {/if}>
                                <div class="col-xs-6 col-6 col-xl-5">
                                    {$LANG.clientareahostingregdate}
                                </div>
                                <div class="col-xs-6 col-6 col-xl-7 text-right">
                                    {$regdate}
                                </div>
                            </div>
                            <div class="row" id="nextDueDate">
                                <div class="col-xs-6 col-6 col-xl-5">
                                    {$LANG.clientareahostingnextduedate}
                                </div>
                                <div class="col-xs-6 col-6 col-xl-7 text-right">
                                    {$nextduedate}
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        {if $bwpercent|substr:0:-1 > 75}
            <div class="col-md-12" style="margin-top: 15px; margin-bottom: 0px;">
                <div class="alert alert-danger">
                    <div class="row">
                        <div class="col-md-6">
                            <b>%% jsToLang('card.billing_details.bandwidth_warning.title') %%</b>
                        </div>
                        {if $packagesupgrade}
                            <div class="col-md-6">
                                <a href="upgrade.php?type=package&id={$serviceid}" class="btn btn-xs btn-danger float-md-right pull-right">
                                    <i :class="faIconRepo('fa-arrow-circle-up')"></i>
                                    {$LANG.usageUpgradeNow}
                                </a>
                            </div>
                        {/if}
                    </div>

                    {if $bwpercent|substr:0:-1 > 75}
                        <div class="text-danger limit-near">
                            {if $bwpercent|substr:0:-1 > 100}  %% jsToLang('card.billing_details.bandwidth_warning.msg.bw_over_limit') %% {else}  %% jsToLang('card.billing_details.bandwidth_warning.msg.bw_near_limit') %% {/if}
                        </div>
                    {/if}
                </div>
            </div>
        {/if}
    </div>

    <div class="col-md-12" style="margin-top: 15px;">
        <div class="panel card panel-default">
            <div class="panel-body card-body">
                <div class="row">
                    <div class="col-md-12">
                        <div class="btn-group" role="group" aria-label="Server Actions">
                            <button type="button" class="btn" :class="activeInformationCard === 'serverDetails' ? 'btn-primary' : 'btn-default'" @click="activeInformationCard = 'serverDetails'">
                                %% jsToLang('card.server_details.button.server_details') %%
                            </button>
                            {if $metricStats}
                                <button type="button" class="btn" :class="activeInformationCard === 'billingMetrics' ? 'btn-primary' : 'btn-default'" @click="activeInformationCard = 'billingMetrics'">
                                    %% jsToLang('card.server_details.button.billing_metrics') %%
                                </button>
                            {/if}
                            {if $customfields || $configurableoptions}
                                <button type="button" class="btn" :class="activeInformationCard === 'additionalInformation' ? 'btn-primary' : 'btn-default'"
                                        @click="activeInformationCard = 'additionalInformation'">
                                    %% jsToLang('card.server_details.button.additional_information') %%
                                </button>
                            {/if}
                            {if $availableAddonProducts}
                                <button type="button" class="btn" :class="activeInformationCard === 'availableAddonProducts' ? 'btn-primary' : 'btn-default'"
                                        @click="activeInformationCard = 'availableAddonProducts'">
                                    %% jsToLang('card.server_details.button.purchase_addon') %%
                                </button>
                            {/if}
                        </div>
                    </div>

                    {if $metricStats}
                        <div class="col-md-12" style="margin-top: 20px;" v-if="activeInformationCard === 'billingMetrics'">
                            {include file="$template/clientareaproductusagebilling.tpl"}
                        </div>
                    {/if}

                    <div class="col-md-12" style="margin-top: 20px;" v-if="activeInformationCard === 'availableAddonProducts'">
                        <div class="panel panel-default card">
                            <div class="panel-body card-body" style="padding-top: 10px;">
                                <div class="row">
                                    <div class="col-md-12">
                                        %% jsToLang('card.server_details.tab.purchase_addon.description') %%
                                    </div>

                                    <div class="col-md-12" style="margin-top: 10px;">
                                        <form method="post" action="{$WEB_ROOT}/cart.php?a=add">
                                            <input type="hidden" name="serviceid" value="{$serviceid}"/>

                                            <div class="input-group">
                                                <select name="aid" class="form-control">
                                                    {foreach $availableAddonProducts as $addonId => $addonName}
                                                        <option value="{$addonId}">{$addonName}</option>
                                                    {/foreach}
                                                </select>
                                                <div class="input-group-append input-group-btn">
                                                    <button type="submit" class="btn btn-primary">
                                                        <i :class="faIconRepo('fa-shopping-cart')"></i>
                                                        {$LANG.purchaseActivate}
                                                    </button>
                                                </div>
                                            </div>
                                        </form>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>

                    <div class="col-md-12" style="margin-top: 20px;" v-if="activeInformationCard === 'additionalInformation'">
                        <div class="row">
                            {if $configurableoptions}
                                <div class="col-md-12">
                                    <h5>{$LANG.orderconfigpackage}</h5>

                                    <table class="table table-bordered" style="margin-bottom: 10px; margin-top: 10px;">
                                    {foreach from=$configurableoptions item=configoption}
                                        <tr>
                                            <td width="30%">
                                                {$configoption.optionname}
                                            </td>
                                            <td>
                                                {if $configoption.optiontype eq 3}{if $configoption.selectedqty}{$LANG.yes}{else}{$LANG.no}{/if}{elseif $configoption.optiontype eq 4}{$configoption.selectedqty} x {$configoption.selectedoption}{else}{$configoption.selectedoption}{/if}
                                            </td>
                                        </tr>
                                    {/foreach}
                                    </table>
                                </div>
                            {/if}

                            {if $customfields}
                                <div class="col-md-12" {if $configurableoptions} style="margin-top: 20px;" {/if}>
                                    <h5>{$LANG.additionalInfo}</h5>

                                    <table class="table table-bordered" style="margin-top: 10px;">
                                    {foreach from=$customfields item=field}
                                        <tr>
                                            <td width="30%">
                                                {$field.name}
                                            </td>
                                            <td>
                                                {if empty($field.value)}
                                                    {$LANG.blankCustomField}
                                                {else}
                                                    {$field.value}
                                                {/if}
                                            </td>
                                        </tr>
                                    {/foreach}
                                    </table>
                                </div>
                            {/if}
                        </div>
                    </div>

                    <div class="col-md-12" style="margin-top: 20px;" v-if="activeInformationCard === 'serverDetails'">
                        <table class="table table-bordered ds-table-td-vertical" style="margin-bottom: 10px;">
                            <tr style="display: revert !important;" v-if="dCan('servers.apiOutput.param.hostname')">
                                <td width="30%">
                                    %% jsToLang('card.server_details.hostname') %%
                                </td>
                                <td>
                                    <editable-field max-length="200" permission-to-edit="servers.update.param.hostname" :loading="$simpleStore.getLoader('updateServer_hostname')" @change="updateServer($event, 'hostname')" :text="serverData.hostname ? serverData.hostname : 'None'"></editable-field>
                                </td>
                            </tr>
                            <tr style="display: revert !important;" v-if="dCan('servers.apiOutput.param.description')">
                                <td width="30%">
                                    %% jsToLang('card.server_details.server_description') %%
                                </td>
                                <td>
                                    <editable-field max-length="200" permission-to-edit="servers.update.param.description" :loading="$simpleStore.getLoader('updateServer_description')" :none-class="serverData.description ? false : 'ds-italic'" @change="updateServer($event, 'description')" :text="serverData.description ? serverData.description : 'None'"></editable-field>
                                </td>
                            </tr>
                            <tr style="display: revert !important;" v-if="dCan('servers.apiOutput.param.tags')">
                                <td width="30%">
                                    %% jsToLang('card.server_details.server_tags') %%
                                </td>
                                <td>
                                    <template v-if="serverData.tags && serverData.tags.length">
                                        <span :style="$simpleStore.getLoader('updateServer_tags') ? 'opacity: 0.5' : 'opacity: 1.0'" style="margin-right: 5px; font-weight: 500;" class="label label-default" v-for="(v, k) in serverData.tags"
                                              :key="'serverTag_' + k">%% v %% <i v-if="dCan('servers.update.param.tags')" @click="updateServer (serverData.tags.filter(e => e !== v), 'tags')" style="margin-left: 2px;" class="ds-mouse-pointer" :class="faIconRepo('fa-times')"></i>
                                        </span>
                                    </template>

                                    <editable-field class="btn btn-primary btn-xs" v-if="dCan('servers.update.param.tags')" :style="$simpleStore.getLoader('updateServer_tags') ? 'opacity: 0.5' : 'opacity: 1.0'"
                                                    @change="serverData.tags.push($event); updateServer (serverData.tags, 'tags')" :text="jsToLang('card.server_details.button.add_new_tag')"></editable-field>
                                </td>
                            </tr>
                            <tr style="display: revert !important;" v-if="serverData.lastBwrate?.in">
                                <td width="30%">
                                    %% jsToLang('card.server_details.last_bw_in') %%  <i style="margin-left: 3px;" :class="faIconRepo('fa-info-circle')" data-toggle="dynamic-tooltip" :title="jsToLang('card.server_details.tooltip.last_bw')"></i>
                                </td>
                                <td>
                                    %% serverData.lastBwrate.in %% Mbit/s
                                </td>
                            </tr>
                            <tr style="display: revert !important;" v-if="serverData.lastBwrate?.out">
                                <td width="30%">
                                    %% jsToLang('card.server_details.last_bw_out') %% <i style="margin-left: 3px;" :class="faIconRepo('fa-info-circle')" data-toggle="dynamic-tooltip" :title="jsToLang('card.server_details.tooltip.last_bw')"></i>
                                </td>
                                <td>
                                    %%serverData.lastBwrate.out%% Mbit/s
                                </td>
                            </tr>

                            <tr style="display: revert !important;" v-if="billingStoredBandwidthStats.usageInMb">
                                <td width="30%">
                                    %% jsToLang('card.server_details.bandwidth_usage') %%

                                    {if $bwpercent|substr:0:-1 > 75}
                                        <i style="margin-left: 3px;" :class="faIconRepo('fa-exclamation-triangle')" class="text-danger" data-toggle="dynamic-tooltip" :title="{if $bwpercent|substr:0:-1 > 100} jsToLang('card.server_details.tooltip.bandwidth_warning.bw_over_limit') {else} jsToLang('card.server_details.tooltip.bandwidth_warning.bw_near_limit') {/if}"></i>
                                    {/if}
                                </td>
                                <td>
                                    %% formatByteToNice(billingStoredBandwidthStats.usageInMb, '', 1) %% / %% formatByteToNice(billingStoredBandwidthStats.limitInMb, '', 1, null, "{$LANG.clientareaunlimited}", null, true) %%
                                    <small style="margin-left: 10px;">{$LANG.usageLastUpdated} %% billingStoredBandwidthStats.lastUpdated %%</small>
                                </td>
                            </tr>
                        </table>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <div class="col-md-12" style="margin-top: 15px;" v-show="isActionCardVisible">
        <div class="panel card panel-default">
            <div class="panel-body card-body ds-overflow-visible">
                <div class="row">
                    <div class="col-md-12">
                        <div class="btn-group" role="group" aria-label="Server Actions">
                            <template v-if="dCan('servers.provisioning.getProfiles') && dCan('servers.provisioning.startReinstallation') && $simpleStore.getProvisioningPossible() === 1">
                                <button @click="openedActionCard = 'reinstallation'; selectedProvisioningType = 'reinstallation'" type="button" class="btn" :class="openedActionCard === 'reinstallation' ? 'btn-primary' : 'btn-default'">%% jsToLang('reinstallation.nav_button.reinstallation') %%</button>
                                <button @click="openedActionCard = 'rescue'; selectedProvisioningType = 'rescue'" type="button" class="btn" :class="openedActionCard === 'rescue' ? 'btn-primary' : 'btn-default'">%% jsToLang('reinstallation.nav_button.rescue') %%</button>
                            </template>

                            <button v-if="isBackupsAvailable" @click="openedActionCard = 'backups'" type="button" class="btn" :class="openedActionCard === 'backups' ? 'btn-primary' : 'btn-default'">%% jsToLang('backups.nav_button.backups') %%</button>
                            <button v-if="isSnapshotsAvailable" @click="openedActionCard = 'snapshots'" type="button" class="btn" :class="openedActionCard === 'snapshots' ? 'btn-primary' : 'btn-default'">%% jsToLang('snapshots.nav_button.snapshots') %%</button>
                        </div>

                        <span :class="areServerActionsAvailable ? 'pull-md-right float-md-right' : ''">
                            <d-button :disabled="$simpleStore.getLoader('manageServerPower') || powerActionsBlocked.blocked === 1" :loading="$simpleStore.getLoader('bmcReset')" @click.native="manageServerPower('setBmcReset')" v-if="canExecutePowerAction('setBmcReset') && dCan('servers.execute.bmc.reset')" type="button" class="btn btn-default">%% jsToLang('power.button.bmc_reset') %%</d-button>
                            <console-button :server-data="serverData" :xhr-url="xhrUrl"></console-button>
                            <a target="_blank" :href="xhrUrl + 'doSsoLogin'" type="button" class="btn btn-default" v-if="isSsoDisabled !== 'yes'">
                                <i :class="faIconRepo('fa-sign-in')" style="margin-right: 3px;"></i> %% jsToLang('card.actions.button.login_to_panel') %%
                            </a>
                        </span>
                    </div>

                    <div class="col-md-12" style="margin-top: 15px;" v-if="dCan('servers.provisioning.getProfiles') && dCan('servers.provisioning.startReinstallation')" v-show="$simpleStore.getProvisioningPossible() === 1 && (openedActionCard === 'reinstallation' || openedActionCard === 'rescue')">
                        <reinstallation :get-server="getServer" :mode="selectedProvisioningType" :xhr-url="xhrUrl" :server-data="serverData"></reinstallation>
                    </div>

                    <div class="col-md-12" style="margin-top: 15px;" v-if="dCan('servers.snapshots.index')" v-show="openedActionCard === 'snapshots'">
                        <server-snapshots @refresh-power="getServerPowerFromBackend()" ref="snapshots" :server-data="serverData" :xhr-url="xhrUrl"></server-snapshots>
                    </div>

                    <div class="col-md-12" style="margin-top: 15px;" v-if="dCan('servers.backups.index')" v-show="openedActionCard === 'backups'">
                        <server-backups @refresh-power="getServerPowerFromBackend()" ref="backups" :server-data="serverData" :xhr-url="xhrUrl"></server-backups>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <div class="col-md-12" style="margin-top: 15px;" v-if="dCan('servers.ipassignments.index') && ipAssignments.length">
        <div class="panel panel-default card">
            <div class="panel-body card-body" style="padding-top: 15px; padding-bottom: 0px;">
                <b style="font-size: 20px; font-weight: 500;">%% jsToLang('card.ipassignments.title') %%</b>

                <div class="row">
                    <div class="col-md-12" style="padding-left: 5px; padding-right: 5px; padding-top: 10px;">
                        <table class="table ds-table-no-top-border ds-table-td-vertical">
                            <thead>
                            <tr>
                                <th>%% jsToLang('card.ipassignments.table.head.ip') %%</th>
                                <th v-if="dCan('servers.ipassignments.apiOutput.param.subnetinformation')">%% jsToLang('card.ipassignments.table.head.netmask') %%</th>
                                <th v-if="dCan('servers.ipassignments.apiOutput.param.subnetinformation')">%% jsToLang('card.ipassignments.table.head.gw') %%</th>
                                <th v-if="dCan('servers.ipassignments.ip.rdns')">%% jsToLang('card.ipassignments.table.head.rdns') %%</th>
                                <th v-if="dCan('servers.ipassignments.apiOutput.param.description')">%% jsToLang('card.ipassignments.table.head.description') %%</th>
                            </tr>
                            </thead>
                            <tbody>
                            <tr v-for="(v, k) in ipAssignments" :key="'ipassignments_' + k">
                                <td>%% v.ip %%</td>
                                <td v-if="dCan('servers.ipassignments.apiOutput.param.subnetinformation')">%% v.subnetinformation.netmask %%</td>
                                <td v-if="dCan('servers.ipassignments.apiOutput.param.subnetinformation')">%% v.subnetinformation.gw %%</td>
                                <td width="20%" v-if="dCan('servers.ipassignments.ip.rdns')">
                                    <template v-if="v?.ipAttributes?.isSubnet === 0">
                                        <template v-if="rdnsEntries?.[v.ip]?.loaded === 1">
                                            <editable-field max-length="37" permission-to-edit="servers.ipassignments.update.param.ptrRecord" :loading="$simpleStore.getLoader('updateIp_ptrRecord_' + v.ip)" :none-class="rdnsEntries[v.ip].rdnsEntry ? false : 'ds-italic'" @change="updateIp($event, 'ptrRecord', v.ip)" :text="rdnsEntries[v.ip].rdnsEntry ? rdnsEntries[v.ip].rdnsEntry : jsToLang('card.ipassignments.table.data.no_rdns_record')"></editable-field>
                                        </template>

                                        <template v-if="rdnsEntries?.[v.ip]?.loaded === 0">
                                            <i :class="faIconRepo('fa-refresh-spin')"></i>
                                        </template>

                                        <template v-if="!rdnsEntries?.[v.ip]">
                                            <i>%% jsToLang('card.ipassignments.table.data.no_rdns_support') %%</i>
                                        </template>
                                    </template>

                                    <template v-if="v?.ipAttributes?.isSubnet === 1 && v?.ipAttributes?.isIpv6 === 1">
                                        <template v-if="v?.subnetinformation.rdnsAvailable === 1">
                                            <span @click.prevent="openSubnetRdnsModal(v.ip)" class="ds-mouse-pointer ds-editable-text">%% jsToLang('card.ipassignments.table.data.button.manage_rdns') %%</span>
                                        </template>
                                        <template v-else>
                                            <i>%% jsToLang('card.ipassignments.table.data.no_rdns_support') %%</i>
                                        </template>
                                    </template>
                                </td>
                                <td width="20%" v-if="dCan('servers.ipassignments.apiOutput.param.description')">
                                    <editable-field max-length="37" permission-to-edit="servers.ipassignments.update.param.description" :loading="$simpleStore.getLoader('updateIp_description_' + v.ip)" :none-class="v.description ? false : 'ds-italic'" @change="updateIp($event, 'description', v.ip)" :text="v.description ? v.description : jsToLang('card.ipassignments.table.data.no_description')"></editable-field>
                                </td>
                            </tr>
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <div class="col-md-12">
        <server-graphs style="margin-top: 15px;" :xhr-url="xhrUrl" v-if="initialLoadCompleted" :server-data="serverData" :whmcs-pid="whmcsPid" :network-graph-show-summary-by-default="clientareaSettings.clientarea_precheck_networkgraph_show_summary" :network-graph-showp95th-line-by-default="clientareaSettings.clientarea_networkgraphs_show_total_p95th_line"></server-graphs>
    </div>
</div>


<script>
    var dServermanagerLanguage = {$dLanguage};
    var faIconsVersion = "{$faIconsVersion}";
</script>

<script type="module">
    import Reinstallation from "./modules/addons/dservermanager/assets/components/Reinstallation.js?v={$dVersion}";
    import AlertModal from "./modules/addons/dservermanager/assets/components/AlertModal.js?v={$dVersion}";
    import ProvisioningStatus from "./modules/addons/dservermanager/assets/components/ProvisioningStatus.js?v={$dVersion}";
    import ShowPasswordAfterInstall from "./modules/addons/dservermanager/assets/components/ShowPasswordAfterInstall.js?v={$dVersion}";
    import Button from "./modules/addons/dservermanager/assets/components/Button.js?v={$dVersion}";
    import EditableField from "./modules/addons/dservermanager/assets/components/EditableField.js?v={$dVersion}";
    import GlobalMixin from "./modules/addons/dservermanager/assets/components/mixin/GlobalMixin.js?v={$dVersion}";
    import SubnetsRdnsModal from "./modules/addons/dservermanager/assets/components/SubnetsRdnsModal.js?v={$dVersion}";
    import SshKeyModal from "./modules/addons/dservermanager/assets/components/SshKeyModal.js?v={$dVersion}";
    import Skeleton from "./modules/addons/dservermanager/assets/components/Skeleton.js?v={$dVersion}";
    import ConsoleButton from "./modules/addons/dservermanager/assets/components/ConsoleButton.js?v={$dVersion}";
    import ServerGraphs from "./modules/addons/dservermanager/assets/components/ServerGraphs.js?v={$dVersion}";
    import ServerSnapshots from "./modules/addons/dservermanager/assets/components/ServerSnapshots.js?v={$dVersion}";
    import ServerBackups from "./modules/addons/dservermanager/assets/components/ServerBackups.js?v={$dVersion}";
    import Semaphore from "./modules/addons/dservermanager/assets/components/helper/Semaphore.js?v={$dVersion}";

    {literal}
    if (!dServermanager?.$options.components['apexchart']) {
        Vue.use(VueApexCharts);
        Vue.use(VueToastification.default, {
            position: 'bottom-center',
            timeout: 3000,
            maxToasts: 4,
        });

        Vue.component('alert-modal', AlertModal);
        Vue.component('provisioning-status', ProvisioningStatus);
        Vue.component('show-password-after-install', ShowPasswordAfterInstall);
        Vue.component('d-button', Button);
        Vue.component('editable-field', EditableField);
        Vue.component('ssh-key-modal', SshKeyModal);
        Vue.component('v-select', VueSelect.VueSelect);
        Vue.component('subnets-rdns-modal', SubnetsRdnsModal);
        Vue.component('skeleton', Skeleton);
        Vue.component('console-button', ConsoleButton);
        Vue.component('server-graphs', ServerGraphs);
        Vue.component('server-snapshots', ServerSnapshots);
        Vue.component('server-backups', ServerBackups);
        Vue.component('reinstallation', Reinstallation);

        Vue.mixin(GlobalMixin);
    }

    const simpleStore = Vue.observable({
        loaderStore: {},
        userPermissions: [],
        userAccountData: {},
        provisioningPossible: 0,
        systemTheme: '',
    });

    const storeFuncs = {
        addLoader (obj) {
            Vue.set(simpleStore.loaderStore, obj, 1);
        },

        delLoader (obj) {
            Vue.delete(simpleStore.loaderStore, obj);
        },

        getLoader(obj) {
            return simpleStore.loaderStore[obj];
        },

        setUserPermissions (data) {
            simpleStore.userPermissions = data;
        },

        getUserPermissions () {
            return simpleStore.userPermissions;
        },

        setProvisioningPossible (data) {
            simpleStore.provisioningPossible = data;
        },

        getProvisioningPossible () {
            return simpleStore.provisioningPossible;
        },

        setUserAccountData (data) {
            simpleStore.userAccountData = data;
        },

        getUserAccountData (data) {
            return simpleStore.userAccountData;
        },

        setServiceInformation (data) {
            simpleStore.serviceInformation = data;
        },

        getServiceInformation (data) {
            return simpleStore.serviceInformation;
        },

        setSystemTheme (data) {
            simpleStore.systemTheme = data;
        },

        getSystemTheme (data) {
            return simpleStore.systemTheme;
        },
    }

    Vue.prototype.$simpleStore = storeFuncs;

    var dServermanager = new Vue({
        delimiters: [
            '%%',
            '%%'
        ],
        el: '#dServermanagerApp',
        components: {
            Reinstallation,
            'apexchart': window.VueApexCharts,
        },
        data() {
            return {
                lastGetServerError: '',
                serverData: {},
                ipAssignments: [],
                activeInformationCard: 'serverDetails',
                clientareaSettings: {/literal}{$clientareaSettings}{literal},
                rdnsEntries: {},
                rdnsSemaphore: null,
                serverRequestPending: false,
                whmcsPid: {/literal}{$id}{literal},
                billingStoredBandwidthStats: {
                    usageInMb: {/literal}{$bwusage}{literal},
                    limitInMb: {/literal}"{$bwlimit}"{literal},
                    lastUpdated: {/literal}"{$lastupdate}"{literal},
                },
                isSsoDisabled: {/literal}"{$disableSso}"{literal},
                xhrUrl: 'modules/addons/dservermanager/request.php?xhr=1&pid={/literal}{$id}{literal}&method=',
                selectedProvisioningType: '',
                osLogoPath: '',
                serviceInformation: {/literal}{$serviceInformation}{literal},
                systemTheme: '{/literal}{$template}{literal}',
                initialLoadCompleted: false,
                openedActionCard: 'reinstallation',
                featureAvailability: {
                    backups: false,
                    snapshots: false,
                }
            }
        },

        mounted() {
            this.getAllData();
            this.getServerByInterval();

            this.$simpleStore.setServiceInformation(this.serviceInformation);
            this.$simpleStore.setSystemTheme(this.systemTheme);

            let provisioningPreselection = this.clientareaSettings?.clientarea_os_installation_preselection || 'reinstallation';
            this.openedActionCard = provisioningPreselection;

            if (provisioningPreselection !== 'none') {
                this.selectedProvisioningType = provisioningPreselection;
            }
        },

        watch: {
            'serverData.os': function (os) {
                this.getOsLogo(os).then(e => {
                    this.osLogoPath = e;
                });
            },

            'openedActionCard': {
                handler(current, old) {
                    if (current === 'snapshots') {
                        this.refsProxy(this.$refs.snapshots, 'loadIfVisible');
                    }

                    if (current === 'backups') {
                        this.refsProxy(this.$refs.backups, 'loadIfVisible');
                    }
                }
            }
        },

        computed: {
            isBackupsAvailable() {
                return this.featureAvailability.backups;
            },

            isSnapshotsAvailable() {
                return this.featureAvailability.snapshots;
            },

            isActionCardVisible: function () {
                if (this.$simpleStore.getProvisioningPossible() === 1 || (this.serverData.consoleprovider && this.dCan('servers.console.start')) || (this.canExecutePowerAction('setBmcReset') && this.dCan('servers.execute.bmc.reset')) || this.isSsoDisabled !== 'yes') {
                    return true;
                }

                if (this.isBackupsAvailable || this.isSnapshotsAvailable) {
                    return true;
                }

                return false;
            },

            areServerActionsAvailable() {
                if (this.$simpleStore.getProvisioningPossible() === 1 || this.isBackupsAvailable || this.isSnapshotsAvailable) {
                    return true;
                }

                return false;
            },

            powerActionsBlocked: function () {
                let mapper = {
                    reinstallationRunning: {
                        type: 'reinstall',
                    },
                    diskwipeRunning: {
                        type: 'diskwipe',
                    },
                    rescueBootRunning: {
                        type: 'rescue',
                    },
                    hardwarecollectRunning: {
                        type: 'hwcollect',
                    }
                }

                for (const [field, installMeta] of Object.entries(mapper)) {
                    if (this.serverData[field] === 1) {
                        return {
                            blocked: 1,
                            reason: this.jsToLang('power.button.tooltip.blocked_because_provisioning_running')
                        };
                    }
                }

                return {
                    blocked: 0,
                };
            },

            getServerPowerStatus: function () {
                let mapper = {
                    probablyOnline: {
                        text: this.jsToLang('card.overview.server_status.online'),
                        class: 'text-success',
                    },
                    online: {
                        text: this.jsToLang('card.overview.server_status.online'),
                        class: 'text-success',
                    },
                    offline: {
                        text: this.jsToLang('card.overview.server_status.offline'),
                        class: 'text-danger',
                    },
                    unknown: {
                        text: this.jsToLang('card.overview.server_status.unknown'),
                        class: 'text-warning',
                    }
                }

                if (!this.serverData?.cachedPowerstatus || this.serverData?.cachedPowerstatus === '') {
                    return mapper.unknown;
                }

                if (mapper[this.serverData.cachedPowerstatus]) {
                    return mapper[this.serverData.cachedPowerstatus];
                }

                return mapper.unknown;
            },
        },

        methods: {
            async getAllData() {
                this.$simpleStore.addLoader('initialLoader');

                this.getUserAccount().then(() => {
                    // refresh server to trigger watchers in components that depends on permissions.
                    this.getServer();
                    this.initialLoadCompleted = true;

                    this.areBackupsAvailable();
                    this.areSnapshotsAvailable();
                });

                this.getServer();
                this.getIpAssignments();
            },

            async getOsLogo (os) {
                try {
                    let data = await axios.post(this.xhrUrl + 'getOsLogo', {os: os});
                    return this.xhrUrl + 'getImage&path=' + data.data.url;
                } catch (e) {
                    return false;
                }
            },

            async areBackupsAvailable() {
                this.featureAvailability.backups = await this.refsProxy(this.$refs.backups, 'areBackupsAvailable', null, true);
            },

            async areSnapshotsAvailable() {
                this.featureAvailability.snapshots = await this.refsProxy(this.$refs.snapshots, 'areSnapshotsAvailable', null, true);
            },

            async openSubnetRdnsModal(subnetIpWithCidr, noEmptyTable) {
                this.$refs.subnetsRdnsModal.open(subnetIpWithCidr, noEmptyTable);
            },

            async updateServer (newValue, updateField) {
                this.$simpleStore.addLoader('updateServer_' + updateField);

                let updateData = {
                    content: {
                        [updateField]: newValue,
                    }
                }

                try {
                    await axios.post(this.xhrUrl + 'updateServer', updateData);
                    await this.getServer();
                } catch (e) {
                    this.errorNotificationFlash(e.response.data);
                } finally {
                    this.$simpleStore.delLoader('updateServer_' + updateField);
                }
            },

            async updateIp (newValue, updateField, ip) {
                this.$simpleStore.addLoader('updateIp_' + updateField + '_' + ip);
                let updateData = {
                    content: {
                        ip: ip,
                        [updateField]: newValue
                    }
                }

                try {
                    await axios.post(this.xhrUrl + 'updateIp', updateData);

                    if (updateField === 'ptrRecord') {
                        this.getRdnsAssignmentByIp(ip);
                    } else {
                        await this.getIpAssignments(1);
                    }
                } catch (e) {
                    this.errorNotificationFlash(e.response.data);
                } finally {
                    this.$simpleStore.delLoader('updateIp_' + updateField + '_' + ip);
                }
            },

            async getServerByInterval() {
                setInterval(async () => {
                    if (this.serverRequestPending === true) {
                        return false;
                    }

                    this.serverRequestPending = true;
                    await this.getServer(1);
                    this.serverRequestPending = false;
                }, Math.floor(Math.random() * (10 - 5 + 1) + 5) * 1000);
            },

            async getIpAssignments(withoutRdns) {
                this.$simpleStore.addLoader('getIpAssignments');

                try {
                    let getIpAssignments = await axios.get('modules/addons/dservermanager/request.php?xhr=1&method=getIpAssignments&pid=' + this.whmcsPid);
                    this.ipAssignments = getIpAssignments.data;

                    if (!withoutRdns) {
                        if (this.rdnsSemaphore) {
                            this.rdnsSemaphore.cancel();
                        }
                        
                        this.rdnsEntries = {};

                        for (const [key, value] of Object.entries(this.ipAssignments)) {
                            if (value?.subnetinformation?.rdnsAvailable === 1 && value?.ipAttributes?.isSubnet === 0) {
                                this.$set(this.rdnsEntries, value.ip, {
                                    rdnsEntry: '',
                                    loaded: 0,
                                });

                                this.getRdnsAssignmentByIp(value.ip);
                            }
                        }
                    }
                } catch (e) {
                    return false;
                } finally {
                    this.$simpleStore.delLoader('getIpAssignments');
                }
            },

            async getRdnsAssignmentByIp (ip) {
                this.$set(this.rdnsEntries, ip, {
                    loaded: 0,
                });

                if (!this.rdnsSemaphore) {
                    this.rdnsSemaphore = new Semaphore(3);
                }

                try {
                    await this.rdnsSemaphore.acquire();
                    
                    try {
                        let getRdnsEntry = await axios.post(this.xhrUrl + 'getRdnsAssignmentByIp', {
                            ip: ip,
                        });

                        this.$set(this.rdnsEntries, ip, {
                            rdnsEntry: getRdnsEntry?.data?.ptrRecord,
                            loaded: 1,
                        });
                    } catch (e) {
                        return false;
                    } finally {
                        this.rdnsSemaphore.release();
                    }
                } catch (e) {
                    if (e.message !== "Semaphore cancelled") {
                        console.error('RDNS semaphore error:', e);
                    }
                }
            },

            async getServerPowerFromBackend(noFailover) {
                let postData = null;

                if (noFailover) {
                    postData = {
                        noFailover: true
                    }
                }

                try {
                    let get = await axios.post('modules/addons/dservermanager/request.php?xhr=1&method=getServerPower&pid=' + this.whmcsPid, postData);
                    return get.data;
                } catch (e) {
                    console.log (e);
                }
            },

            async manageServerPower (mode) {
                if (await this.$refs.confirm.open(mode !== 'setBmcReset' ? this.jsToLang('modal.alert.power_action.title') : this.jsToLang('modal.alert.bmc_reset.title'), mode !== 'setBmcReset' ? this.jsToLang('modal.alert.power_action.description') : this.jsToLang('modal.alert.bmc_reset.description') , '', mode !== 'setBmcReset' ? this.jsToLang('modal.alert.power_action.acceptButton') : this.jsToLang('modal.alert.bmc_reset.acceptButton'))) {
                    this.$simpleStore.addLoader(mode)
                    this.$simpleStore.addLoader('manageServerPower')
                    let noFailover = null;

                    try {
                        let expectAfterBmc = this.serverData.cachedPowerstatus;

                        if (expectAfterBmc === 'unknown') {
                            expectAfterBmc = 'online';
                        }

                        const assumePowerReturn = {
                            setPowerOn: 'online',
                            setPowerOff: 'offline',
                            setPowerCycle: 'online',
                            setPowerReset: 'online',
                            setBmcReset: expectAfterBmc,
                        }

                        await axios.post('modules/addons/dservermanager/request.php?xhr=1&method=setServerPower&pid=' + this.whmcsPid, {powerMode: mode});
                        if (mode === 'setBmcReset') {
                            this.successNotificationFlash(this.jsToLang('notification.success.bmc_reset'));
                            noFailover = 1;
                            await this.sleeper(1500);
                        }

                        // wait until server's power state has changed
                        // power state changes are tricky, because IPMI may not answer for some time, or with a huge delay, or with old data (<- sleeper is used to prevent old data)
                        // this may seems ugly, but it's "ok"
                        await this.sleeper(250);
                        for (var i = 0; i < 20; i++) {
                            let getCurrentPowerstatus = await this.getServerPowerFromBackend(noFailover);

                            // depending on the power source, the online state may be "probablyOnline"
                            if (getCurrentPowerstatus.toLowerCase().includes(assumePowerReturn[mode])) {
                                break;
                            }

                            await this.sleeper(800);
                        }
                    } catch (e) {
                        console.log (e);
                        this.errorNotificationFlash(e.response.data);
                    } finally {
                        if (mode === 'bmcReset') {
                            // if something goes wrong during the loop, refetch the power state to ensure we trigger a cache refresh on the backend.
                            try {
                                await this.getServerPowerFromBackend();
                            } catch (e) {
                                console.log (e);
                            }
                        }

                        await this.getServer();

                        this.$simpleStore.delLoader(mode)
                        this.$simpleStore.delLoader('manageServerPower')
                    }
                }
            },

            canExecutePowerAction(powerAction) {
                if (!this.serverData?.powerprovider?.supportedFeatures) {
                    return false;
                }

                if (this.serverData.powerprovider.supportedFeatures.includes(powerAction)) {
                    switch (this.serverData?.cachedPowerstatus) {
                        case 'offline':
                            // if server is offline, only setPowerOn is possible.
                            return powerAction === 'setPowerOn';

                        default:
                            // if server is not offline, all actions are possible except setPowerOff
                            return powerAction !== 'setPowerOn';
                    }
                }

                return false;
            },

            async getServer(fromBackground) {
                if (fromBackground) {
                    // dont refresh from background if server power request is running
                    // otherwise, it could cause button flaps (because we use cachedPowerstatus to show the current power state)
                    if (this.$simpleStore.getLoader('manageServerPower')) {
                        return false;
                    }
                }

                this.$simpleStore.addLoader('getServer');

                try {
                    let getServer = await axios.get('modules/addons/dservermanager/request.php?xhr=1&method=getServer&pid=' + this.whmcsPid);
                    this.serverData = Object.assign({}, getServer.data);
                    this.lastGetServerError = '';

                    if (this.serverData.reinstallationprovider && this.serverData.reinstallationprovider !== '') {
                        this.$simpleStore.setProvisioningPossible(1);
                    } else {
                        this.$simpleStore.setProvisioningPossible(0);
                    }
                } catch (e) {
                    if (e?.response?.data)
                        this.lastGetServerError = this.jsToLang('error.get_server_api_request_failed.text');
                    return false;
                } finally {
                    this.$simpleStore.delLoader('getServer');
                    this.$simpleStore.delLoader('initialLoader');
                }
            },
        },
    });
</script>

<script>
    jQuery(document).ready(function() {
        let getBsVersion = '4';

        try {
            getBsVersion = jQuery.fn.tooltip.Constructor.VERSION.split('.').shift();

            jQuery('body').tooltip({
                selector: '[data-toggle="dynamic-tooltip"]',
                container: 'body',
                width: '500px',
            });
        } catch (e) {
            getBsVersion = '3';
        }

        if (getBsVersion === '3') {
            jQuery('head').append('<link rel="stylesheet" type="text/css" href="modules/addons/dservermanager/assets/css/clientarea/advanced_v1/main_bs3.css?v={/literal}{$dVersion}{literal}">');
        }
    });
</script>


{/literal}

{$customCssBottom}
{$customJsBottom}