aboutsummaryrefslogtreecommitdiff
path: root/front-end/src/views/Blog/components/FeedFields.vue
blob: 2d725f9250f2996ed1fab26b629f58de45442812 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
<script setup lang="ts">
import { computed, defineAsyncComponent, ref } from 'vue';
import { FeedProperty, UseXmlProperties } from '@vnuge/cmnext-admin';
const EpAdder = defineAsyncComponent(() => import('./podcast-helpers/EpisodeAdder.vue'));
const JsonEditorVue = defineAsyncComponent(() => import('json-editor-vue'))

const props = defineProps<{
    properties: UseXmlProperties,
    showEpAdder?: boolean
}>()

const { getXml, saveJson, getModel, addProperties } = props.properties

const jsonFeedData = ref()
const editMode = ref(false)
const xmlData = ref<string | undefined>(getXml())

const cleanXml = computed(() => {

    const formatXml = (xml : string) => { // tab = optional indent value, default is tab (\t)
        var formatted = '', indent = '';
        xml.split(/>\s*</).forEach(function (node) {
            if (node.match(/^\/\w/)){
                indent = indent.substring(1); // decrease indent by one 'tab'
            }
            formatted += indent + '<' + node + '>\r\n';
            if (node.match(/^<?\w[^>]*[^\/]$/)){
                 indent += '\t';              // increase indent
            }
        });

        return formatted.substring(1, formatted.length - 3);
    }
    return formatXml(xmlData.value || '')
})

const edit = () => {
    jsonFeedData.value = getModel()
    editMode.value = true
}

const save = () : void => {
    //Only close editor if the json is valid
    if(saveJson(jsonFeedData.value)){
        editMode.value = false
        //update xml
        xmlData.value = getXml()
    }
}

const cancel = () : void => {
    editMode.value = false
    xmlData.value = getXml()
}

const onAddEnclosure = (props: FeedProperty[]) =>{
    addProperties(props);
    //update xml
    xmlData.value = getXml()
    //update json editor
    jsonFeedData.value = getModel()
}

</script>

<template>
    <div id="feed-custom-fields">
        <div class="my-3 text-center">
            <h4>Feed custom fields</h4>
        </div>

        <div v-if="cleanXml" class="w-full max-w-2xl mx-auto">
            <pre class="xml">
{{ cleanXml }}
            </pre>
        </div>

        
        <div class="my-2 ml-auto w-fit">
            <div v-if="!editMode"  class="button-group">
                <button class="btn" @click="edit">Edit</button>
            </div>
            <div v-else class="button-group">
                <button class="btn primary" @click="save" >Update</button>
                <button class="btn" @click="cancel">Cancel</button>
            </div>
        </div>


        <div v-if="editMode" class="flex flex-col">
            <div v-if="$props.showEpAdder" class="mb-2">
                <EpAdder @submit="onAddEnclosure" />
            </div>

            <div class="">
                <JsonEditorVue :ask-to-format="true" class="json" v-model="jsonFeedData"/>
            </div>
        </div>

    </div>
</template>


<style lang="scss">

#feed-custom-fields{

    @apply w-full max-w-[80%] mx-auto py-4 my-5;

    .json > .jse-main{
        @apply w-full min-h-[40rem] rounded bg-transparent mx-auto;
    }

    .feed-fields{
        @apply mx-auto gap-4 flex flex-row justify-center my-6;
        
        input.primary{
            @apply w-full;
        }

        textarea.primary{
            @apply w-full h-full tracking-wider font-mono p-3 text-sm;
        }

        textarea.invalid{
            @apply border-red-500;
        }
    }

    .xml{
        @apply tracking-wider font-mono p-3 text-sm border dark:border-dark-500 rounded whitespace-pre-wrap;
    }

    .xml.invalid{
        @apply border-red-500;
    }

}

</style>