PageSourceSearch

https://www.kfzparts24.de/js-static/de/frontend/resources/js/desig…/mediaBrowser.js?v=4.26.41.1&p=3

js kfzparts24.de collected 2026-10-08 03:23:37 UTC 8,631 bytes, 191 lines download raw bytes

1const MediaBrowser = {
2    delimiters: ['{[', ']}'],
3    components: { CategoryBranch },
4    props: {
5        modelValue: {
6            type: String,
7            default: () => ''
8        },
9        standalone: {
10            type: Boolean,
11            default: true
12        },
13        showdelete: {
14            type: Boolean,
15            default: true
16        }
17    },
18    emits: ['update:modelValue', 'image-selected'],
19    template: `
20        <!-- Buttons nur anzeigen, wenn im standalone-Modus -->
21        <template v-if="standalone">
22            <button type="button" class="btn btn-primary" @click="openBrowserInternally">Medien Bild ausw\u00E4hlen</button>
23            <button type="button" class="btn btn-default" @click="removeImage" v-if="selectedImagePath !== '' && showdelete">Entfernen</button>
24        </template>
25        <div class="modal" role="dialog" :style="{ display: isEditing ? 'block' : 'none' }">
26            <div class="modal-dialog modal-xl" role="document">
27                <div class="modal-content">
28                    <div class="modal-header">
29                        <h1 class="modal-title fs-4">Bilder-Auswahl</h1>
30                    </div>
31                    <div class="modal-body">
32                        <div class="row">
33                            <div class="col-3 mediaMenu">
34                                <category-branch v-for="category in displayedCategories" :key="category.categoryId" :category="category" @select-category="handleCategorySelection" :highlightselected="selectedFolder" />
35                            </div>
36                            <div class="col-9 mediaManager">
37                                <div id="mediaMenuFileList" class="row">
38                                    <div v-for="image in folderImages" class="col-3">
39                                        <div class="image-box" @click="selectImage(image.absoluteOrRelativeWebFile)">
40                                            <div class="image-fluid-box">
41                                                <img :src="'/' + image.absoluteOrRelativeWebFile" class="img-fluid" >
42                                            </div>
43                                            <p class="img-title">{[ image.fileNameWithExtension ]}</p>
44                                        </div>
45                                    </div>
46                                    <div v-if="folderImages.length === 0">keine Bilder gefunden</div>
47                                </div>
48                            </div>
49                        </div>
50                    </div>
51                    <div class="modal-footer">
52                        <button type="button" class="btn btn-secondary" @click="closeBrowser">Abbrechen</button>
53                    </div>
54                </div>
55            </div>
56        </div>
57    `,
58    data() {
59        return {
60            displayedCategories: {},
61            selectedImagePath: '',
62            selectedFolder: '',
63            folders: {},
64            folderImages: [],
65            isEditing: false,
66            showAsWidget: false, // Diese Property wird nicht direkt verwendet, aber ich lasse sie mal drin.
67            callingEditorId: null // NEU: Speichert die ID des aufrufenden Editors
68        };
69    },
70    watch: {
71        selectedImagePath(newVal, oldVal) {
72            this.$emit('update:modelValue', newVal);
73        }
74    },
75    created() {
76   this.selectedImagePath = this.modelValue;
77		if (!this.standalone) {
78			this.handleOpenMediaBrowserEvent = (event) => {
79				if (event.detail && event.detail.editorId) {
80					this.callingEditorId = event.detail.editorId;
81				} else {
82					this.callingEditorId = null;
83					console.warn('MediaBrowser (non-standalone) opened without an editorId.');
84				}
85				this.isEditing = true;
86			};
87			if (window.mediaBrowserEvents) {
88				window.mediaBrowserEvents.addEventListener('open-media-browser', this.handleOpenMediaBrowserEvent);
89			} else {
90				console.warn('window.mediaBrowserEvents not found in MediaBrowser (non-standalone). Exter
90nal opening might fail.');
91			}
92		}
93        fetch(`/servlets/ajax?todo=getmediafolders`, { method: 'GET', headers: new Headers({ 'content-type': 'application/json' }) })
94            .then(response => response.json())
95            .then(folders => {
96                let newFolders = Object.fromEntries(
97                    Object.entries(folders).map(([fullPath, value]) => {
98                        const newKey = fullPath.split('media')[1];
99                        return [newKey, value];
100                    })
101                );
102                this.selectedFolder = Object.keys(newFolders)[0];
103                this.loadImages(this.selectedFolder);
104                this.folders = newFolders;
105                let test = this.buildTreeFromOrderedFolders(this.folders);
106                this.displayedCategories = test;
107            });
108    },
109    beforeUnmount() { // NEU: Event Listener aufräumen
110        if (window.mediaBrowserEvents && this.handleOpenMediaBrowserEvent) {
111            window.mediaBrowserEvents.removeEventListener('open-media-browser', this.handleOpenMediaBrowserEvent);
112        }
113    },
114    methods: {
115        loadImages(folder) {
116            if (typeof folder === 'undefined') {
117                return;
118            }
119            folder = folder.replaceAll('\\', '/');
120            fetch(`/servlets/ajax?todo=getmediaimages&dir=${folder}`, { method: 'GET', headers: new Headers({ 'content-type': 'application/json' }) })
121                .then(response => response.json())
122                .then(images => {
123                    this.folderImages = images;
124                });
125        },
126        selectImage(path) {
127            this.selectedImagePath = '/' + path;
128            const event = new CustomEvent('image-selected', {
129                detail: {
130                    path: this.selectedImagePath,
131                    targetEditorId: this.callingEditorId
132                }
133            });
134            if (window.mediaBrowserEvents) {
135                window.mediaBrowserEvents.dispatchEvent(event);
136            } else {
137                console.warn('window.mediaBrowserEvents not found. Image selection event might not be globally dispatched.');
138            }
139            this.$emit('image-selected', this.selectedImagePath); // Für standalone v-model und event
140            this.isEditing = false;
141            // this.callingEditorId = null; // Kann hier zurückgesetzt werden, oder in closeBrowser/openBrowserInternally
142        },
143        removeImage() {
144            this.selectedImagePath = '';
145            this.$emit('update:modelValue', '');
146        },
147        handleCategorySelection(id) {
148            this.loadImages(id);
149        },
150        buildTreeFromOrderedFolders(folders) {
151            const categories = [];
152            const nodeMap = {};
153            for (let path of Object.keys(folders)) {
154                path = path.replaceAll('/', '\\');
155                const lastSlashIndex = path.lastIndexOf("\\");
156                let parentPath = null;
157                if (lastSlashIndex !== -1) {
158                    parentPath = path.substring(0, lastSlashIndex);
159                }
160                const node = {
161                    categoryId: path,
162                    identifier: path.substring(lastSlashIndex).substring(1),
163                    children: []
164                };
165                nodeMap[path] = node;
166                if (parentPath) {
167                    const parentNode = nodeMap[parentPath];
168                    if (parentNode) {
169                        parentNode.children.push(node);
170                    } else {
171                        categories.push(node);
172                    }
173                } else {
174                    categories.push(node);
175                }
176            }
177            return categories;
178        },
179        openBrowserInternally() { // Umbenannt von openBrowser, um Verwechslung mit externem Event zu vermeiden
180            // Wenn der Browser "standalone" geöffnet wird, gibt es keine callingEditorId von außen
181            this.callingEditorId = null; // Sicherstellen, dass keine alte ID verwendet wird
182            this.isEditing = true;
183        },
184        closeBrowser() {
185            this.isEditing = false;
186            this.callingEditorId = null; // NEU: ID zurücksetzen, wenn abgebrochen wird
187        },
188    }
189};
190window.designerwidgets = window.designerwidgets || {};
191window.designerwidgets.mediabrowser = MediaBrowser;

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.