diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d31299..10c80c7 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,39 +4,62 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## 5.1.0 - 2023-12-01 + +### Added + +- Support for Assets + ## 5.0.1 - 2023-11-22 + ### Changed -- Changed the handling of the document deletion for mutli sites + +- Changed the handling of the document deletion for mutli sites ## 5.0.0 - 2023-03-13 / Official release + ### Added -- Docs for the official release -- Seperate typesense logging + +- Docs for the official release +- Seperate typesense logging ### Changed -- Move the deletion of the collection into the sync if it's a flush #7 + +- Move the deletion of the collection into the sync if it's a flush #7 ## 4.0.2 - 2022-11-04 + ### Added -- Added the possibility to handle save for all the types inside of the section + +- Added the possibility to handle save for all the types inside of the section ## 4.0.1 - 2022-10-25 + ### Fix -- Fixed: the project rebuild command was failing because of project config settings, these were disabled since we don't use them yet + +- Fixed: the project rebuild command was failing because of project config settings, these were disabled since we don't use them yet ## 4.0.0 - 2022-10-06 + ### Added -- Added: A sync console command + +- Added: A sync console command ## 4.0.0-beta.3 - 2022-09-19 + ### Changed -- Changed: disabled the before routing fetch to check for scheduled posts + +- Changed: disabled the before routing fetch to check for scheduled posts ## 4.0.0-beta.2 - 2022-09-19 + ### Added -- Added: Delete the document when setting an enabled entry to disable [#6](https://github.com/percipioglobal/craft-typesense/issues/6) -- Added: Create the document when a scheduled post becomes active [#9](https://github.com/percipioglobal/craft-typesense/issues/9) + +- Added: Delete the document when setting an enabled entry to disable [#6](https://github.com/percipioglobal/craft-typesense/issues/6) +- Added: Create the document when a scheduled post becomes active [#9](https://github.com/percipioglobal/craft-typesense/issues/9) ## 4.0.0-beta.1 - 2022-08-21 + ### Added -- Added support for Craft 4 + +- Added support for Craft 4 diff --git a/README.md b/README.md index f0cb66c..0d83534 100755 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # Typesense plugin for Craft CMS 4.x -Craft Plugin that synchronises with Typesense. Visit our [Demo](https://typesense.percipio.london/demo) to see the Craft Typesense plugin in action. You can read our [docs](https://typesense.percipio.london/docs/about) to setup your project. Need more help with the setup? Follow our blogpost "[Setup the Typsesense plugin with Typesense Cloud with javascript](https://percipio.london/blog/craftcms-plugin-typsesense)" +Craft Plugin that synchronises with Typesense. + + ![Screenshot](resources/img/plugin-logo.png) @@ -12,15 +14,15 @@ This plugin requires Craft CMS 4.0.0 or later. To install the plugin, follow these instructions. -1. Open your terminal and go to your Craft project: +1. Open your terminal and go to your Craft project: cd /path/to/project -2. Then tell Composer to load the plugin: +2. Then tell Composer to load the plugin: composer require craftpulse/craft-typesense -3. In the Control Panel, go to Settings → Plugins and click the “Install” button for Typesense. +3. In the Control Panel, go to Settings → Plugins and click the “Install” button for Typesense. ## Typesense Overview @@ -77,6 +79,7 @@ After copy and paste the config.php into your own config folder and name it type ``` By default, Craft CMS doesn't fire an event after updating a status when a scheduled post goes out. Therefore we provide a console command that you can attach to your cron jobs. The command checks if there are entries that are scheduled to go out today and if they haven't been updated after that date + ``` ./craft typesense/default/update-scheduled-posts ``` @@ -89,6 +92,6 @@ By default, Craft CMS doesn't fire an event after updating a status when a sched Some things to do, and ideas for potential features: -* Release it +- Release it -Brought to you by [percipiolondon](https://percipio.london) +Brought to you by [craftpulse](https://github.com/craftpulse) diff --git a/composer.json b/composer.json index 2be80d3..84b6900 100755 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "craftpulse/craft-typesense", "description": "Craft Plugin that synchronises with Typesense", "type": "craft-plugin", - "version": "5.0.1", + "version": "5.1.0", "keywords": [ "craft", "cms", diff --git a/src/controllers/CollectionsController.php b/src/controllers/CollectionsController.php index 6e5d6bc..d8962bc 100755 --- a/src/controllers/CollectionsController.php +++ b/src/controllers/CollectionsController.php @@ -62,7 +62,7 @@ class CollectionsController extends Controller * @throws InvalidConfigException * @throws ForbiddenHttpException */ - public function init() :void + public function init(): void { parent::init(); @@ -91,19 +91,53 @@ public function actionCollections(): Response $indexes = Typesense::$plugin->getSettings()->collections; foreach ($indexes as $index) { - $entry = $index->criteria->one(); - $section = $entry->section ?? null; - - if ($section) { - $variables['sections'][] = [ - 'id' => $section->id, - 'name' => $section->name, - 'handle' => $section->handle, - 'type' => $entry->type->handle, - 'entryCount' => $index->criteria->count(), - 'index' => $index->indexName, - ]; + $element = $index->criteria->one(); + + switch ($index->elementType) { + case 'craft\elements\Asset': + $volume = $element->getVolume() ?? null; + + if ($volume) { + $variables['sections'][] = [ + 'id' => 1, + 'name' => $volume->name, + 'handle' => $volume->handle, + 'type' => 'Asset: ' . $volume->handle, + 'entryCount' => $index->criteria->count(), + 'index' => $index->indexName, + ]; + } + break; + + case 'craft\elements\Entry': + $section = $element->section ?? null; + + if ($section) { + $variables['sections'][] = [ + 'id' => $section->id, + 'name' => $section->name, + 'handle' => $section->handle, + 'type' => 'Entry: ' . $element->type->handle, + 'entryCount' => $index->criteria->count(), + 'index' => $index->indexName, + ]; + } + break; } + + // Craft::dd($element); + // $section = $entry->section ?? null; + + // if ($section) { + // $variables['sections'][] = [ + // 'id' => $section->id, + // 'name' => $section->name, + // 'handle' => $section->handle, + // 'type' => $entry->type->handle, + // 'entryCount' => $index->criteria->count(), + // 'index' => $index->indexName, + // ]; + // } } $variables['csrf'] = [ @@ -337,7 +371,7 @@ public function actionDocuments(): Response|string // Render the template return $this->renderTemplate('typesense/documents/index', $variables); -// $request = Craft::$app->getRequest(); + // $request = Craft::$app->getRequest(); // $index = $request->getBodyParam('index'); // // if (isset(Typesense::$plugin->getClient()->client()->collections[$index])) { @@ -367,11 +401,11 @@ public function actionDocument(int $sectionId): Response|string $section = $entry->section ?? null; if ($section->id === $sectionId) { - $templateTitle = Craft::t('typesense', 'Collections of '.$section->name); + $templateTitle = Craft::t('typesense', 'Collections of ' . $section->name); $documents = $this->asJson(Typesense::$plugin->getClient()->client()->collections[$index->indexName]->documents->export()); if ($documents) { - $documents = explode("\n",$documents->data); + $documents = explode("\n", $documents->data); foreach ($documents as $document) { $variables['documents'][] = Json::decode($document); } @@ -456,7 +490,8 @@ public function actionRetrieveCollection() return $this->asJson(Typesense::$plugin->getClient()->client()->collections[$index]->retrieve()); } - private function _sortDocuments($a, $b) { + private function _sortDocuments($a, $b) + { if ($a['post_date_timestamp'] == $b['post_date_timestamp']) { return 0; } diff --git a/src/web/assets/dist/assets/typesense-collections.05a23db9.js b/src/web/assets/dist/assets/typesense-collections.78c961d3.js similarity index 61% rename from src/web/assets/dist/assets/typesense-collections.05a23db9.js rename to src/web/assets/dist/assets/typesense-collections.78c961d3.js index 3398d1f..f1ffdfc 100644 --- a/src/web/assets/dist/assets/typesense-collections.05a23db9.js +++ b/src/web/assets/dist/assets/typesense-collections.78c961d3.js @@ -1,2 +1,2 @@ -var w=Object.defineProperty,b=Object.defineProperties;var C=Object.getOwnPropertyDescriptors;var m=Object.getOwnPropertySymbols;var k=Object.prototype.hasOwnProperty,$=Object.prototype.propertyIsEnumerable;var y=(e,t,s)=>t in e?w(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s,l=(e,t)=>{for(var s in t||(t={}))k.call(t,s)&&y(e,s,t[s]);if(m)for(var s of m(t))$.call(t,s)&&y(e,s,t[s]);return e},d=(e,t)=>b(e,C(t));import{d as u,c,a as i,t as a,b as f,F as x,o as r,r as A,e as S,f as q,g as B,h as j}from"./vendor.68b06e04.js";const O=e=>({baseURL:e,headers:{"X-Requested-With":"XMLHttpRequest"}}),_=async(e,t,s,n)=>{try{const o=await e.post(t,s);n&&o.data&&n(o.data)}catch(o){console.error("xhr",o)}};var v=(e,t)=>{const s=e.__vccOpts||e;for(const[n,o]of t)s[n]=o;return s};const V=u({props:{section:{type:Object,required:!0},api:{type:Object,required:!0}},data:()=>({type:null}),methods:{async syncCollection(){this.type="sync";let e=d(l({},this.section),{sectionId:this.section.id,[this.api.csrf.name]:this.api.csrf.value});await _(this.api.client,"typesense/sync-collection",e,t=>{this.type=null})},async flushCollection(){this.type="flush";let e=d(l({},this.section),{sectionId:this.section.id,[this.api.csrf.name]:this.api.csrf.value});await _(this.api.client,"typesense/flush-collection",e,t=>{this.type=null})}}}),z={class:"px-6 py-4 whitespace-nowrap flex items-center"},I={class:"px-6 py-4 whitespace-nowrap flex items-center"},L={class:"px-6 py-4 whitespace-nowrap flex items-center"},F={class:"px-6 py-4 whitespace-nowrap flex items-center"},H={class:"px-6 py-2 space-x-2"},M=i("span",null,"Sync",-1),N={key:0,class:"animate-spin ml-1 h-3 w-3 mb-0",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24"},R=i("circle",{class:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor","stroke-width":"4"},null,-1),E=i("path",{class:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"},null,-1),T=[R,E],U=i("span",null,"Flush",-1),X={key:0,class:"animate-spin ml-1 h-3 w-3 mb-0",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24"},D=i("circle",{class:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor","stroke-width":"4"},null,-1),G=i("path",{class:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"},null,-1),W=[D,G];function J(e,t,s,n,o,g){return r(),c(x,null,[i("div",z,a(e.section.index),1),i("div",I,a(e.section.name),1),i("div",L,a(e.section.type),1),i("div",F,a(e.section.entryCount),1),i("div",H,[i("button",{type:"button",class:"cursor-pointer inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-700 hover:bg-indigo-900",onClick:t[0]||(t[0]=p=>e.syncCollection())},[M,e.type==="sync"?(r(),c("svg",N,T)):f("",!0)]),i("button",{type:"button",class:"cursor-pointer inline-flex items-center px-4 py-2 border-transparent shadow-sm text-sm font-medium rounded-md text-indigo-700 border border-solid border-indigo-700 hover:text-white hover:bg-indigo-900",onClick:t[1]||(t[1]=p=>e.flushCollection())},[U,e.type==="flush"?(r(),c("svg",X,W)):f("",!0)])])],64)}var K=v(V,[["render",J]]);const P=u({components:{"list-item-section":K},props:{sections:{type:Object,required:!0},apiConfig:{type:Object,required:!0}},data:()=>({api:null}),methods:{createApi(){const e={client:axios.create(O(this.apiConfig.baseUrl)),csrf:this.apiConfig.csrf};this.api=e}},async created(){await this.createApi()}}),Q={class:"rounded-tr-sm rounded-tl-sm"},Y=S('
Index
Section
Type
Total Entries
Sync
',1),Z={class:"grid grid-cols-5"};function ee(e,t,s,n,o,g){const p=q("list-item-section");return r(),c("section",Q,[Y,i("div",Z,[(r(!0),c(x,null,A(e.sections,h=>(r(),B(p,{section:h,key:h.id,api:e.api},null,8,["section","api"]))),128))])])}var te=v(P,[["render",ee]]);const se=u({components:{"grid-sections":te}}),ie=async()=>j(se).mount("#typesense-collections");ie().then(e=>{}); -//# sourceMappingURL=typesense-collections.05a23db9.js.map +var w=Object.defineProperty,b=Object.defineProperties;var C=Object.getOwnPropertyDescriptors;var m=Object.getOwnPropertySymbols;var k=Object.prototype.hasOwnProperty,$=Object.prototype.propertyIsEnumerable;var y=(e,t,s)=>t in e?w(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s,l=(e,t)=>{for(var s in t||(t={}))k.call(t,s)&&y(e,s,t[s]);if(m)for(var s of m(t))$.call(t,s)&&y(e,s,t[s]);return e},d=(e,t)=>b(e,C(t));import{d as u,c,a as i,t as a,b as f,F as x,o as r,r as A,e as q,f as B,g as S,h as j}from"./vendor.68b06e04.js";const O=e=>({baseURL:e,headers:{"X-Requested-With":"XMLHttpRequest"}}),_=async(e,t,s,n)=>{try{const o=await e.post(t,s);n&&o.data&&n(o.data)}catch(o){console.error("xhr",o)}};var v=(e,t)=>{const s=e.__vccOpts||e;for(const[n,o]of t)s[n]=o;return s};const V=u({props:{section:{type:Object,required:!0},api:{type:Object,required:!0}},data:()=>({type:null}),methods:{async syncCollection(){this.type="sync";let e=d(l({},this.section),{sectionId:this.section.id,[this.api.csrf.name]:this.api.csrf.value});await _(this.api.client,"typesense/sync-collection",e,t=>{this.type=null})},async flushCollection(){this.type="flush";let e=d(l({},this.section),{sectionId:this.section.id,[this.api.csrf.name]:this.api.csrf.value});await _(this.api.client,"typesense/flush-collection",e,t=>{this.type=null})}}}),z={class:"px-6 py-4 whitespace-nowrap flex items-center"},I={class:"px-6 py-4 whitespace-nowrap flex items-center"},L={class:"px-6 py-4 whitespace-nowrap flex items-center"},N={class:"px-6 py-4 whitespace-nowrap flex items-center"},R={class:"px-6 py-2 space-x-2"},F=i("span",null,"Sync",-1),H={key:0,class:"animate-spin ml-1 h-3 w-3 mb-0",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24"},M=i("circle",{class:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor","stroke-width":"4"},null,-1),U=i("path",{class:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"},null,-1),X=[M,U],D=i("span",null,"Flush",-1),E={key:0,class:"animate-spin ml-1 h-3 w-3 mb-0",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24"},G=i("circle",{class:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor","stroke-width":"4"},null,-1),T=i("path",{class:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"},null,-1),W=[G,T];function J(e,t,s,n,o,g){return r(),c(x,null,[i("div",z,a(e.section.index),1),i("div",I,a(e.section.name),1),i("div",L,a(e.section.type),1),i("div",N,a(e.section.entryCount),1),i("div",R,[i("button",{type:"button",class:"cursor-pointer inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-700 hover:bg-indigo-900",onClick:t[0]||(t[0]=p=>e.syncCollection())},[F,e.type==="sync"?(r(),c("svg",H,X)):f("",!0)]),i("button",{type:"button",class:"cursor-pointer inline-flex items-center px-4 py-2 border-transparent shadow-sm text-sm font-medium rounded-md text-indigo-700 border border-solid border-indigo-700 hover:text-white hover:bg-indigo-900",onClick:t[1]||(t[1]=p=>e.flushCollection())},[D,e.type==="flush"?(r(),c("svg",E,W)):f("",!0)])])],64)}var K=v(V,[["render",J]]);const P=u({components:{"list-item-section":K},props:{sections:{type:Object,required:!0},apiConfig:{type:Object,required:!0}},data:()=>({api:null}),methods:{createApi(){const e={client:axios.create(O(this.apiConfig.baseUrl)),csrf:this.apiConfig.csrf};this.api=e}},async created(){await this.createApi()}}),Q={class:"rounded-tr-sm rounded-tl-sm"},Y=q('
Index
Name
Type
Results
Sync
',1),Z={class:"grid grid-cols-5"};function ee(e,t,s,n,o,g){const p=B("list-item-section");return r(),c("section",Q,[Y,i("div",Z,[(r(!0),c(x,null,A(e.sections,h=>(r(),S(p,{section:h,key:h.id,api:e.api},null,8,["section","api"]))),128))])])}var te=v(P,[["render",ee]]);const se=u({components:{"grid-sections":te}}),ie=async()=>j(se).mount("#typesense-collections");ie().then(e=>{}); +//# sourceMappingURL=typesense-collections.78c961d3.js.map diff --git a/src/web/assets/dist/assets/typesense-collections.05a23db9.js.map b/src/web/assets/dist/assets/typesense-collections.78c961d3.js.map similarity index 91% rename from src/web/assets/dist/assets/typesense-collections.05a23db9.js.map rename to src/web/assets/dist/assets/typesense-collections.78c961d3.js.map index ede2bb1..d5f1def 100644 --- a/src/web/assets/dist/assets/typesense-collections.05a23db9.js.map +++ b/src/web/assets/dist/assets/typesense-collections.78c961d3.js.map @@ -1 +1 @@ -{"version":3,"file":"typesense-collections.05a23db9.js","sources":["../../../../../buildchain/src/js/api/api.ts","../../../../../buildchain/plugin-vue:export-helper","../../../../../buildchain/src/js/typesense-collections.ts"],"sourcesContent":["export const configureApi = (url) => ({\n baseURL: url,\n headers: {\n 'X-Requested-With': 'XMLHttpRequest'\n }\n})\n\nexport const executeApi = async(api, url, variables, callback) => {\n try {\n const response = await api.post(url, variables)\n if ( callback && response.data ) {\n callback(response.data)\n }\n } catch (error) {\n console.error('xhr', error)\n }\n}\n","\nexport default (sfc, props) => {\n const target = sfc.__vccOpts || sfc;\n for (const [key, val] of props) {\n target[key] = val;\n }\n return target;\n}\n","import { createApp } from 'vue'\nimport TypesenseCollections from '@/vue/TypesenseCollections.vue'\n\nconst main = async () => {\n\n const app = createApp(TypesenseCollections)\n const root = app.mount('#typesense-collections')\n\n return root\n\n};\n\nmain().then( (root) => {} )\n"],"names":["TypesenseCollections"],"mappings":"miBAAa,GAAe,AAAC,KACzB,QAAS,EACT,QAAS,CACL,mBAAoB,oBAIf,EAAa,MAAM,EAAK,EAAK,EAAW,IAAa,IAC1D,MACM,GAAW,KAAM,GAAI,KAAK,EAAK,GAChC,GAAY,EAAS,QACb,EAAS,YAEjB,WACG,MAAM,MAAO,KCb7B,MAAe,CAAC,EAAK,IAAU,CAC7B,KAAM,GAAS,EAAI,WAAa,EAChC,SAAW,CAAC,EAAK,IAAQ,GACvB,EAAO,GAAO,EAEhB,MAAO,qtHCHH,GAAO,SAGI,AADD,EAAUA,IACL,MAAM,0BAM3B,KAAO,KAAM,AAAC,GAAS"} \ No newline at end of file +{"version":3,"file":"typesense-collections.78c961d3.js","sources":["../../../../../buildchain/src/js/api/api.ts","../../../../../buildchain/plugin-vue:export-helper","../../../../../buildchain/src/js/typesense-collections.ts"],"sourcesContent":["export const configureApi = (url) => ({\n baseURL: url,\n headers: {\n 'X-Requested-With': 'XMLHttpRequest'\n }\n})\n\nexport const executeApi = async(api, url, variables, callback) => {\n try {\n const response = await api.post(url, variables)\n if ( callback && response.data ) {\n callback(response.data)\n }\n } catch (error) {\n console.error('xhr', error)\n }\n}\n","\nexport default (sfc, props) => {\n const target = sfc.__vccOpts || sfc;\n for (const [key, val] of props) {\n target[key] = val;\n }\n return target;\n}\n","import { createApp } from 'vue'\nimport TypesenseCollections from '@/vue/TypesenseCollections.vue'\n\nconst main = async () => {\n\n const app = createApp(TypesenseCollections)\n const root = app.mount('#typesense-collections')\n\n return root\n\n};\n\nmain().then( (root) => {} )\n"],"names":["TypesenseCollections"],"mappings":"miBAAa,GAAe,AAAC,KACzB,QAAS,EACT,QAAS,CACL,mBAAoB,oBAIf,EAAa,MAAM,EAAK,EAAK,EAAW,IAAa,IAC1D,MACM,GAAW,KAAM,GAAI,KAAK,EAAK,GAChC,GAAY,EAAS,QACb,EAAS,YAEjB,WACG,MAAM,MAAO,KCb7B,MAAe,CAAC,EAAK,IAAU,CAC7B,KAAM,GAAS,EAAI,WAAa,EAChC,SAAW,CAAC,EAAK,IAAQ,GACvB,EAAO,GAAO,EAEhB,MAAO,4sHCHH,GAAO,SAGI,AADD,EAAUA,IACL,MAAM,0BAM3B,KAAO,KAAM,AAAC,GAAS"} \ No newline at end of file diff --git a/src/web/assets/dist/manifest.json b/src/web/assets/dist/manifest.json index 76d155c..fd13ea4 100644 --- a/src/web/assets/dist/manifest.json +++ b/src/web/assets/dist/manifest.json @@ -8,7 +8,7 @@ ] }, "src/js/typesense-collections.ts": { - "file": "assets/typesense-collections.05a23db9.js", + "file": "assets/typesense-collections.78c961d3.js", "src": "src/js/typesense-collections.ts", "isEntry": true, "imports": [ diff --git a/src/web/assets/src/vue/organisms/grids/GridSections.vue b/src/web/assets/src/vue/organisms/grids/GridSections.vue index de45d64..c5c93a6 100644 --- a/src/web/assets/src/vue/organisms/grids/GridSections.vue +++ b/src/web/assets/src/vue/organisms/grids/GridSections.vue @@ -57,7 +57,7 @@
- Section + Name
@@ -65,7 +65,7 @@
- Total Entries + Results