Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
coddmeistr committed Feb 12, 2025
2 parents 3909bc0 + 142612b commit 23c7f1d
Show file tree
Hide file tree
Showing 9 changed files with 273 additions and 31 deletions.
2 changes: 1 addition & 1 deletion admin-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"jodit-vue": "^2.6.0",
"js-cookie": "^3.0.5",
"json-schema": "^0.4.0",
"nocloud-proto": "https://github.com/slntopp/nocloud-proto#36f115ce6bf0d0c2615c2c00e970df0c7e450882",
"nocloud-proto": "https://github.com/slntopp/nocloud-proto#78355039f2b5400d80d26b6006bc659c294212db",
"nocloud-ui": "^1.0.16",
"nocloudjsrest": "^1.5.17",
"nth-check": "^2.1.1",
Expand Down
204 changes: 204 additions & 0 deletions admin-ui/src/components/ServicesProvider/suspend-rules.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
<template>
<div class="pa-5">
<div class="d-flex align-center">
<v-card-title>Rules enabled</v-card-title>
<v-switch v-model="isRulesEnabled"></v-switch>
</div>

<v-form ref="suspendRulesForm">
<div v-for="day in dayOfWeeks" :key="day">
<v-card-title
>{{ day }}

<v-switch
class="ml-3"
@change="changeEnableAll(day)"
:input-value="suspendRules[day]?.length === 0"
label="Enable all day"
/>
<v-btn @click="addNewIn(day)" class="ml-2" icon>
<v-icon>mdi-plus</v-icon>
</v-btn></v-card-title
>

<v-row
v-for="(rule, index) in suspendRules[day] || []"
:key="index"
class="rule-row"
>
<div class="field">
<span>UTC Start time:</span>
<v-text-field :rules="timeRule" v-model="rule.startTime" />
</div>
<div class="field">
<span>Local Start time:</span>
<v-text-field
disabled
readonly
:value="formatTimeFromUtc(rule.startTime)"
/>
</div>
<div class="field">
<span>UTC End time:</span>
<v-text-field :rules="timeRule" v-model="rule.endTime" />
</div>
<div class="field">
<span>Local End time:</span>
<v-text-field
disabled
readonly
:value="formatTimeFromUtc(rule.endTime)"
/>
</div>

<div class="d-flex justify-center align-center">
<v-btn @click="deleteRangeFromDay(day, index)" class="mr-2" icon>
<v-icon>mdi-delete</v-icon>
</v-btn>
</div>
</v-row>
</div>
</v-form>

<div class="d-flex justify-end">
<v-btn @click="save" :loading="isSaveLoading">Save</v-btn>
</div>
</div>
</template>

<script setup>
import { DayOfWeek } from "nocloud-proto/proto/es/services_providers/services_providers_pb";
import { onMounted, ref, toRefs } from "vue";
import { useStore } from "@/store";
import api from "@/api";
const dayOfWeeks = Object.keys(DayOfWeek).filter((v) => !+v && +v !== 0);
const props = defineProps(["template"]);
const { template } = toRefs(props);
const store = useStore();
const suspendRules = ref({});
const isRulesEnabled = ref(false);
const isSaveLoading = ref(false);
const suspendRulesForm = ref();
const timeRule = [(v) => !!isTime(v) || "Not valid time"];
onMounted(() => {
dayOfWeeks.forEach((day) => (suspendRules.value[day] = null));
setTemplateRules();
isRulesEnabled.value = !!template.value?.suspendRules?.enabled;
});
function formatTimeFromUtc(time) {
if (!isTime(time)) {
return "-";
}
const nowDate = new Date().toUTCString();
const oldTime = /[0-9]{2}:[0-9]{2}/.exec(nowDate)[0];
var newDate = new Date(Date.parse(nowDate.replace(oldTime, time)));
return /[0-9]{2}:[0-9]{2}/.exec(newDate)[0];
}
function isTime(value) {
return /^([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]$/.test(value);
}
const setTemplateRules = () => {
template.value.suspendRules.schedules.map((shedule) => {
suspendRules.value[shedule.day] = shedule.allowedSuspendTime.map(
(range) => ({
startTime: range.startTime,
endTime: range.endTime,
})
);
});
suspendRules.value = { ...suspendRules.value };
};
const addNewIn = (day) => {
if (!suspendRules.value[day]) {
suspendRules.value[day] = [];
}
suspendRules.value[day].push({
endTime: "00:00",
startTime: "00:00",
});
suspendRules.value = { ...suspendRules.value };
};
const deleteRangeFromDay = (day, index) => {
suspendRules.value[day] = suspendRules.value[day].filter(
(_, i) => i !== index
);
suspendRules.value = { ...suspendRules.value };
};
const changeEnableAll = (day) => {
if (suspendRules.value[day]?.length === 0) {
suspendRules.value[day] = null;
} else {
suspendRules.value[day] = [];
}
};
const save = async () => {
if (!suspendRulesForm.value.validate()) {
store.commit("snackbar/showSnackbarError", {
message: "Rules not valid!!!",
});
return;
}
isSaveLoading.value = true;
try {
const newSuspendRules = {};
newSuspendRules.enabled = isRulesEnabled.value;
newSuspendRules.schedules = [];
Object.keys(suspendRules.value).map((day) => {
newSuspendRules.schedules.push({
day,
allowedSuspendTime: suspendRules.value[day],
});
});
await api.servicesProviders.update(template.value.uuid, {
...template.value,
suspendRules: newSuspendRules,
});
store.commit("snackbar/showSnackbarSuccess", {
message: "Done",
});
} catch {
store.commit("snackbar/showSnackbarError", {
message: "Error while try update suspend rules",
});
} finally {
isSaveLoading.value = false;
}
};
</script>
<style scoped lang="scss">
.rule-row {
.field {
margin: 0px 20px;
display: flex;
align-items: center;
span {
margin-right: 10px;
}
div {
max-width: 75px;
}
}
}
</style>
8 changes: 4 additions & 4 deletions admin-ui/src/components/account/info.vue
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@
</v-btn>
</confirm-dialog>
</hint-btn>
<hint-btn hint="Create transaction/invoice">
<v-chip @click="openTransaction" class="ma-1" color="primary" outlined
<hint-btn hint="Create invoice">
<v-chip @click="openInvoice" class="ma-1" color="primary" outlined
>Balance: {{ account.balance?.toFixed(2) || 0 }}
{{ account.currency?.code }}</v-chip
>
Expand Down Expand Up @@ -438,9 +438,9 @@ export default {
this.isChangeRegularPaymentLoading = false;
}
},
openTransaction() {
openInvoice() {
this.$router.push({
name: "Transactions create",
name: "Invoice create",
query: { account: this.account.uuid },
});
},
Expand Down
22 changes: 15 additions & 7 deletions admin-ui/src/components/invoiceItemsTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,12 @@
</template>

<template v-if="showDelete" v-slot:[`item.total`]="{ item }">
<span>{{ (item.price * item.amount || 0).toFixed(2) }}</span>
<span>{{
[
(item.price * item.amount || 0).toFixed(2),
account?.currency?.code,
].join(" ")
}}</span>
</template>

<template v-if="items.length" v-slot:body.append>
Expand All @@ -68,12 +73,15 @@
<td></td>
<td>
{{
items
.reduce(
(acc, item) => acc + (item.amount || 0) * (item.price || 0),
0
)
.toFixed(2)
[
items
.reduce(
(acc, item) => acc + (item.amount || 0) * (item.price || 0),
0
)
.toFixed(2),
account?.currency?.code,
].join(" ")
}}
</td>
<td></td>
Expand Down
30 changes: 19 additions & 11 deletions admin-ui/src/components/plan/event-overrides.vue
Original file line number Diff line number Diff line change
Expand Up @@ -55,21 +55,28 @@
<v-card-title v-else>New event override</v-card-title>

<v-text-field
:rules="[requiredRule, uniqueKeyRule]"
:rules="[requiredRule]"
v-model="newOverride.key"
label="Key"
/>
<v-text-field
:rules="[requiredRule, uniqueOverrideRule]"
:rules="[requiredRule]"
v-model="newOverride.override"
label="Override"
/>

<div class="d-flex justify-center">
<v-card-title style="color: red" v-if="isNotUniqueOverride">{{
"Already overrided!"
}}</v-card-title>
</div>

<div class="d-flex justify-end">
<v-btn @click="isAddOverrideOpen = false">Close</v-btn>
<v-btn
@click="addNewEvent"
:loading="isAddOverrideLoading"
:disabled="isNotUniqueOverride"
class="ml-3"
>{{ isEditOverride ? "Edit" : "Add" }}</v-btn
>
Expand All @@ -81,7 +88,7 @@
</template>

<script setup>
import { onMounted, ref, toRefs, watch } from "vue";
import { computed, onMounted, ref, toRefs, watch } from "vue";
import api from "@/api";
const props = defineProps(["template"]);
Expand All @@ -103,14 +110,15 @@ const editedOverride = ref(false);
onMounted(() => setEventOverrides());
const requiredRule = (val) => !!val || "Field required";
const uniqueKeyRule = (val) =>
isEditOverride.value ||
!eventOverrides.value.find((override) => override.key === val) ||
"Already overrided!";
const uniqueOverrideRule = (val) =>
isEditOverride.value ||
!eventOverrides.value.find((override) => override.override === val) ||
"Already overrided!";
const isNotUniqueOverride = computed(
() =>
!isEditOverride.value &&
eventOverrides.value.find(
(override) =>
override.override === newOverride.value.override &&
override.key === newOverride.value.key
)
);
const setEventOverrides = () => {
eventOverrides.value = [...template.value.customEvents];
Expand Down
4 changes: 4 additions & 0 deletions admin-ui/src/functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,10 @@ export function getSecondsByDays(days) {

export function getState(item) {
if (!item.state) return item?.data?.is_monitored ? "ERROR" : "LCM_INIT";
if (!item.state.state)
return item?.state?.meta?.lcm_state_str
? item?.state.meta.lcm_state_str.toUpperCase()
: "ERROR";

return item.state.state;
}
Expand Down
Loading

0 comments on commit 23c7f1d

Please sign in to comment.