Skip to content

Commit

Permalink
Merge pull request #1031 from pateljannat/brand-settings
Browse files Browse the repository at this point in the history
feat:  brand settings
  • Loading branch information
pateljannat authored Sep 26, 2024
2 parents 41ad3d0 + 11a9bff commit bb9b179
Show file tree
Hide file tree
Showing 11 changed files with 322 additions and 114 deletions.
85 changes: 85 additions & 0 deletions frontend/src/components/BrandSettings.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<template>
<div class="flex flex-col justify-between h-full">
<div>
<div class="flex items-center justify-between">
<div class="font-semibold mb-1">
{{ __(label) }}
</div>
<Badge
v-if="isDirty"
:label="__('Not Saved')"
variant="subtle"
theme="orange"
/>
</div>
<div class="text-xs text-gray-600">
{{ __(description) }}
</div>
</div>
<SettingFields :fields="fields" :data="data.data" />
<div class="flex flex-row-reverse mt-auto">
<Button variant="solid" :loading="saveSettings.loading" @click="update">
{{ __('Update') }}
</Button>
</div>
</div>
</template>
<script setup>
import { createResource, Button, Badge } from 'frappe-ui'
import SettingFields from '@/components/SettingFields.vue'
import { watch, ref } from 'vue'
const isDirty = ref(false)
const props = defineProps({
fields: {
type: Array,
required: true,
},
data: {
type: Object,
required: true,
},
label: {
type: String,
required: true,
},
description: {
type: String,
},
})
const saveSettings = createResource({
url: 'frappe.client.set_value',
makeParams(values) {
console.log(values)
return {
doctype: 'Website Settings',
name: 'Website Settings',
fieldname: values.fields,
}
},
})
const update = () => {
let fieldsToSave = {}
let imageFields = ['favicon', 'banner_image', 'footer_logo']
props.fields.forEach((f) => {
if (imageFields.includes(f.name)) {
fieldsToSave[f.name] = f.value ? f.value.file_url : null
} else {
fieldsToSave[f.name] = f.value
}
})
saveSettings.submit({
fields: fieldsToSave,
})
}
watch(props.data, (newData) => {
console.log(newData)
if (newData && !isDirty.value) {
isDirty.value = true
}
})
</script>
64 changes: 63 additions & 1 deletion frontend/src/components/Modals/Settings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@
:label="activeTab.label"
:description="activeTab.description"
/>
<BrandSettings
v-else-if="activeTab.label === 'Branding'"
:label="activeTab.label"
:description="activeTab.description"
:fields="activeTab.fields"
:data="branding"
/>
<SettingDetails
v-else
:fields="activeTab.fields"
Expand All @@ -58,13 +65,14 @@
</Dialog>
</template>
<script setup>
import { Dialog, createDocumentResource } from 'frappe-ui'
import { Dialog, createDocumentResource, createResource } from 'frappe-ui'
import { ref, computed, watch } from 'vue'
import { useSettings } from '@/stores/settings'
import SettingDetails from '../SettingDetails.vue'
import SidebarLink from '@/components/SidebarLink.vue'
import Members from '@/components/Members.vue'
import Categories from '@/components/Categories.vue'
import BrandSettings from '@/components/BrandSettings.vue'
const show = defineModel()
const doctype = ref('LMS Settings')
Expand All @@ -79,6 +87,12 @@ const data = createDocumentResource({
auto: true,
})
const branding = createResource({
url: 'lms.lms.api.get_branding',
auto: true,
cache: 'brand',
})
const tabsStructure = computed(() => {
return [
{
Expand Down Expand Up @@ -155,6 +169,54 @@ const tabsStructure = computed(() => {
label: 'Customise',
hideLabel: false,
items: [
{
label: 'Branding',
icon: 'Blocks',
description:
'Customize the brand information of your learning system',
fields: [
{
label: 'Brand Name',
name: 'app_name',
type: 'text',
},
{
label: 'Copyright',
name: 'copyright',
type: 'text',
},
{
label: 'Address',
name: 'address',
type: 'textarea',
rows: 4,
},
{
label: 'Footer "Powered By"',
name: 'footer_powered',
type: 'textarea',
rows: 4,
},
{
type: 'Column Break',
},
{
label: 'Logo',
name: 'banner_image',
type: 'Upload',
},
{
label: 'Favicon',
name: 'favicon',
type: 'Upload',
},
{
label: 'Footer Logo',
name: 'footer_logo',
type: 'Upload',
},
],
},
{
label: 'Sidebar',
icon: 'PanelLeftIcon',
Expand Down
92 changes: 17 additions & 75 deletions frontend/src/components/SettingDetails.vue
Original file line number Diff line number Diff line change
@@ -1,53 +1,23 @@
<template>
<div class="flex flex-col justify-between h-full">
<div>
<div class="font-semibold mb-1">
{{ __(label) }}
<div class="flex itemsc-center justify-between">
<div class="font-semibold mb-1">
{{ __(label) }}
</div>
<Badge
v-if="data.isDirty"
:label="__('Not Saved')"
variant="subtle"
theme="orange"
/>
</div>
<div class="text-xs text-gray-600">
{{ __(description) }}
</div>
</div>
<div
class="my-5"
:class="{ 'flex justify-between w-full': columns.length > 1 }"
>
<div v-for="(column, index) in columns" :key="index">
<div
class="flex flex-col space-y-5"
:class="columns.length > 1 ? 'w-72' : 'w-full'"
>
<div v-for="field in column">
<Link
v-if="field.type == 'Link'"
v-model="field.value"
:doctype="field.doctype"
:label="field.label"
/>

<Codemirror
v-else-if="field.type == 'Code'"
v-model:value="field.value"
:label="field.label"
:height="200"
:options="{
mode: field.mode,
theme: 'seti',
}"
/>

<FormControl
v-else
:key="field.name"
v-model="field.value"
:label="field.label"
:type="field.type"
:rows="field.rows"
/>
</div>
</div>
</div>
</div>
<SettingFields :fields="fields" :data="data.doc" />
<div class="flex flex-row-reverse mt-auto">
<Button variant="solid" :loading="data.save.loading" @click="update">
{{ __('Update') }}
Expand All @@ -57,12 +27,8 @@
</template>

<script setup>
import { FormControl, Button } from 'frappe-ui'
import { computed } from 'vue'
import Link from '@/components/Controls/Link.vue'
import Codemirror from 'codemirror-editor-vue3'
import 'codemirror/theme/seti.css'
import 'codemirror/mode/htmlmixed/htmlmixed.js'
import { Button, Badge } from 'frappe-ui'
import SettingFields from '@/components/SettingFields.vue'
const props = defineProps({
fields: {
Expand All @@ -82,40 +48,16 @@ const props = defineProps({
},
})
const columns = computed(() => {
const cols = []
let currentColumn = []
props.fields.forEach((field) => {
if (field.type === 'Column Break') {
if (currentColumn.length > 0) {
cols.push(currentColumn)
currentColumn = []
}
} else {
if (field.type == 'checkbox') {
field.value = props.data.doc[field.name] ? true : false
} else {
field.value = props.data.doc[field.name]
}
currentColumn.push(field)
}
})
if (currentColumn.length > 0) {
cols.push(currentColumn)
}
return cols
})
const update = () => {
props.fields.forEach((f) => {
props.data.doc[f.name] = f.value
if (f.type != 'Column Break') {
props.data.doc[f.name] = f.value
}
})
props.data.save.submit()
}
</script>

<style>
.CodeMirror pre.CodeMirror-line,
.CodeMirror pre.CodeMirror-line-like {
Expand Down
Loading

0 comments on commit bb9b179

Please sign in to comment.