directus-extension-inframe 1.0.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.
Files changed (3) hide show
  1. package/README.md +29 -0
  2. package/dist/index.js +1 -0
  3. package/package.json +57 -0
package/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Directus - Extensão Module inFrame
2
+
3
+ Este projeto é uma extensão do tipo Module para o Directus voltada para visualização de conteúdo em iframes.
4
+
5
+ ## 💎 Usando a extensão
6
+
7
+ - Ative o novo módulo na página de configurações do Directus;
8
+ - Crie uma nova Coleção com nome de `inframe` e adicione os seguintes campos:
9
+ ` "id", "sort", "status", "icon", "url", "thumbnail", "translations.languages_code", "translations.title"`;
10
+
11
+ - [Veja mais sobre traduções aqui](https://docs.directus.io/guides/headless-cms/content-translations.html)
12
+
13
+ ![Tela de visualização da extensão](docs/tela.jpg)
14
+
15
+ ## 🚀 Levantando um Directus a partir de docker-compose
16
+
17
+ - Baixe este projeto ou copie o arquivo `docker-compose.yml` e inicie uma instalação do zero;
18
+ - Com o docker instalado na máquina ([saiba mais](https://docs.docker.com/get-docker/)), rode o comando:
19
+
20
+ ```
21
+ docker compose up
22
+ ```
23
+
24
+ > [!IMPORTANT] _O docker-compose usado neste projeto está configurado para permitir iframe de qualquer domínio. Em
25
+ > produção você deve liberar apenas domínios confiáveis."_
26
+
27
+ ```yaml
28
+ CONTENT_SECURITY_POLICY_DIRECTIVES__FRAME_SRC: '*' # permite iframe de qualquer domínio
29
+ ```
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ import{useApi as e,defineModule as n}from"@directus/extensions-sdk";import{ref as t,defineComponent as a,onMounted as i,resolveComponent as r,openBlock as o,createElementBlock as d,createElementVNode as s,Fragment as l,renderList as c,createCommentVNode as u,createVNode as m,withCtx as p,toDisplayString as f,createBlock as g,watch as v}from"vue";import{useRouter as h}from"vue-router";const b=async e=>{try{return(await e.get("/users/me")).data.data.language||"en-US"}catch(e){return"en-US"}},x=e=>e&&0!==e.length&&e[0]&&e[0].title||"Item inFrame",y=()=>{const n=t([]),a=t(!1),i=e();return{items:n,loading:a,fetchItems:async()=>{a.value=!0;try{const e=await b(i),t=await i.get("/items/inframe",{params:{fields:["id","sort","status","icon","url","thumbnail","translations.languages_code","translations.title"],deep:{translations:{_filter:{languages_code:{_eq:e}}}},filter:{status:{_eq:"published"}},sort:["sort"]}});n.value=t.data.data}finally{a.value=!1}},getTitle:x}},w=()=>{const n=t(null),a=t(!1),i=e();return{item:n,loading:a,fetchItem:async e=>{if(e){a.value=!0;try{const t=await b(i),a=await i.get(`/items/inframe/${e}`,{params:{fields:["id","status","sort","icon","url","thumbnail","translations.languages_code","translations.title"],deep:{translations:{_filter:{languages_code:{_eq:t}}}},filter:{status:{_eq:"published"}}}});n.value=a.data.data}finally{a.value=!1}}},getTitle:x}};var _=a({name:"NavMenu",setup(){const{items:e,fetchItems:n,getTitle:t}=y();return i((()=>{n()})),{items:()=>{if(!e.value||0===e.value.length)return[];const n=e.value.find((e=>"published"===e.status)),t=e.value.filter((e=>"published"!==e.status));return n?[n,...t]:[...t]},getTitle:t}}}),k=[],T=[];function I(e,n){if(e&&"undefined"!=typeof document){var t,a=!0===n.prepend?"prepend":"append",i=!0===n.singleTag,r="string"==typeof n.container?document.querySelector(n.container):document.getElementsByTagName("head")[0];if(i){var o=k.indexOf(r);-1===o&&(o=k.push(r)-1,T[o]={}),t=T[o]&&T[o][a]?T[o][a]:T[o][a]=d()}else t=d();65279===e.charCodeAt(0)&&(e=e.substring(1)),t.styleSheet?t.styleSheet.cssText+=e:t.appendChild(document.createTextNode(e))}function d(){var e=document.createElement("style");if(e.setAttribute("type","text/css"),n.attributes)for(var t=Object.keys(n.attributes),i=0;i<t.length;i++)e.setAttribute(t[i],n.attributes[t[i]]);var o="prepend"===a?"afterbegin":"beforeend";return r.insertAdjacentElement(o,e),e}}I("\n.nav-menu[data-v-23d1e69d] {\n margin-top: 20px;\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n}\n.menu-list[data-v-23d1e69d] {\n list-style: none;\n padding: 0;\n margin: 0;\n}\n.menu-item[data-v-23d1e69d] {\n margin-bottom: 8px;\n}\n.menu-link[data-v-23d1e69d] {\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-23d1e69d]:hover {\n background-color: var(--theme--primary-light);\n color: var(--theme--primary);\n}\n.menu-link.active-link[data-v-23d1e69d] {\n background-color: var(--theme--primary);\n color: var(--white);\n font-weight: bold;\n}\n.menu-icon[data-v-23d1e69d] {\n margin-right: 10px;\n font-size: 20px;\n}\n.menu-link span[data-v-23d1e69d] {\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 N={class:"nav-menu"},q={class:"menu-list"},M={class:"menu-link-text"};var O=z(_,[["render",function(e,n,t,a,i,g){const v=r("v-icon"),h=r("router-link");return o(),d("nav",N,[s("ul",q,[(o(!0),d(l,null,c(e.items(),(n=>(o(),d("li",{key:n.id,class:"menu-item"},[u(" Ícones de Material Design "),m(h,{to:`/inframe/${n.id}`,class:"menu-link","active-class":"active-link"},{default:p((()=>[m(v,{class:"menu-icon",name:n.icon},null,8,["name"]),s("span",M,f(e.getTitle(n.translations)),1)])),_:2},1032,["to"])])))),128))])])}],["__scopeId","data-v-23d1e69d"],["__file","NavMenu.vue"]]),S=a({name:"InframeList",components:{NavMenu:O},setup(){const{items:e,fetchItems:n,getTitle:t}=y(),a=h();return i((async()=>{if(await n(),e.value&&e.value.length>0&&!e.value[0]){const n=e.value[0];n&&a.push(`/inframe/${n.id}`)}})),{items:e,page_title:"Organograma",getTitle:t}}});I("\n.container[data-v-bf819e72] {\n display: flex;\n flex-wrap: wrap;\n gap: 20px;\n padding: 20px 50px;\n}\n.card-container[data-v-bf819e72] {\n display: flex;\n flex-wrap: wrap;\n gap: 20px;\n width: 100%;\n}\n.card[data-v-bf819e72] {\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-bf819e72]:hover {\n transform: translateY(-10px);\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);\n}\n.card-link[data-v-bf819e72] {\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-bf819e72] {\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-bf819e72] {\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-bf819e72] {\n padding: 16px;\n font-size: 14px;\n color: var(--theme--foreground);\n}\n.card-body p[data-v-bf819e72] {\n margin: 0;\n}\n",{});const j={class:"container"};var A=z(S,[["render",function(e,n,t,a,i,d){const l=r("NavMenu"),c=r("router-view"),f=r("private-view");return o(),g(f,{title:e.page_title},{navigation:p((()=>[m(l)])),default:p((()=>[s("div",j,[u(" O router-view vai renderizar o conteúdo do primeiro item automaticamente "),m(c)])])),_:1},8,["title"])}],["__scopeId","data-v-bf819e72"],["__file","List.vue"]]),C=a({name:"ItemDetail",components:{NavMenu:O},props:{id:{type:String,required:!0}},setup(e){const n=[{name:"Home",to:"/inframe"}],{item:t,loading:a,fetchItem:r,getTitle:o}=w();return i((()=>{r(e.id)})),v((()=>e.id),(e=>{r(e)})),{item:t,loading:a,breadcrumb:n,getTitle:o}}});I("\n.header-bar[data-v-8f6ca5ec] {\n display: none !important;\n}\n[data-v-8f6ca5ec] .header-bar {\n display: none !important;\n}\n.container[data-v-8f6ca5ec] {\n margin: 20px 50px;\n}\nh2[data-v-8f6ca5ec] {\n color: var(--theme--foreground-accent);\n margin-bottom: 10px;\n}\np[data-v-8f6ca5ec] {\n font-size: 16px;\n line-height: 1.5;\n color: var(--theme--foreground-accent);\n}\n.main[data-v-8f6ca5ec] {\n position: relative;\n width: 100%;\n height: 100%;\n margin: 0;\n padding: 0;\n}\n.iframe-area[data-v-8f6ca5ec] {\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-8f6ca5ec] {\n width: 100%;\n height: 100%;\n border: none;\n}\n",{});const E={class:"main"},D={key:0},$={key:1},L={class:"iframe-area"},R=["src"],U={key:2};var B=n({id:"inframe",name:"Organograma",icon:"account_tree",routes:[{path:"",props:!0,component:A},{path:":id",component:z(C,[["render",function(e,n,t,a,i,l){const c=r("NavMenu"),f=r("private-view");return e.item?(o(),g(f,{key:0,title:e.getTitle(e.item.translations)},{navigation:p((()=>[m(c)])),default:p((()=>[s("div",E,[e.loading?(o(),d("div",D,n[0]||(n[0]=[s("p",null,"Carregando...",-1)]))):e.item?(o(),d("div",$,[s("div",L,[s("iframe",{src:e.item.url,frameborder:"0",sandbox:"allow-scripts allow-same-origin"},null,8,R)])])):(o(),d("div",U,n[1]||(n[1]=[s("p",null,"Erro ao carregar os dados. Tente novamente mais tarde.",-1)])))])])),_:1},8,["title"])):u("v-if",!0)}],["__scopeId","data-v-8f6ca5ec"],["__file","ItemDetail.vue"]]),props:!0}]});export{B as default};
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "directus-extension-inframe",
3
+ "description": "Extensão para módulo de visualização de conteúdo em iframes",
4
+ "icon": "extension",
5
+ "version": "1.0.0",
6
+ "keywords": [
7
+ "directus",
8
+ "directus-extension",
9
+ "directus-extension-module"
10
+ ],
11
+ "type": "module",
12
+ "files": [
13
+ "dist"
14
+ ],
15
+ "directus:extension": {
16
+ "type": "module",
17
+ "path": "dist/index.js",
18
+ "source": "src/index.ts",
19
+ "host": "^10.10.0"
20
+ },
21
+ "devDependencies": {
22
+ "@directus/extensions-sdk": "^13.1.1",
23
+ "@eslint/js": "9.28.0",
24
+ "eslint": "9.28.0",
25
+ "eslint-config-prettier": "10.1.5",
26
+ "eslint-plugin-vue": "10.1.0",
27
+ "globals": "^16.2.0",
28
+ "prettier": "3.5.3",
29
+ "rollup": "^2.79.1",
30
+ "typescript": "^5.8.3",
31
+ "typescript-eslint": "8.33.0",
32
+ "vue": "^3.5.16",
33
+ "vue-eslint-parser": "^10.0.0"
34
+ },
35
+ "dependencies": {
36
+ "vue-router": "^4.5.1"
37
+ },
38
+ "engines": {
39
+ "node": "22",
40
+ "pnpm": "9"
41
+ },
42
+ "author": "Devix Tecnologia",
43
+ "license": "GPL-3.0",
44
+ "bugs": {
45
+ "url": "https://github.com/utomic-media/directus-extension-field-actions/issues"
46
+ },
47
+ "homepage": "https://github.com/devix-tecnologia/directus-extension-inframe#readme",
48
+ "scripts": {
49
+ "build": "directus-extension build",
50
+ "dev": "directus-extension build -w --no-minify",
51
+ "link": "directus-extension link",
52
+ "lint": "eslint . --ext .ts,.vue",
53
+ "lint:fix": "eslint . --ext .ts,.vue --fix",
54
+ "format": "prettier --write .",
55
+ "format:check": "prettier --check ."
56
+ }
57
+ }