[9/10/1400] All APIs since 7/10/1400 are done

This commit is contained in:
Your Name 2022-01-29 12:04:56 +03:30
parent f34605b9a2
commit 732054d95b
9 changed files with 14489 additions and 20 deletions

14122
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -50,6 +50,7 @@
"vue-good-table": "2.21.0",
"vue-i18n": "8.22.2",
"vue-jstree": "^2.1.6",
"vue-number-animation": "^1.1.1",
"vue-perfect-scrollbar": "0.2.1",
"vue-persian-datetime-picker": "^2.10.1",
"vue-prism-component": "1.1.1",

View File

@ -13,9 +13,10 @@ Example:
<b-button v-b-modal:modal-charge-user>Charge User</b-button>
Props:
Name Type Description
------- ------- -------------------------------------------------------------
user-id Number the id of the user you want to charge his/her account
Name Type Description
--------- ------- -------------------------------------------------------------
user-id Number the id of the user you want to charge his/her account
table-ref ? a reference to the table engine which must be refershed e.g. v-bind:xtable="this.$refs.MyTable"
-->
@ -32,7 +33,7 @@ user-id Number the id of the user you want to charge his/her account
>
<div class="d-flex align-items-center" style="column-gap: 0.5rem;">
<span>$</span>
<b-form-input v-bind:value="Payload_D.amount" />
<b-form-input v-bind:value="Payload_D.amount" v-on:input="HandleInputChanged" />
</div>
</b-modal>
@ -58,6 +59,11 @@ export default {
type: Number,
required: true,
},
tableRef: {
type: Object,
required: false,
default: undefined,
},
},
components: {
@ -78,10 +84,12 @@ export default {
methods: {
async HandleChargeButtonClicked()
{
this.Payload_D.amount = parseInt(this.Payload_D.amount)
this.$store.commit('app/toggle_full_page_overlay')
try
{
let { data } = await axios.post(`https://api.ira-lex.com/administrator/user/${this.userId}/charge/`, this.Payload_D)
if( this.tableRef !== undefined ) this.tableRef.fetch()
this.$store.commit('app/toggle_full_page_overlay')
this.$bvModal.show('modal-success')
}
@ -92,6 +100,11 @@ export default {
Log('ERROR::AXIOS::COMPONENTS/UI/CHARGE_USER_MODAL.VUE>CHARGE_USER_MODAL', e)
}
},
HandleInputChanged(e)
{
this.Payload_D.amount = e
},
},
}
</script>

View File

@ -38,6 +38,10 @@ import Antd from 'ant-design-vue'
import 'ant-design-vue/dist/antd.css'
Vue.use(Antd)
// Vue Number Animation
import VueNumber from 'vue-number-animation'
Vue.use(VueNumber)
// Feather font icon - For form-wizard
// * Shall remove it if not using font-icons of feather-icons - For form-wizard
require('@core/assets/fonts/feather/iconfont.css') // For form-wizard

65
src/modules/core.js Normal file
View File

@ -0,0 +1,65 @@
/*******************************************************************************
* Core *
* Contains various javascript utilities. *
* *
* Table of Contents: *
* - Number Thousand Separator *
* - Logging *
*******************************************************************************/
/*
|-----------------------------------------------------------------------
| Number Thousand Separator
|-----------------------------------------------------------------------
|
| A function which takes a number and a character and returns a string
| containing that number with the given character as thousands
| separators.
|
*/
export function SeparateNumberByThousands(Num, Separator = ',')
{
return Num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, Separator)
// P.S: Thanks Github Copilot for saving me numerous hours of stackoverflowing 🙂
}
/*
|-----------------------------------------------------------------------
| Format Bytes
|-----------------------------------------------------------------------
|
| Converts bytes to the equivalent kilobytes, megabytes, gigabytes, etc.
|
*/
export function FormatBytes(Bytes, Decimals = 2)
{
if( Bytes === 0 ) return '0 Bytes'
const K = 1024
const Dm = (Decimals < 0) ? 0 : Decimals
const Sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
const I = Math.floor(Math.log(Bytes) / Math.log(K))
return parseFloat((Bytes / Math.pow(K, I)).toFixed(Dm)) + ' ' + Sizes[I]
}
/*
|-----------------------------------------------------------------------
| Logging
|-----------------------------------------------------------------------
|
| Logs a message to the browser console.
| This function is provided to abstract all your logging calls, so you
| can change the style of all of them at once. It is useful to make the
| logs of your application look different so you can find them easier
| when there are hundreds of logs in the console.
|
*/
export function Log(Message, Data = '')
{
console.log(`%c ${Message} `, 'background:black; color:#bada55; font-family:"PxPlus ToshibaSat 9x16"; font-size: 13px;')
if( Data !== '' )
console.log(Data)
}

View File

@ -3,18 +3,240 @@
<h3>Dashboard</h3>
<b-card>
<b-card-title>Users Information</b-card-title>
<b-row>
<b-col sm="4" style="text-align: center;">
<number
style="font-weight: bold; font-size: 5rem; color: #7367f0;"
v-bind:from="0"
v-bind:to="UserAccountsCount_D"
v-bind:duration="2"
v-bind:delay="1"
/>
<p style="font-size: 1.1rem;">User Accounts</p>
</b-col>
<b-col sm="4" style="text-align: center;">
<number
style="font-weight: bold; font-size: 5rem; color: #7367f0;"
v-bind:from="0"
v-bind:to="FirmAccountsCount_D"
v-bind:duration="2"
v-bind:delay="1"
/>
<p style="font-size: 1.1rem;">Firm Accounts</p>
</b-col>
<b-col sm="4" style="text-align: center;">
<number
style="font-weight: bold; font-size: 5rem; color: #7367f0;"
v-bind:from="0"
v-bind:to="TotalAccountsCount_D"
v-bind:duration="2"
v-bind:delay="1"
/>
<p style="font-size: 1.1rem;">Total Accounts</p>
</b-col>
</b-row>
<br>
<br>
<b-card-title>Hardware Information</b-card-title>
<b-row class="justify-content-center">
<b-col sm="3">
<vue-apex-charts
type="donut"
height="350"
v-bind:options="DiskChartData_D.options"
v-bind:series="DiskChartData_D.series"
/>
</b-col>
<b-col sm="3">
<vue-apex-charts
type="donut"
height="350"
v-bind:options="RAMChartData_D.options"
v-bind:series="RAMChartData_D.series"
/>
</b-col>
<b-col sm="3">
<vue-apex-charts
type="donut"
height="350"
v-bind:options="CPUChartData_D.options"
v-bind:series="CPUChartData_D.series"
/>
</b-col>
<!-- <b-col sm="3">
<number
style="font-weight: bold; font-size: 5rem; color: #7367f0;"
v-bind:from="0"
v-bind:to="HardwareInfo_D.cpu.count"
v-bind:duration="2"
v-bind:delay="1"
/>
<p style="font-size: 1.1rem;">CPU Cores</p>
</b-col> -->
<!-- <div class="d-flex flex-column align-items-center">
</div> -->
</b-row>
</b-card>
</div>
</template>
<script>
import { BCard } from 'bootstrap-vue'
import { BRow, BCol, BCard, BCardTitle } from 'bootstrap-vue'
import { Log, FormatBytes } from '@/modules/core'
import axios from '@/axios'
import VueApexCharts from 'vue-apexcharts'
export default {
name: 'DashboardView',
components: {
BRow,
BCol,
BCard,
BCardTitle,
VueApexCharts,
},
data() {
return {
TotalAccountsCount_D: 0,
UserAccountsCount_D: 0,
FirmAccountsCount_D: 0,
HardwareInfo_D: undefined,
DiskChartData_D: {
series: [],
options: {
labels: [ 'Used', 'Free' ],
plotOptions: {
pie: {
donut: {
labels: {
show: true,
total: {
show: true,
label: 'Disk',
formatter: () => '',
},
}
}
}
},
},
},
RAMChartData_D: {
series: [],
options: {
labels: [ 'Used', 'Free' ],
plotOptions: {
pie: {
donut: {
labels: {
show: true,
total: {
show: true,
label: 'RAM',
formatter: () => '',
},
}
}
}
},
},
},
CPUChartData_D: {
series: [],
options: {
labels: [ 'Involved', 'Free' ],
plotOptions: {
pie: {
donut: {
labels: {
show: true,
total: {
show: true,
label: 'CPU',
formatter: (val) =>'',
},
}
}
}
},
},
},
}
},
async created()
{
// -----------------------------------------------------------------
// Get Hardware Info
// -----------------------------------------------------------------
try
{
const { data } = await axios.post('administrator/hardware/')
this.HardwareInfo_D = data
Log('Hardware', data)
// this.DiskChartData_D.options.plotOptions.pie.donut.labels.total.label = FormatBytes(data.disk.total)
this.DiskChartData_D.series.push(data.disk.used)
this.DiskChartData_D.series.push(data.disk.free)
this.RAMChartData_D.series.push(data.ram.used)
this.RAMChartData_D.series.push(data.ram.available)
this.CPUChartData_D.series.push(data.cpu.percent)
this.CPUChartData_D.series.push(100 - data.cpu.percent)
}
catch (e)
{
Log('ERROR::AXIOS::VIEWS/MISC/DASHBOARD>MOUNTED>GET_HARDWARE_INFO', e)
}
},
async mounted()
{
// -----------------------------------------------------------------
// Get Number of Users
// -----------------------------------------------------------------
try
{
const { data } = await axios.post('administrator/user/query/', {
query: [{ field: 'is_main', condition: '=', value: false }]
})
this.UserAccountsCount_D = data.query.total
}
catch (e)
{
Log('ERROR::AXIOS::VIEWS/MISC/DASHBOARD>MOUNTED>GET_NUMBER_OF_USERS', e)
}
// -----------------------------------------------------------------
// Get Number of Firms
// -----------------------------------------------------------------
try
{
const { data } = await axios.post('administrator/user/query/', {
query: [{ field: 'is_main', condition: '=', value: true }]
})
this.FirmAccountsCount_D = data.query.total
}
catch (e)
{
Log('ERROR::AXIOS::VIEWS/MISC/DASHBOARD>MOUNTED>GET_NUMBER_OF_FIRMS', e)
}
// -----------------------------------------------------------------
// Get Number of Accounts
// -----------------------------------------------------------------
try
{
const { data } = await axios.post('administrator/user/query/')
this.TotalAccountsCount_D = data.query.total
}
catch (e)
{
Log('ERROR::AXIOS::VIEWS/MISC/DASHBOARD>MOUNTED>GET_NUMBER_OF_ACCOUNTS', e)
}
},
}
</script>

View File

@ -54,6 +54,29 @@
v-on:selectedRows="SelectedRows_D"
v-bind:options="TableOptions_D"
>
<span slot="firm" slot-scope="text, record">
<svg v-if="text.record.is_main" style="width: 24px; height: 24px" viewBox="0 0 24 24">
<path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z" />
</svg>
<svg v-else style="width: 24px; height: 24px" viewBox="0 0 24 24">
<path fill="currentColor" d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" />
</svg>
</span>
<span slot="charge" slot-scope="text, record">
<span v-if="text.record.subscription">${{ SeparateNumberByThousands(text.record.subscription.charge) }}</span>
<!-- <span v-if="text.record.subscription">$ {{ text.record.subscription.charge }}</span> -->
<span v-else>$0</span>
</span>
<span slot="total_uploaded_size" slot-scope="text, record">
<span>{{ FormatBytes(text.record.total_uploaded_size) }}</span>
</span>
<span slot="total_firm_uploaded_size" slot-scope="text, record">
<span>{{ FormatBytes(text.record.total_firm_uploaded_size) }}</span>
</span>
<span slot="action" slot-scope="text, record">
<b-button
v-if="text.record.is_main"
@ -65,21 +88,12 @@
Charge
</b-button>
</span>
<span slot="firm" slot-scope="text, record">
<svg v-if="text.record.is_main" style="width: 24px; height: 24px" viewBox="0 0 24 24">
<path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z" />
</svg>
<svg v-else style="width: 24px; height: 24px" viewBox="0 0 24 24">
<path fill="currentColor" d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" />
</svg>
</span>
</XTable>
</div>
</b-card>
<AddUserModal type="user" v-on:submit="HandleNewUserAdded()" />
<ChargeUserModal v-bind:user-id="IdOfUserToCharge_D" v-on:submit="HandleUserCharged()" />
<ChargeUserModal v-bind:user-id="IdOfUserToCharge_D" v-bind:table-ref="$refs.users" v-on:submit="HandleUserCharged()" />
</div>
</template>
@ -92,6 +106,7 @@ import ChargeUserModal from '@/components/ui/ChargeUserModal'
import * as TableCol from "./userTbl"
import XTable from "@/components/x-table/XTable"
import axios from '@/axios'
import { SeparateNumberByThousands, FormatBytes } from '@/modules/core'
// import CoreMixin from '@/mixins/index'
const InnerColumns = [
@ -149,6 +164,16 @@ export default {
},
methods: {
SeparateNumberByThousands(Num)
{
return SeparateNumberByThousands(Num)
},
FormatBytes(Bytes)
{
return FormatBytes(Bytes)
},
HandleNewUserAdded()
{
this.Users_D.push(2)
@ -166,7 +191,6 @@ export default {
ApplyFilters()
{
console.log('FETCH')
this.$refs.users.query.query = [
]
if( this.Query_D.IsMain )
@ -175,7 +199,6 @@ export default {
condition: '=',
value: this.Query_D.IsMain,
})
console.log(this.$refs.users.query.query)
this.$refs.users.fetch()
},
},
@ -184,6 +207,12 @@ export default {
{
this.Model_D = TableCol.default
},
async mounted()
{
const { data } = await axios.post('administrator/user/query/')
console.log('users: ', data)
}
}
</script>

View File

@ -5,9 +5,10 @@ tbl.add(new Xtc('first_name', 'First Name'))
tbl.add(new Xtc('last_name', 'Last Name'))
tbl.add(new Xtc('email_address', 'Email'))
tbl.add(new Xtc('is_main', 'Firm').renderSlot('firm'))
// tbl.add(new Xtc('user_type', 'User Type'))
// tbl.add(new Xtc('birthday', 'Birthday'))
// tbl.add(new Xtc('status', 'Status'))
tbl.add(new Xtc('subscription.charge', 'Charge').renderSlot('charge'))
tbl.add(new Xtc('total_uploaded_size', 'Uploaded Size').renderSlot('total_uploaded_size'))
tbl.add(new Xtc('total_firm_uploaded_size', 'Firm Uploaded Size').renderSlot('total_firm_uploaded_size'))
tbl.add(new Xtc('action', 'Action').noSort().renderSlot('action'))
export default tbl

View File

@ -4718,6 +4718,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a"
integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==
gsap@^3.6.0:
version "3.9.1"
resolved "https://registry.yarnpkg.com/gsap/-/gsap-3.9.1.tgz#d4c7443540497afee9ddc0824fd0180224e33360"
integrity sha512-JSGVYoC6da4pIjdF/yxFU6Rz8OojOIDkbooveZlfNg0+JIoFoRruyfWAEi6R/gUeNcuOiTqUIb0gi1nCNrHf8w==
gzip-size@^5.0.0:
version "5.1.1"
resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274"
@ -9423,6 +9428,13 @@ vue-loader@^15.9.2:
vue-hot-reload-api "^2.3.0"
vue-style-loader "^4.1.0"
vue-number-animation@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/vue-number-animation/-/vue-number-animation-1.1.1.tgz#785d35b8cbd349919265fb98ced566c388d5753b"
integrity sha512-xSYZZ50dbfQa0MPtDMECCkPSe6jDU56gPIBRXzfu9G/lFaCMzWyMokRQiHHK3/H/2WXdWGwnuZjpdphurtAHAg==
dependencies:
gsap "^3.6.0"
vue-perfect-scrollbar@0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/vue-perfect-scrollbar/-/vue-perfect-scrollbar-0.2.1.tgz#2fecab975512f7c8c37e1610dee48faf46d649f3"