-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #68 from krantheman/feat-admin-dashboard
feat: Admin Dashboard
- Loading branch information
Showing
39 changed files
with
2,767 additions
and
938 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
frontend/src/components/Controls/HorizontalFormControl.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<template> | ||
<div class="grid grid-cols-1 sm:grid-cols-2 px-2.5" :class="{ 'text-ink-gray-4': disabled }"> | ||
<label class="font-medium leading-normal my-auto"> | ||
{{ label }} | ||
</label> | ||
<slot /> | ||
</div> | ||
</template> | ||
|
||
<script setup> | ||
const props = defineProps({ | ||
label: { | ||
type: String, | ||
required: true, | ||
}, | ||
disabled: { | ||
type: Boolean, | ||
default: false, | ||
}, | ||
}) | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
<template> | ||
<Dialog | ||
v-model="show" | ||
:options="{ | ||
title: __('Add Domain'), | ||
actions: [ | ||
{ | ||
label: __(domainRequest?.data ? 'Verify DNS' : 'Add Domain'), | ||
variant: 'solid', | ||
onClick: domainRequest?.data ? verifyDNS.submit : domainRequest.submit, | ||
}, | ||
], | ||
}" | ||
> | ||
<template #body-content> | ||
<div class="space-y-4"> | ||
<p class="text-p-base"> | ||
{{ | ||
__( | ||
`To add a domain, you must already own it. If you don't have one, purchase one and return here.` | ||
) | ||
}} | ||
</p> | ||
<FormControl | ||
type="text" | ||
:label="__('Domain Name')" | ||
placeholder="example.com" | ||
v-model="domainName" | ||
:readonly="!!domainRequest?.data" | ||
autocomplete="off" | ||
/> | ||
<ErrorMessage :message="domainRequest.error?.messages[0]" /> | ||
<div v-if="domainRequest.data?.verification_key" class="space-y-4"> | ||
<p class="text-p-base"> | ||
{{ | ||
__( | ||
`Add the following TXT record to your domain's DNS records to verify your ownership:` | ||
) | ||
}} | ||
</p> | ||
<Copy | ||
:label="__('Verification Key')" | ||
:value="domainRequest.data.verification_key" | ||
/> | ||
<ErrorMessage :message="verifyDNS.error?.messages[0] || verificationError" /> | ||
</div> | ||
</div> | ||
</template> | ||
</Dialog> | ||
</template> | ||
|
||
<script setup> | ||
import { ref, inject, watch } from 'vue' | ||
import { Dialog, FormControl, ErrorMessage, createResource } from 'frappe-ui' | ||
import Copy from '@/components/Controls/Copy.vue' | ||
import { raiseToast } from '@/utils' | ||
const show = defineModel() | ||
const user = inject('$user') | ||
const domainName = ref('') | ||
const verificationError = ref('') | ||
const emit = defineEmits(['reloadDomains']) | ||
watch(show, () => { | ||
if (show.value) { | ||
domainName.value = '' | ||
verificationError.value = '' | ||
domainRequest.reset() | ||
verifyDNS.reset() | ||
} | ||
}) | ||
const domainRequest = createResource({ | ||
url: 'mail.api.admin.get_domain_request', | ||
makeParams() { | ||
return { domain_name: domainName.value, mail_tenant: user.data.tenant } | ||
}, | ||
}) | ||
const verifyDNS = createResource({ | ||
url: 'mail.api.admin.verify_dns_record', | ||
makeParams() { | ||
return { domain_request: domainRequest?.data.name } | ||
}, | ||
onSuccess(data) { | ||
if (data) { | ||
show.value = false | ||
emit('reloadDomains') | ||
raiseToast('Domain added successfully!') | ||
} else verificationError.value = __('Failed to verify DNS record.') | ||
}, | ||
}) | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
<template> | ||
<Dialog | ||
v-model="show" | ||
:options="{ | ||
title: __('Add Member'), | ||
actions: [ | ||
{ | ||
label: __(accountRequest.send_invite ? 'Invite Member' : 'Add Member'), | ||
variant: 'solid', | ||
onClick: addMember.submit, | ||
}, | ||
], | ||
}" | ||
> | ||
<template #body-content> | ||
<div class="space-y-4"> | ||
<div class="flex items-center justify-between"> | ||
<FormControl | ||
type="text" | ||
:label="__('Username')" | ||
placeholder="johndoe" | ||
v-model="accountRequest.username" | ||
class="w-full" | ||
/> | ||
<FeatherIcon | ||
class="text-gray-400 h-4 w-4 mt-auto mb-1.5 mx-2.5" | ||
name="at-sign" | ||
/> | ||
<Link | ||
:label="__('Domain')" | ||
placeholder="yourdomain.com" | ||
v-model="accountRequest.domain" | ||
doctype="Mail Domain" | ||
:filters="{ tenant: user.data.tenant }" | ||
class="w-full" | ||
/> | ||
</div> | ||
<FormControl | ||
type="select" | ||
:label="__('Member Role')" | ||
:options="[ | ||
{ label: __('Mail User'), value: 'Mail User' }, | ||
{ label: __('Mail Admin'), value: 'Mail Admin' }, | ||
]" | ||
v-model="accountRequest.role" | ||
/> | ||
<hr /> | ||
<FormControl | ||
type="checkbox" | ||
:label="__('Send Invite')" | ||
v-model="accountRequest.send_invite" | ||
/> | ||
<FormControl | ||
v-if="accountRequest.send_invite" | ||
type="email" | ||
:label="__('Email')" | ||
placeholder="[email protected]" | ||
v-model="accountRequest.email" | ||
/> | ||
<template v-else> | ||
<FormControl | ||
type="text" | ||
:label="__('First Name')" | ||
placeholder="John" | ||
v-model="accountRequest.first_name" | ||
/> | ||
<FormControl | ||
type="text" | ||
:label="__('Last Name')" | ||
placeholder="Doe" | ||
v-model="accountRequest.last_name" | ||
/> | ||
<FormControl | ||
type="password" | ||
:label="__('Password')" | ||
placeholder="••••••••" | ||
v-model="accountRequest.password" | ||
/> | ||
</template> | ||
<ErrorMessage :message="addMember.error?.messages[0]" /> | ||
</div> | ||
</template> | ||
</Dialog> | ||
</template> | ||
|
||
<script setup> | ||
import { reactive, inject, watch } from 'vue' | ||
import { Dialog, FeatherIcon, FormControl, ErrorMessage, createResource } from 'frappe-ui' | ||
import Link from '@/components/Controls/Link.vue' | ||
import { raiseToast } from '@/utils' | ||
const show = defineModel() | ||
const user = inject('$user') | ||
const defaultAccountRequest = { | ||
username: '', | ||
domain: '', | ||
role: 'Mail User', | ||
send_invite: true, | ||
email: '', | ||
first_name: '', | ||
last_name: '', | ||
password: '', | ||
} | ||
const accountRequest = reactive({ ...defaultAccountRequest }) | ||
const emit = defineEmits(['reloadMembers']) | ||
watch( | ||
() => accountRequest.send_invite, | ||
() => addMember.reset() | ||
) | ||
watch(show, () => { | ||
if (show.value) { | ||
Object.assign(accountRequest, defaultAccountRequest) | ||
addMember.reset() | ||
} | ||
}) | ||
const addMember = createResource({ | ||
url: 'mail.api.admin.add_member', | ||
makeParams() { | ||
return { | ||
tenant: user.data.tenant, | ||
...accountRequest, | ||
} | ||
}, | ||
onSuccess() { | ||
raiseToast( | ||
__( | ||
accountRequest.send_invite | ||
? 'Member invited successfully' | ||
: 'Member added successfully' | ||
) | ||
) | ||
if (!accountRequest.send_invite) emit('reloadMembers') | ||
show.value = false | ||
}, | ||
}) | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.