directus-extension-inframe 2.0.7 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -76
- package/dist/app.js +1 -1
- package/package.json +40 -37
package/README.md
CHANGED
|
@@ -1,107 +1,120 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 🚀 inFrame: The Ultimate Module for External Content Integration in Directus
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/directus-extension-inframe)
|
|
4
4
|
[](https://github.com/devix-tecnologia/directus-extension-inframe/blob/main/LICENSE)
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
---
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
## 💡 Stop Switching Tabs. Start Integrating.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
**inFrame** is the _plug-and-play_ solution that transforms your Directus admin panel into a centralized information
|
|
11
|
+
hub. Integrate BI dashboards, real-time reports, external tools, and any content via `iframe` directly into your
|
|
12
|
+
Headless CMS.
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
- **📈 Real-time reports**: View updated data without leaving Directus
|
|
14
|
-
- **🔗 Organized links**: Centralize access to external tools in one place
|
|
15
|
-
- **🌍 Multilingual support**: Automatic translations for multiple languages
|
|
16
|
-
- **⚡ Zero configuration**: Plug-and-play installation with automatic setup
|
|
14
|
+
> **Boost Productivity:** Get instant access to critical data and third-party tools without ever leaving Directus.
|
|
17
15
|
|
|
18
|
-
|
|
16
|
+

|
|
19
17
|
|
|
20
|
-
|
|
18
|
+
---
|
|
21
19
|
|
|
22
|
-
|
|
20
|
+
## 🎯 Why inFrame is Essential for Your Directus Project
|
|
23
21
|
|
|
24
|
-
|
|
22
|
+
| Key Benefit | Description |
|
|
23
|
+
| :-------------------------------- | :---------------------------------------------------------------------------------------------------- |
|
|
24
|
+
| **📊 BI & Dashboard Integration** | Connect Power BI, Tableau, Metabase, Grafana, or any Business Intelligence tool. |
|
|
25
|
+
| **🔗 Tool Centralization** | Organize external links and systems into a single, easily accessible module for your entire team. |
|
|
26
|
+
| **⚡ Zero-Config Installation** | The extension automatically creates all necessary collections and fields. Install and use in seconds! |
|
|
27
|
+
| **🔄 Navigation Persistence** | The module automatically saves and restores your last view, even after closing the browser. |
|
|
28
|
+
| **🌍 Multilingual Support** | Ready for global projects, with automatic translations for multiple languages. |
|
|
25
29
|
|
|
26
|
-
|
|
27
|
-
- ✅ `languages` collection for languages
|
|
28
|
-
- ✅ `inframe_translations` collection for translations
|
|
29
|
-
- ✅ Folder system for organization
|
|
30
|
-
- ✅ All fields and relations configured
|
|
30
|
+
---
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
## ✨ Exclusive Feature: Dynamic URL Variables
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
3. Done! Start using immediately
|
|
34
|
+
Take integration to the next level. inFrame allows you to inject user data and the current Directus context directly
|
|
35
|
+
into your iframe's URL. Perfect for authentication and report personalization.
|
|
37
36
|
|
|
38
|
-
###
|
|
37
|
+
### Available Variables
|
|
39
38
|
|
|
40
|
-
|
|
39
|
+
| Variable | Description | Usage Example |
|
|
40
|
+
| :------------ | :---------------------------------------------------------- | :---------------------------------------------- |
|
|
41
|
+
| `$token` | Directus access token (JWT). **(Use with extreme caution)** | `https://app.site.com/report?auth=$token` |
|
|
42
|
+
| `$user_id` | ID of the logged-in user. | `https://metabase.com/dash?user_id=$user_id` |
|
|
43
|
+
| `$user_email` | Email of the logged-in user. | `https://analytics.com/view?viewer=$user_email` |
|
|
44
|
+
| `$user_role` | Key of the user's role. | `https://app.site.com/access?role=$user_role` |
|
|
45
|
+
| `$timestamp` | Current timestamp (ISO 8601). | `https://app.site.com/log?time=$timestamp` |
|
|
46
|
+
| `$locale` | User's language preference (e.g., `en-US`). | `https://app.site.com/lang?locale=$locale` |
|
|
41
47
|
|
|
42
|
-
|
|
43
|
-
- 🔖 Restores state when returning to the module
|
|
44
|
-
- 🚀 Works even after closing/reopening browser
|
|
45
|
-
- ⚡ Zero performance impact
|
|
48
|
+
### ⚠️ Security: Responsible Use of `$token`
|
|
46
49
|
|
|
47
|
-
|
|
50
|
+
Using the `$token` exposes the Directus access token in the URL, which can be a security risk. **We strongly recommend
|
|
51
|
+
using `$user_id` or `$user_email` whenever possible.**
|
|
48
52
|
|
|
49
|
-
|
|
53
|
+
> [!WARNING] **Use `$token` ONLY with sites you fully trust and control.** The token can leak in server logs, browser
|
|
54
|
+
> history, and `Referer` headers. The extension will block the use of `$token` in URLs that do not use HTTPS.
|
|
50
55
|
|
|
51
|
-
|
|
52
|
-
npm install directus-extension-inframe
|
|
53
|
-
```
|
|
56
|
+
---
|
|
54
57
|
|
|
55
|
-
|
|
58
|
+
## 🛠️ Installation: Click & Go (Zero Config)
|
|
56
59
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
+
The inFrame module is designed for immediate use. Choose the installation method that suits your setup:
|
|
61
|
+
|
|
62
|
+
### 1. Directus Marketplace (Recommended)
|
|
63
|
+
|
|
64
|
+
The easiest way to install is directly through the Directus Admin App:
|
|
65
|
+
|
|
66
|
+
1. Navigate to **Settings** -> **Extensions**.
|
|
67
|
+
2. Find **"inFrame Module"** in the Marketplace.
|
|
68
|
+
3. Click **"Install"**.
|
|
69
|
+
4. Restart your Directus server (if self-hosted).
|
|
70
|
+
5. Done! The **"Reports"** module will appear in your sidebar.
|
|
60
71
|
|
|
61
|
-
###
|
|
72
|
+
### 2. Manual Installation (NPM/PNPM)
|
|
62
73
|
|
|
63
|
-
|
|
64
|
-
2. Access the admin panel
|
|
65
|
-
3. The "Reports" module will be available in the sidebar
|
|
74
|
+
For self-hosted environments or custom setups, you can install via your package manager:
|
|
66
75
|
|
|
67
|
-
|
|
76
|
+
```bash
|
|
77
|
+
# Using NPM
|
|
78
|
+
npm install directus-extension-inframe
|
|
79
|
+
|
|
80
|
+
# Using PNPM
|
|
81
|
+
pnpm add directus-extension-inframe
|
|
82
|
+
```
|
|
68
83
|
|
|
69
|
-
|
|
84
|
+
**Automatic Setup:** The extension automatically creates all necessary collections, fields, and relations upon
|
|
85
|
+
installation:
|
|
70
86
|
|
|
71
|
-
|
|
87
|
+
- ✅ `inframe` Collection to manage your content.
|
|
88
|
+
- ✅ Translation Collections (`languages`, `inframe_translations`).
|
|
89
|
+
- ✅ All required fields and relations configured.
|
|
72
90
|
|
|
73
|
-
|
|
91
|
+
---
|
|
74
92
|
|
|
75
|
-
|
|
76
|
-
2. Fill in the fields:
|
|
77
|
-
- **URL**: Link to the content to be displayed in the iframe
|
|
78
|
-
- **Status**: Published, Draft or Archived
|
|
79
|
-
- **Icon**: Choose a Material Design icon
|
|
80
|
-
- **Thumbnail**: Preview image (optional)
|
|
81
|
-
3. Add translations for different languages (optional)
|
|
82
|
-
4. Save
|
|
93
|
+
## 📖 How to Use
|
|
83
94
|
|
|
84
|
-
|
|
95
|
+
1. **Access the Module:** Click on **"Reports"** in the sidebar.
|
|
96
|
+
2. **Create a New Item:** Click "Create new" and fill in:
|
|
97
|
+
- **URL:** The link to the iframe content.
|
|
98
|
+
- **Status:** Published, Draft, or Archived.
|
|
99
|
+
- **Icon:** Choose a Material Design icon for the item.
|
|
100
|
+
3. **Save:** The content will be displayed in the iframe, ready for interaction.
|
|
85
101
|
|
|
86
|
-
|
|
102
|
+
---
|
|
87
103
|
|
|
88
|
-
## ⚙️
|
|
104
|
+
## ⚙️ Advanced Configuration (Docker)
|
|
89
105
|
|
|
90
|
-
If you
|
|
106
|
+
If you are using Docker, you may need to configure the Content Security Policy (CSP) to allow loading iframes from
|
|
107
|
+
external domains.
|
|
91
108
|
|
|
92
109
|
```yaml
|
|
93
110
|
environment:
|
|
94
|
-
|
|
111
|
+
# Add trusted domains to the frame-src directive
|
|
112
|
+
CONTENT_SECURITY_POLICY_DIRECTIVES__FRAME_SRC: "'self' https://your-bi-domain.com https://another-tool.com"
|
|
95
113
|
```
|
|
96
114
|
|
|
97
|
-
> [!
|
|
115
|
+
> [!CAUTION] Avoid using `'*'` in production. List only trusted domains.
|
|
98
116
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
- Configure CSP (Content Security Policy) properly
|
|
102
|
-
- List only trusted domains for iframes
|
|
103
|
-
- Use HTTPS in production
|
|
104
|
-
- Review user permissions in Directus
|
|
117
|
+
---
|
|
105
118
|
|
|
106
119
|
## 🌍 Compatibility
|
|
107
120
|
|
|
@@ -111,19 +124,10 @@ Tested and compatible with:
|
|
|
111
124
|
- **Directus 10.x**: 10.8.3
|
|
112
125
|
- **Directus 11.x**: 11.13.1 and newer versions
|
|
113
126
|
|
|
114
|
-
## 🐛 Known Issues
|
|
115
|
-
|
|
116
|
-
- Some websites block iframe display by policy (X-Frame-Options)
|
|
117
|
-
- HTTPS content cannot be displayed in HTTP Directus
|
|
118
|
-
|
|
119
127
|
## 🤝 Contributing
|
|
120
128
|
|
|
121
|
-
Contributions are welcome! See our [Contributing Guide](CONTRIBUTING.md) for details
|
|
122
|
-
|
|
123
|
-
- How to set up the development environment
|
|
124
|
-
- Running tests
|
|
125
|
-
- Submitting Pull Requests
|
|
126
|
-
- Code standards
|
|
129
|
+
Contributions are welcome! See our [Contributing Guide](CONTRIBUTING.md) for details on how to set up the development
|
|
130
|
+
environment, run tests, and submit Pull Requests.
|
|
127
131
|
|
|
128
132
|
## 📝 License
|
|
129
133
|
|
package/dist/app.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{useApi as n,defineModule as e}from"@directus/extensions-sdk";import{ref as t,defineComponent as a,resolveComponent as r,createElementBlock as i,openBlock as o,createElementVNode as d,Fragment as l,renderList as s,createVNode as c,withCtx as m,toDisplayString as u,watch as p,computed as g,onMounted as f,createBlock as v,createCommentVNode as h,normalizeStyle as b,createSlots as x}from"vue";import{useRouter as y,useRoute as w}from"vue-router";const k=async n=>(await n.get("/users/me")).data.data.language||"en-US",I=n=>n&&0!==n.length&&n[0]&&n[0].title?n[0].title:"Item inFrame",T=()=>{const e=t([]),a=t(!1),r=n();return{items:e,loading:a,fetchItems:async()=>{a.value=!0;try{const n=await k(r),t=await r.get("/items/inframe",{params:{fields:["id","sort","status","icon","url","thumbnail","translations.language","translations.title"],filter:{status:{_eq:"published"}},sort:["sort"]}}),a=Array.isArray(t.data)?t.data:t.data.data||[];e.value=a.map(e=>{if(e.translations&&e.translations.length>0){const t=e.translations.find(e=>e.language===n);t&&(e.translations=[t,...e.translations.filter(e=>e.language!==n)])}return e})}finally{a.value=!1}},getTitle:I}},_=()=>{const e=t(null),a=t(!1),r=n();return{item:e,loading:a,fetchItem:async n=>{if(n){a.value=!0;try{const t=await k(r),a=await r.get(`/items/inframe/${n}`,{params:{fields:["id","status","sort","icon","url","thumbnail","translations.language","translations.title"]}}),i=a.data.data||a.data;if(i.translations&&i.translations.length>0){const n=i.translations.find(n=>n.language===t);n&&(i.translations=[n,...i.translations.filter(n=>n.language!==t)])}e.value=i}finally{a.value=!1}}},getTitle:I}};var z=a({name:"NavMenu",props:{items:{type:Array,required:!0}},setup(){const{getTitle:n}=T();return{getTitle:n}}}),q=[],S=[];function A(n,e){if(n&&"undefined"!=typeof document){var t,a=!0===e.prepend?"prepend":"append",r=!0===e.singleTag,i="string"==typeof e.container?document.querySelector(e.container):document.getElementsByTagName("head")[0];if(r){var o=q.indexOf(i);-1===o&&(o=q.push(i)-1,S[o]={}),t=S[o]&&S[o][a]?S[o][a]:S[o][a]=d()}else t=d();65279===n.charCodeAt(0)&&(n=n.substring(1)),t.styleSheet?t.styleSheet.cssText+=n:t.appendChild(document.createTextNode(n))}function d(){var n=document.createElement("style");if(n.setAttribute("type","text/css"),e.attributes)for(var t=Object.keys(e.attributes),r=0;r<t.length;r++)n.setAttribute(t[r],e.attributes[t[r]]);var o="prepend"===a?"afterbegin":"beforeend";return i.insertAdjacentElement(o,n),n}}A("\n.nav-menu[data-v-33faf0a5] {\n margin-top: 20px;\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n}\n.menu-list[data-v-33faf0a5] {\n list-style: none;\n padding: 0;\n margin: 0;\n}\n.menu-item[data-v-33faf0a5] {\n margin-bottom: 8px;\n}\n.menu-link[data-v-33faf0a5] {\n display: flex;\n align-items: center;\n text-decoration: none;\n color: var(--theme--foreground-accent);\n font-size: 16px;\n padding: 12px 20px;\n transition:\n background-color 0.3s ease,\n color 0.3s ease;\n}\n.menu-link[data-v-33faf0a5]:hover {\n background-color: var(--theme--primary-light);\n color: var(--theme--primary);\n}\n.menu-link.active-link[data-v-33faf0a5] {\n background-color: var(--theme--primary);\n color: var(--white);\n font-weight: bold;\n}\n.menu-icon[data-v-33faf0a5] {\n margin-right: 10px;\n font-size: 20px;\n}\n.menu-link span[data-v-33faf0a5] {\n font-weight: 500;\n}\n",{});var C=(n,e)=>{const t=n.__vccOpts||n;for(const[n,a]of e)t[n]=a;return t};const R={class:"nav-menu"},j={class:"menu-list"},N={class:"menu-link-text"};var E=C(z,[["render",function(n,e,t,a,p,g){const f=r("v-icon"),v=r("router-link");return o(),i("nav",R,[d("ul",j,[(o(!0),i(l,null,s(n.items,e=>(o(),i("li",{key:e.id,class:"menu-item"},[c(v,{to:`/inframe/${e.id}`,class:"menu-link","active-class":"active-link"},{default:m(()=>[c(f,{class:"menu-icon",name:e.icon},null,8,["name"]),d("span",N,u(n.getTitle(e.translations)),1)]),_:2},1032,["to"])]))),128))])])}],["__scopeId","data-v-33faf0a5"]]);const M="directus_inframe_last_route",$="lastRoute",D=()=>{const n=y(),e=w(),a=t(!1);(()=>{try{const n=localStorage.getItem(M);"undefined"!==n&&"null"!==n&&""!==n||localStorage.removeItem(M)}catch{}})();const r=t=>{const a=t||e.params.id;if(a&&"undefined"!==a)try{localStorage.setItem(M,a);const t={...e.query};t[$]=a,n.replace({path:e.path,query:t}).catch(()=>{})}catch{}},i=()=>{try{const n=e.query[$];if(n&&"string"==typeof n&&"undefined"!==n)return n;const t=localStorage.getItem(M);if(t&&"undefined"!==t)return t;"undefined"===t&&localStorage.removeItem(M)}catch{}return null};return{saveCurrentRoute:r,getLastRoute:i,restoreLastRoute:async()=>{const e=i();if(!e||"undefined"===e)return!1;try{return a.value=!0,await n.push(`/inframe/${e}`),!0}catch{return!1}finally{a.value=!1}},clearSavedRoute:()=>{try{localStorage.removeItem(M);const t={...e.query};delete t[$],n.replace({path:e.path,query:t}).catch(()=>{})}catch{}},startAutoSave:()=>{p(()=>e.params.id,n=>{!a.value&&n&&r(n)},{immediate:!1})},isRestoringRoute:a}};var L=a({name:"InframeList",components:{NavMenu:E},setup(){const{items:n,loading:e,fetchItems:t,getTitle:a}=T(),r=y(),i=w(),{startAutoSave:o}=D(),d=g(()=>i.params.id);return f(async()=>{await t(),o()}),{items:n,loading:e,page_title:"Extra",getTitle:a,currentItemId:d,navigateToItem:n=>{r.push(`/inframe/${n}`)}}}});A("\n.container[data-v-2d557b14] {\n display: flex;\n flex-wrap: wrap;\n gap: 20px;\n padding: 20px 50px;\n}\n.card-container[data-v-2d557b14] {\n display: flex;\n flex-wrap: wrap;\n gap: 20px;\n width: 100%;\n}\n.card[data-v-2d557b14] {\n background-color: #ffffff;\n border-radius: 8px;\n box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);\n flex: 1 1 25%;\n height: 200px;\n display: flex;\n flex-direction: column; /* Para garantir que o conteúdo não sobreponha a imagem */\n justify-content: flex-end; /* Ajusta o conteúdo para o fundo */\n align-items: center;\n text-align: center;\n overflow: hidden;\n transition:\n transform 0.3s ease,\n box-shadow 0.3s ease;\n}\n.card[data-v-2d557b14]:hover {\n transform: translateY(-10px);\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);\n}\n.card-link[data-v-2d557b14] {\n display: flex;\n flex-direction: column;\n justify-content: flex-end; /* Coloca o conteúdo no fundo do link */\n align-items: center;\n height: 100%;\n text-decoration: none; /* Remove o estilo de link */\n background-size: cover;\n background-position: center;\n background-repeat: no-repeat;\n padding: 0;\n width: 100%;\n}\n.card-header h3[data-v-2d557b14] {\n margin: 0; /* Remove a margem para melhor controle de espaçamento */\n padding: 10px;\n background: var(--theme--primary);\n width: 100%;\n}\n.card-header[data-v-2d557b14] {\n background-color: var(--theme--primary-light);\n padding: 0;\n font-size: 18px;\n font-weight: bold;\n color: var(--white);\n width: 100%;\n}\n.card-body[data-v-2d557b14] {\n padding: 16px;\n font-size: 14px;\n color: var(--theme--foreground);\n}\n.card-body p[data-v-2d557b14] {\n margin: 0;\n}\n.empty-state[data-v-2d557b14] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 400px;\n color: var(--theme--foreground-subdued);\n text-align: center;\n gap: 1rem;\n}\n.empty-state h2[data-v-2d557b14] {\n margin: 0;\n font-size: 1.5rem;\n font-weight: 600;\n color: var(--theme--foreground);\n}\n.empty-state p[data-v-2d557b14] {\n margin: 0;\n font-size: 1rem;\n}\n.loading-state[data-v-2d557b14] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 400px;\n color: var(--theme--foreground-subdued);\n text-align: center;\n}\n.loading-state p[data-v-2d557b14] {\n margin: 0;\n font-size: 1.125rem;\n}\n.card-container[data-v-2d557b14] {\n display: flex;\n flex-wrap: wrap;\n gap: 20px;\n width: 100%;\n}\n.card[data-v-2d557b14] {\n background-color: #ffffff;\n border-radius: 8px;\n box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);\n flex: 1 1 25%;\n height: 200px;\n display: flex;\n flex-direction: column;\n justify-content: flex-end;\n align-items: center;\n text-align: center;\n overflow: hidden;\n transition:\n transform 0.3s ease,\n box-shadow 0.3s ease;\n cursor: pointer;\n}\n.card[data-v-2d557b14]:hover {\n transform: translateY(-10px);\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);\n}\n.card-link[data-v-2d557b14] {\n display: flex;\n flex-direction: column;\n justify-content: flex-end;\n align-items: center;\n height: 100%;\n text-decoration: none;\n background-size: cover;\n background-position: center;\n background-repeat: no-repeat;\n padding: 0;\n width: 100%;\n}\n.card-header h3[data-v-2d557b14] {\n margin: 0;\n padding: 10px;\n background: var(--theme--primary);\n width: 100%;\n}\n.card-header[data-v-2d557b14] {\n background-color: var(--theme--primary-light);\n padding: 0;\n font-size: 18px;\n font-weight: bold;\n color: var(--white);\n width: 100%;\n}\n.card-body[data-v-2d557b14] {\n padding: 16px;\n font-size: 14px;\n color: var(--theme--foreground);\n}\n.card-body p[data-v-2d557b14] {\n margin: 0;\n}\n",{});const O={class:"container"},U={key:0,class:"loading-state"},B={class:"empty-state"},Y={class:"card-container"},F=["onClick"],H={class:"card-header"};var P=C(L,[["render",function(n,e,t,a,p,g){const f=r("NavMenu"),x=r("v-icon"),y=r("router-view"),w=r("private-view");return o(),v(w,{title:n.page_title},{navigation:m(()=>[c(f,{items:n.items},null,8,["items"])]),default:m(()=>[d("div",O,[h(" Loading state "),n.loading?(o(),i("div",U,[...e[0]||(e[0]=[d("p",null,"Carregando...",-1)])])):0===n.items.length?(o(),i(l,{key:1},[h(" Mensagem quando não há itens (após carregar) "),d("div",B,[c(x,{name:"inbox",large:""}),e[1]||(e[1]=d("h2",null,"Nenhum item cadastrado",-1)),e[2]||(e[2]=d("p",null,"Crie um novo item na coleção inframe para começar.",-1))])],2112)):n.currentItemId?(o(),i(l,{key:3},[h(" O router-view vai renderizar o conteúdo quando há um item selecionado "),c(y)],2112)):(o(),i(l,{key:2},[h(" Lista de cards quando está na página inicial (sem ID na rota) "),d("div",Y,[(o(!0),i(l,null,s(n.items,e=>(o(),i("div",{key:e.id,class:"card",onClick:t=>n.navigateToItem(e.id)},[d("div",{class:"card-link",style:b(e.thumbnail?`background-image: url(http://localhost:8055/assets/${e.thumbnail})`:"")},[d("div",H,[d("h3",null,u(n.getTitle(e.translations)),1)])],4)],8,F))),128))])],2112))])]),_:1},8,["title"])}],["__scopeId","data-v-2d557b14"]]),V=a({name:"ItemDetail",components:{NavMenu:E},props:{item:{type:Object,required:!0},items:{type:Array,required:!0},loading:{type:Boolean,default:!1},title:{type:String,default:""}},setup:n=>({...n,breadcrumb:[{name:"Home",to:"/inframe"}],normalizeUrl:n=>n?n.match(/^https?:\/\//i)?n:`https://${n}`:""})});A("\n.header-bar[data-v-0ceec750] {\n display: none !important;\n}\n[data-v-0ceec750] .header-bar {\n display: none !important;\n}\n.container[data-v-0ceec750] {\n margin: 20px 50px;\n}\nh2[data-v-0ceec750] {\n color: var(--theme--foreground-accent);\n margin-bottom: 10px;\n}\np[data-v-0ceec750] {\n font-size: 16px;\n line-height: 1.5;\n color: var(--theme--foreground-accent);\n}\n.main[data-v-0ceec750] {\n position: relative;\n width: 100%;\n height: 100%;\n margin: 0;\n padding: 0;\n}\n.iframe-area[data-v-0ceec750] {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n margin: 0;\n padding: 0;\n overflow: hidden !important;\n}\niframe[data-v-0ceec750] {\n width: 100%;\n height: 100%;\n border: none;\n}\n",{});const G={class:"main"},J={key:0},K={key:1},Q={key:2},W={class:"iframe-area"},X=["src"],Z={key:3};var nn=a({name:"ItemDetailRoute",components:{ItemDetail:C(V,[["render",function(n,e,t,a,l,s){const u=r("v-breadcrumb"),p=r("NavMenu"),g=r("private-view");return o(),v(g,{title:n.title},x({navigation:m(()=>[c(p,{items:n.items},null,8,["items"])]),default:m(()=>[d("div",G,[n.loading?(o(),i("div",J,[...e[0]||(e[0]=[d("p",null,"Carregando...",-1)])])):n.item?n.item?(o(),i("div",Q,[d("div",W,[d("iframe",{src:n.normalizeUrl(n.item.url),frameborder:"0",sandbox:"allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowfullscreen:""},null,8,X)])])):(o(),i("div",Z,[...e[2]||(e[2]=[d("p",null,"Erro ao carregar dados. Tente novamente mais tarde.",-1)])])):(o(),i("div",K,[...e[1]||(e[1]=[d("p",null,"Nenhum item encontrado. Verifique se o item existe e está publicado.",-1)])]))])]),_:2},[n.breadcrumb.length>0?{name:"headline",fn:m(()=>[c(u,{items:n.breadcrumb},null,8,["items"])]),key:"0"}:void 0]),1032,["title"])}],["__scopeId","data-v-0ceec750"]])},setup(){const n=w(),{items:e,fetchItems:t,getTitle:a}=T(),{item:r,loading:i,fetchItem:o}=_(),{saveCurrentRoute:d,startAutoSave:l}=D();return f(async()=>{await t();const e=n.params.id;e&&(await o(e),d(e)),l()}),p(()=>n.params.id,async n=>{n&&(await o(n),d(n))}),{item:r,items:e,loading:i,getTitle:a}}});const en={key:1,class:"loading-state"},tn={key:2,class:"error-state"};const an=[],rn=[],on=[],dn=[e({id:"inframe",name:"Extra",icon:"tv_signin",routes:[{path:"",props:!0,component:P},{path:":id",component:C(nn,[["render",function(n,e,t,a,l,s){const c=r("ItemDetail");return n.item?(o(),v(c,{key:0,item:n.item,items:n.items,loading:n.loading,title:n.getTitle(n.item?.translations||[])},null,8,["item","items","loading","title"])):n.loading?(o(),i("div",en,[...e[0]||(e[0]=[d("p",null,"Carregando item...",-1)])])):(o(),i("div",tn,[...e[1]||(e[1]=[d("p",null,"Item não encontrado ou erro ao carregar.",-1)])]))}]]),props:!0}]})],ln=[],sn=[],cn=[];export{rn as displays,an as interfaces,on as layouts,dn as modules,cn as operations,ln as panels,sn as themes};
|
|
1
|
+
import{useApi as e,useStores as n,defineModule as t}from"@directus/extensions-sdk";import{ref as a,defineComponent as r,resolveComponent as o,createElementBlock as i,openBlock as s,createElementVNode as l,Fragment as d,renderList as c,createVNode as u,withCtx as m,toDisplayString as p,watch as g,computed as f,onMounted as v,createBlock as h,createCommentVNode as b,normalizeStyle as y,createSlots as x}from"vue";import{useRouter as w,useRoute as k}from"vue-router";const I=async e=>(await e.get("/users/me")).data.data.language||"en-US",_=e=>e&&0!==e.length&&e[0]&&e[0].title?e[0].title:"Item inFrame",R=()=>{const n=a([]),t=a(!1),r=e();return{items:n,loading:t,fetchItems:async()=>{t.value=!0;try{const e=await I(r),t=await r.get("/items/inframe",{params:{fields:["id","sort","status","icon","url","thumbnail","translations.language","translations.title"],filter:{status:{_eq:"published"}},sort:["sort"]}}),a=Array.isArray(t.data)?t.data:t.data.data||[];n.value=a.map(n=>{if(n.translations&&n.translations.length>0){const t=n.translations.find(n=>n.language===e);t&&(n.translations=[t,...n.translations.filter(n=>n.language!==e)])}return n})}finally{t.value=!1}},getTitle:_}},$=()=>{const n=a(null),t=a(!1),r=e();return{item:n,loading:t,fetchItem:async e=>{if(e){t.value=!0;try{const t=await I(r),a=await r.get(`/items/inframe/${e}`,{params:{fields:["id","status","sort","icon","url","thumbnail","translations.language","translations.title"]}}),o=a.data.data||a.data;if(o.translations&&o.translations.length>0){const e=o.translations.find(e=>e.language===t);e&&(o.translations=[e,...o.translations.filter(e=>e.language!==t)])}n.value=o}finally{t.value=!1}}},getTitle:_}};var S=r({name:"NavMenu",props:{items:{type:Array,required:!0}},setup(){const{getTitle:e}=R();return{getTitle:e}}}),U=[],T=[];function C(e,n){if(e&&"undefined"!=typeof document){var t,a=!0===n.prepend?"prepend":"append",r=!0===n.singleTag,o="string"==typeof n.container?document.querySelector(n.container):document.getElementsByTagName("head")[0];if(r){var i=U.indexOf(o);-1===i&&(i=U.push(o)-1,T[i]={}),t=T[i]&&T[i][a]?T[i][a]:T[i][a]=s()}else t=s();65279===e.charCodeAt(0)&&(e=e.substring(1)),t.styleSheet?t.styleSheet.cssText+=e:t.appendChild(document.createTextNode(e))}function s(){var e=document.createElement("style");if(e.setAttribute("type","text/css"),n.attributes)for(var t=Object.keys(n.attributes),r=0;r<t.length;r++)e.setAttribute(t[r],n.attributes[t[r]]);var i="prepend"===a?"afterbegin":"beforeend";return o.insertAdjacentElement(i,e),e}}C("\n.nav-menu[data-v-33faf0a5] {\n margin-top: 20px;\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n}\n.menu-list[data-v-33faf0a5] {\n list-style: none;\n padding: 0;\n margin: 0;\n}\n.menu-item[data-v-33faf0a5] {\n margin-bottom: 8px;\n}\n.menu-link[data-v-33faf0a5] {\n display: flex;\n align-items: center;\n text-decoration: none;\n color: var(--theme--foreground-accent);\n font-size: 16px;\n padding: 12px 20px;\n transition:\n background-color 0.3s ease,\n color 0.3s ease;\n}\n.menu-link[data-v-33faf0a5]:hover {\n background-color: var(--theme--primary-light);\n color: var(--theme--primary);\n}\n.menu-link.active-link[data-v-33faf0a5] {\n background-color: var(--theme--primary);\n color: var(--white);\n font-weight: bold;\n}\n.menu-icon[data-v-33faf0a5] {\n margin-right: 10px;\n font-size: 20px;\n}\n.menu-link span[data-v-33faf0a5] {\n font-weight: 500;\n}\n",{});var z=(e,n)=>{const t=e.__vccOpts||e;for(const[e,a]of n)t[e]=a;return t};const E={class:"nav-menu"},q={class:"menu-list"},A={class:"menu-link-text"};var j=z(S,[["render",function(e,n,t,a,r,g){const f=o("v-icon"),v=o("router-link");return s(),i("nav",E,[l("ul",q,[(s(!0),i(d,null,c(e.items,n=>(s(),i("li",{key:n.id,class:"menu-item"},[u(v,{to:`/inframe/${n.id}`,class:"menu-link","active-class":"active-link"},{default:m(()=>[u(f,{class:"menu-icon",name:n.icon},null,8,["name"]),l("span",A,p(e.getTitle(n.translations)),1)]),_:2},1032,["to"])]))),128))])])}],["__scopeId","data-v-33faf0a5"]]);const L="directus_inframe_last_route",F="lastRoute",N=()=>{const e=w(),n=k(),t=a(!1);(()=>{try{const e=localStorage.getItem(L);"undefined"!==e&&"null"!==e&&""!==e||localStorage.removeItem(L)}catch{}})();const r=t=>{const a=t||n.params.id;if(a&&"undefined"!==a)try{localStorage.setItem(L,a);const t={...n.query};t[F]=a,e.replace({path:n.path,query:t}).catch(()=>{})}catch{}},o=()=>{try{const e=n.query[F];if(e&&"string"==typeof e&&"undefined"!==e)return e;const t=localStorage.getItem(L);if(t&&"undefined"!==t)return t;"undefined"===t&&localStorage.removeItem(L)}catch{}return null};return{saveCurrentRoute:r,getLastRoute:o,restoreLastRoute:async()=>{const n=o();if(!n||"undefined"===n)return!1;try{return t.value=!0,await e.push(`/inframe/${n}`),!0}catch{return!1}finally{t.value=!1}},clearSavedRoute:()=>{try{localStorage.removeItem(L);const t={...n.query};delete t[F],e.replace({path:n.path,query:t}).catch(()=>{})}catch{}},startAutoSave:()=>{g(()=>n.params.id,e=>{!t.value&&e&&r(e)},{immediate:!1})},isRestoringRoute:t}};var D=r({name:"InframeList",components:{NavMenu:j},setup(){const{items:e,loading:n,fetchItems:t,getTitle:a}=R(),r=w(),o=k(),{startAutoSave:i}=N(),s=f(()=>o.params.id);return v(async()=>{await t(),i()}),{items:e,loading:n,page_title:"Extra",getTitle:a,currentItemId:s,navigateToItem:e=>{r.push(`/inframe/${e}`)}}}});C("\n.container[data-v-2d557b14] {\n display: flex;\n flex-wrap: wrap;\n gap: 20px;\n padding: 20px 50px;\n}\n.card-container[data-v-2d557b14] {\n display: flex;\n flex-wrap: wrap;\n gap: 20px;\n width: 100%;\n}\n.card[data-v-2d557b14] {\n background-color: #ffffff;\n border-radius: 8px;\n box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);\n flex: 1 1 25%;\n height: 200px;\n display: flex;\n flex-direction: column; /* Para garantir que o conteúdo não sobreponha a imagem */\n justify-content: flex-end; /* Ajusta o conteúdo para o fundo */\n align-items: center;\n text-align: center;\n overflow: hidden;\n transition:\n transform 0.3s ease,\n box-shadow 0.3s ease;\n}\n.card[data-v-2d557b14]:hover {\n transform: translateY(-10px);\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);\n}\n.card-link[data-v-2d557b14] {\n display: flex;\n flex-direction: column;\n justify-content: flex-end; /* Coloca o conteúdo no fundo do link */\n align-items: center;\n height: 100%;\n text-decoration: none; /* Remove o estilo de link */\n background-size: cover;\n background-position: center;\n background-repeat: no-repeat;\n padding: 0;\n width: 100%;\n}\n.card-header h3[data-v-2d557b14] {\n margin: 0; /* Remove a margem para melhor controle de espaçamento */\n padding: 10px;\n background: var(--theme--primary);\n width: 100%;\n}\n.card-header[data-v-2d557b14] {\n background-color: var(--theme--primary-light);\n padding: 0;\n font-size: 18px;\n font-weight: bold;\n color: var(--white);\n width: 100%;\n}\n.card-body[data-v-2d557b14] {\n padding: 16px;\n font-size: 14px;\n color: var(--theme--foreground);\n}\n.card-body p[data-v-2d557b14] {\n margin: 0;\n}\n.empty-state[data-v-2d557b14] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 400px;\n color: var(--theme--foreground-subdued);\n text-align: center;\n gap: 1rem;\n}\n.empty-state h2[data-v-2d557b14] {\n margin: 0;\n font-size: 1.5rem;\n font-weight: 600;\n color: var(--theme--foreground);\n}\n.empty-state p[data-v-2d557b14] {\n margin: 0;\n font-size: 1rem;\n}\n.loading-state[data-v-2d557b14] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 400px;\n color: var(--theme--foreground-subdued);\n text-align: center;\n}\n.loading-state p[data-v-2d557b14] {\n margin: 0;\n font-size: 1.125rem;\n}\n.card-container[data-v-2d557b14] {\n display: flex;\n flex-wrap: wrap;\n gap: 20px;\n width: 100%;\n}\n.card[data-v-2d557b14] {\n background-color: #ffffff;\n border-radius: 8px;\n box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);\n flex: 1 1 25%;\n height: 200px;\n display: flex;\n flex-direction: column;\n justify-content: flex-end;\n align-items: center;\n text-align: center;\n overflow: hidden;\n transition:\n transform 0.3s ease,\n box-shadow 0.3s ease;\n cursor: pointer;\n}\n.card[data-v-2d557b14]:hover {\n transform: translateY(-10px);\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);\n}\n.card-link[data-v-2d557b14] {\n display: flex;\n flex-direction: column;\n justify-content: flex-end;\n align-items: center;\n height: 100%;\n text-decoration: none;\n background-size: cover;\n background-position: center;\n background-repeat: no-repeat;\n padding: 0;\n width: 100%;\n}\n.card-header h3[data-v-2d557b14] {\n margin: 0;\n padding: 10px;\n background: var(--theme--primary);\n width: 100%;\n}\n.card-header[data-v-2d557b14] {\n background-color: var(--theme--primary-light);\n padding: 0;\n font-size: 18px;\n font-weight: bold;\n color: var(--white);\n width: 100%;\n}\n.card-body[data-v-2d557b14] {\n padding: 16px;\n font-size: 14px;\n color: var(--theme--foreground);\n}\n.card-body p[data-v-2d557b14] {\n margin: 0;\n}\n",{});const O={class:"container"},M={key:0,class:"loading-state"},P={class:"empty-state"},V={class:"card-container"},Y=["onClick"],H={class:"card-header"};var B=z(D,[["render",function(e,n,t,a,r,g){const f=o("NavMenu"),v=o("v-icon"),x=o("router-view"),w=o("private-view");return s(),h(w,{title:e.page_title},{navigation:m(()=>[u(f,{items:e.items},null,8,["items"])]),default:m(()=>[l("div",O,[b(" Loading state "),e.loading?(s(),i("div",M,[...n[0]||(n[0]=[l("p",null,"Carregando...",-1)])])):0===e.items.length?(s(),i(d,{key:1},[b(" Mensagem quando não há itens (após carregar) "),l("div",P,[u(v,{name:"inbox",large:""}),n[1]||(n[1]=l("h2",null,"Nenhum item cadastrado",-1)),n[2]||(n[2]=l("p",null,"Crie um novo item na coleção inframe para começar.",-1))])],2112)):e.currentItemId?(s(),i(d,{key:3},[b(" O router-view vai renderizar o conteúdo quando há um item selecionado "),u(x)],2112)):(s(),i(d,{key:2},[b(" Lista de cards quando está na página inicial (sem ID na rota) "),l("div",V,[(s(!0),i(d,null,c(e.items,n=>(s(),i("div",{key:n.id,class:"card",onClick:t=>e.navigateToItem(n.id)},[l("div",{class:"card-link",style:y(n.thumbnail?`background-image: url(http://localhost:8055/assets/${n.thumbnail})`:"")},[l("div",H,[l("h3",null,p(e.getTitle(n.translations)),1)])],4)],8,Y))),128))])],2112))])]),_:1},8,["title"])}],["__scopeId","data-v-2d557b14"]]);var W=r({name:"ItemDetail",components:{NavMenu:j},props:{item:{type:Object,required:!0},items:{type:Array,required:!0},loading:{type:Boolean,default:!1},title:{type:String,default:""}},setup(t){const r=[{name:"Home",to:"/inframe"}],o=a(""),i=a(!1),s=a(null),{processUrl:l}=(()=>{const t=e(),r=a(null),o=a(""),i=a(!1),s=a(null),l=async()=>{try{const e=await t.get("/users/me",{params:{fields:["id","email","first_name","last_name","role","language"]}}),n=e.data?.data||e.data;return r.value={id:n.id||"",email:n.email||"",first_name:n.first_name||"",last_name:n.last_name||"",role:n.role||"",language:n.language||"en-US"},r.value}catch(e){return s.value=`Failed to fetch user data: ${e.message}`,console.error("[inFrame Security]",s.value),null}},d=()=>{try{const{useUserStore:e}=n(),t=e();if(t&&t.currentUser)return o.value=t.accessToken||"",o.value;const a=localStorage.getItem("directus_token")||"";return o.value=a,a}catch(e){return console.error("[inFrame Security] Failed to get access token:",e.message),""}},c=e=>{const n={isValid:!0,errors:[],warnings:[]};if(e.includes("$token")||e.includes("$refresh_token")){if(!e.match(/\$token/)&&!e.match(/\$refresh_token/))return n;const t=e.split("?"),a=t.length>0?t[0]:e;a&&!a.startsWith("https://")&&(n.isValid=!1,n.errors.push("🔒 SECURITY ERROR: $token variable can only be used with HTTPS URLs. HTTP is not allowed.")),n.warnings.push("⚠️ WARNING: You are using $token in the URL. The token will be exposed in server logs, browser history, and referrer headers."),n.warnings.push("⚠️ Only use this with fully trusted external sites. Consider using a backend proxy for better security.")}return n},u=(e,n,t)=>{if(!e)return"";let a=e;t&&e.includes("$token")&&(a=a.replace(/\$token/g,encodeURIComponent(t))),n&&(a=a.replace(/\$user_id/g,encodeURIComponent(n.id)).replace(/\$user_email/g,encodeURIComponent(n.email)).replace(/\$user_first_name/g,encodeURIComponent(n.first_name)).replace(/\$user_last_name/g,encodeURIComponent(n.last_name)).replace(/\$user_name/g,encodeURIComponent(`${n.first_name} ${n.last_name}`)).replace(/\$user_role/g,encodeURIComponent(n.role)).replace(/\$locale/g,encodeURIComponent(n.language)));const r=(new Date).toISOString();return a=a.replace(/\$timestamp/g,encodeURIComponent(r)),a};return{processUrl:async e=>{if(!e)return"";i.value=!0,s.value=null;try{const n=c(e);if(n.warnings.length>0&&n.warnings.forEach(e=>{console.warn("[inFrame Security]",e)}),!n.isValid)throw n.errors.forEach(e=>{console.error("[inFrame Security]",e)}),s.value=n.errors.join("\n"),new Error(n.errors.join("\n"));if(!e.match(/\$\w+/))return e;const t=await l();t||console.warn("[inFrame] Failed to fetch user data, some variables may not be replaced");const a=e.includes("$token")?d():"",r=u(e,t,a);return e.includes("$token")?console.info("[inFrame] URL processed with token variable (not logging full URL for security)"):console.info("[inFrame] URL processed:",r),r}catch(e){throw s.value=e.message,console.error("[inFrame] Error processing URL:",e),e}finally{i.value=!1}},getUserData:l,getAccessToken:d,validateUrlSecurity:c,replaceVariables:u,userData:r,accessToken:o,loading:i,error:s}})(),d=async e=>{if(e){i.value=!0,s.value=null;try{const n=(e=>e?e.match(/^https?:\/\//i)?e:`https://${e}`:"")(e),t=await l(n);o.value=t}catch(e){s.value=e.message||"Erro ao processar URL",o.value=""}finally{i.value=!1}}else o.value=""};return v(()=>{t.item?.url&&d(t.item.url)}),g(()=>t.item?.url,e=>{e&&d(e)}),{...t,breadcrumb:r,processedUrl:o,urlProcessing:i,urlError:s}}});C("\n.header-bar[data-v-f3075c8b] {\n display: none !important;\n}\n[data-v-f3075c8b] .header-bar {\n display: none !important;\n}\n.container[data-v-f3075c8b] {\n margin: 20px 50px;\n}\nh2[data-v-f3075c8b] {\n color: var(--theme--foreground-accent);\n margin-bottom: 10px;\n}\np[data-v-f3075c8b] {\n font-size: 16px;\n line-height: 1.5;\n color: var(--theme--foreground-accent);\n}\n.main[data-v-f3075c8b] {\n position: relative;\n width: 100%;\n height: 100%;\n margin: 0;\n padding: 0;\n}\n.iframe-area[data-v-f3075c8b] {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n margin: 0;\n padding: 0;\n overflow: hidden !important;\n}\niframe[data-v-f3075c8b] {\n width: 100%;\n height: 100%;\n border: none;\n}\n.error-state[data-v-f3075c8b] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 400px;\n color: var(--theme--danger);\n text-align: center;\n gap: 1rem;\n padding: 2rem;\n}\n.error-state h2[data-v-f3075c8b] {\n margin: 0;\n font-size: 1.5rem;\n font-weight: 600;\n}\n.error-state p[data-v-f3075c8b] {\n margin: 0;\n font-size: 1rem;\n max-width: 600px;\n}\n.error-state .help-text[data-v-f3075c8b] {\n color: var(--theme--foreground-subdued);\n font-size: 0.875rem;\n}\n",{});const G={class:"main"},J={key:0},K={key:1,class:"error-state"},Q={style:{"white-space":"pre-line"}},X={key:2},Z={key:3},ee={class:"iframe-area"},ne=["src"],te={key:4};var ae=r({name:"ItemDetailRoute",components:{ItemDetail:z(W,[["render",function(e,n,t,a,r,d){const c=o("v-breadcrumb"),g=o("NavMenu"),f=o("v-icon"),v=o("private-view");return s(),h(v,{title:e.title},x({navigation:m(()=>[u(g,{items:e.items},null,8,["items"])]),default:m(()=>[l("div",G,[e.loading||e.urlProcessing?(s(),i("div",J,[...n[0]||(n[0]=[l("p",null,"Carregando...",-1)])])):e.urlError?(s(),i("div",K,[u(f,{name:"error",large:""}),n[1]||(n[1]=l("h2",null,"Erro de Segurança",-1)),l("p",Q,p(e.urlError),1),n[2]||(n[2]=l("p",{class:"help-text"}," Para usar variáveis como $token, a URL deve começar com https:// para garantir a segurança dos dados. ",-1))])):e.item?e.item?(s(),i("div",Z,[l("div",ee,[l("iframe",{src:e.processedUrl,frameborder:"0",sandbox:"allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowfullscreen:""},null,8,ne)])])):(s(),i("div",te,[...n[4]||(n[4]=[l("p",null,"Erro ao carregar dados. Tente novamente mais tarde.",-1)])])):(s(),i("div",X,[...n[3]||(n[3]=[l("p",null,"Nenhum item encontrado. Verifique se o item existe e está publicado.",-1)])]))])]),_:2},[e.breadcrumb.length>0?{name:"headline",fn:m(()=>[u(c,{items:e.breadcrumb},null,8,["items"])]),key:"0"}:void 0]),1032,["title"])}],["__scopeId","data-v-f3075c8b"]])},setup(){const e=k(),{items:n,fetchItems:t,getTitle:a}=R(),{item:r,loading:o,fetchItem:i}=$(),{saveCurrentRoute:s,startAutoSave:l}=N();return v(async()=>{await t();const n=e.params.id;n&&(await i(n),s(n)),l()}),g(()=>e.params.id,async e=>{e&&(await i(e),s(e))}),{item:r,items:n,loading:o,getTitle:a}}});const re={key:1,class:"loading-state"},oe={key:2,class:"error-state"};const ie=[],se=[],le=[],de=[t({id:"inframe",name:"Extra",icon:"tv_signin",routes:[{path:"",props:!0,component:B},{path:":id",component:z(ae,[["render",function(e,n,t,a,r,d){const c=o("ItemDetail");return e.item?(s(),h(c,{key:0,item:e.item,items:e.items,loading:e.loading,title:e.getTitle(e.item?.translations||[])},null,8,["item","items","loading","title"])):e.loading?(s(),i("div",re,[...n[0]||(n[0]=[l("p",null,"Carregando item...",-1)])])):(s(),i("div",oe,[...n[1]||(n[1]=[l("p",null,"Item não encontrado ou erro ao carregar.",-1)])]))}]]),props:!0}]})],ce=[],ue=[],me=[];export{se as displays,ie as interfaces,le as layouts,de as modules,me as operations,ce as panels,ue as themes};
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "directus-extension-inframe",
|
|
3
|
+
"type": "module",
|
|
3
4
|
"description": "Display dashboards, reports and external sites in iframes, directly in your Directus panel. Install, configure and centralize everything in one place!",
|
|
4
5
|
"icon": "web_asset",
|
|
5
|
-
"type": "module",
|
|
6
6
|
"private": false,
|
|
7
|
-
"version": "2.0
|
|
7
|
+
"version": "2.1.0",
|
|
8
8
|
"keywords": [
|
|
9
9
|
"directus",
|
|
10
10
|
"directus-extension",
|
|
@@ -48,37 +48,60 @@
|
|
|
48
48
|
"type": "git",
|
|
49
49
|
"url": "git+https://github.com/devix-tecnologia/directus-extension-inframe.git"
|
|
50
50
|
},
|
|
51
|
+
"scripts": {
|
|
52
|
+
"build": "directus-extension build",
|
|
53
|
+
"dev": "directus-extension build -w --no-minify",
|
|
54
|
+
"link": "directus-extension link",
|
|
55
|
+
"validate": "directus-extension validate",
|
|
56
|
+
"lint": "eslint . --ext .ts,.vue",
|
|
57
|
+
"lint:fix": "eslint . --ext .ts,.vue --fix",
|
|
58
|
+
"format": "prettier --write .",
|
|
59
|
+
"format:check": "prettier --check .",
|
|
60
|
+
"typecheck": "tsc --noEmit",
|
|
61
|
+
"test": "pnpm test:e2e",
|
|
62
|
+
"test:integration": "vitest run tests/*.spec.ts",
|
|
63
|
+
"test:watch": "vitest",
|
|
64
|
+
"test:coverage": "vitest run --coverage",
|
|
65
|
+
"test:e2e": "VERBOSE=true node tests/run-e2e.js",
|
|
66
|
+
"test:e2e:ui": "VERBOSE=true node tests/run-e2e.js --ui",
|
|
67
|
+
"test:e2e:debug": "playwright test --debug",
|
|
68
|
+
"test:e2e:headed": "playwright test --headed",
|
|
69
|
+
"test:e2e:report": "playwright show-report",
|
|
70
|
+
"semantic-release": "semantic-release"
|
|
71
|
+
},
|
|
51
72
|
"devDependencies": {
|
|
52
|
-
"@directus/extensions-sdk": "^17.0.
|
|
53
|
-
"@eslint/js": "9.39.
|
|
73
|
+
"@directus/extensions-sdk": "^17.0.4",
|
|
74
|
+
"@eslint/js": "9.39.2",
|
|
54
75
|
"@playwright/test": "^1.57.0",
|
|
55
76
|
"@semantic-release/git": "^10.0.1",
|
|
56
77
|
"@semantic-release/github": "^12.0.2",
|
|
57
|
-
"@semantic-release/npm": "^13.1.
|
|
58
|
-
"@types/node": "^
|
|
78
|
+
"@semantic-release/npm": "^13.1.3",
|
|
79
|
+
"@types/node": "^25.0.3",
|
|
59
80
|
"axios": "^1.13.2",
|
|
60
81
|
"dotenv": "^17.2.3",
|
|
61
|
-
"eslint": "9.39.
|
|
82
|
+
"eslint": "9.39.2",
|
|
62
83
|
"eslint-config-prettier": "10.1.8",
|
|
63
|
-
"eslint-plugin-vue": "10.6.
|
|
84
|
+
"eslint-plugin-vue": "10.6.2",
|
|
64
85
|
"globals": "^16.5.0",
|
|
65
86
|
"playwright": "^1.57.0",
|
|
66
|
-
"prettier": "3.
|
|
67
|
-
"rollup": "^4.
|
|
87
|
+
"prettier": "3.7.4",
|
|
88
|
+
"rollup": "^4.54.0",
|
|
68
89
|
"semantic-release": "^25.0.2",
|
|
90
|
+
"taskin": "^2.3.1",
|
|
69
91
|
"typescript": "^5.9.3",
|
|
70
|
-
"typescript-eslint": "8.
|
|
71
|
-
"vite": "^7.
|
|
72
|
-
"vitest": "^4.0.
|
|
73
|
-
"vue": "^3.5.
|
|
92
|
+
"typescript-eslint": "8.50.0",
|
|
93
|
+
"vite": "^7.3.0",
|
|
94
|
+
"vitest": "^4.0.16",
|
|
95
|
+
"vue": "^3.5.26",
|
|
74
96
|
"vue-eslint-parser": "^10.2.0"
|
|
75
97
|
},
|
|
76
98
|
"dependencies": {
|
|
77
99
|
"vue-router": "^4.6.3"
|
|
78
100
|
},
|
|
101
|
+
"packageManager": "pnpm@10.28.2",
|
|
79
102
|
"engines": {
|
|
80
103
|
"node": "22",
|
|
81
|
-
"pnpm": "10.
|
|
104
|
+
"pnpm": "10.28.2"
|
|
82
105
|
},
|
|
83
106
|
"author": "Devix Tecnologia",
|
|
84
107
|
"contributors": [
|
|
@@ -97,25 +120,5 @@
|
|
|
97
120
|
"bugs": {
|
|
98
121
|
"url": "https://github.com/devix-tecnologia/directus-extension-inframe/issues"
|
|
99
122
|
},
|
|
100
|
-
"homepage": "https://github.com/devix-tecnologia/directus-extension-inframe#readme"
|
|
101
|
-
|
|
102
|
-
"build": "directus-extension build",
|
|
103
|
-
"dev": "directus-extension build -w --no-minify",
|
|
104
|
-
"link": "directus-extension link",
|
|
105
|
-
"validate": "directus-extension validate",
|
|
106
|
-
"lint": "eslint . --ext .ts,.vue",
|
|
107
|
-
"lint:fix": "eslint . --ext .ts,.vue --fix",
|
|
108
|
-
"format": "prettier --write .",
|
|
109
|
-
"format:check": "prettier --check .",
|
|
110
|
-
"test": "pnpm test:e2e",
|
|
111
|
-
"test:integration": "vitest run tests/*.spec.ts",
|
|
112
|
-
"test:watch": "vitest",
|
|
113
|
-
"test:coverage": "vitest run --coverage",
|
|
114
|
-
"test:e2e": "playwright test",
|
|
115
|
-
"test:e2e:ui": "playwright test --ui",
|
|
116
|
-
"test:e2e:debug": "playwright test --debug",
|
|
117
|
-
"test:e2e:headed": "playwright test --headed",
|
|
118
|
-
"test:e2e:report": "playwright show-report",
|
|
119
|
-
"semantic-release": "semantic-release"
|
|
120
|
-
}
|
|
121
|
-
}
|
|
123
|
+
"homepage": "https://github.com/devix-tecnologia/directus-extension-inframe#readme"
|
|
124
|
+
}
|