Prerequisites: You have an ocis-extension defining at least one service with rpc requests in a .proto file.
Goal: Your ocis-extension is now supposed to have a web UI, which can be hooked into ocis-web as a frontend extension and is able to communicate with the service(s) in your ocis-extension.
Note: All files referenced below can be copied over from ocis-hello:
Set up an empty Vue app as extension for ocis-web
- copy package.json, rollup.config.js, babel.config.js and .eslintrc.json
- adjust package.json and rollup.config.js to your project-name. This is mostly a search-and-replace from
hello to your extension name.
- run
yarn install
- create an empty Vue.js file
ui/components/App.vue in your project. This is where your web ui lives - it will be rendered within the content area of ocis-web (just having the left sidebar and the topbar) when navigating to your extension. Looking at the same file in ocis-hello or other extensions will give you an idea of what you can do here.
- copy
ui/app.js to your project. Again, you can just go through it and replace hello with your extension name. This file will be loaded by ocis-web and contains all the required information to make your extension available with it's own menu item and properly recognized in the ocis-web extension system. You can export a vuex-store module here if your extension works with it, but it's not required to do so.
- run
yarn build. This will build your app and copy it to the assets folder of your extension.
TODO: store is mandatory for ocis-web extension system! needs to have a loadConfig action.
TODO: include frontend drone steps for building JS assets
Result: You have an (empty) ocis-web extension that fulfils the requirements of ocis-web to be loaded as an external extension. Next step is to enable your ocis-extension to deliver the built assets.
Enable your ocis-extension to deliver the built assets
- your ocis-extension will not serve the generate .js bundle. Instead, we will use
fileb0x to generate embeddable go assets from your .js bundle.
- from
pkg/assets/, copy assets.go, option.go and embed.yml. Adapt import paths in assets.go and option.go to point to your extension instead of ocis-hello. Don't worry about the unresolved FS and CTX vars, they will be part of generated code later on.
- change the
GENERATE target in your Makefile from GENERATE ?= $(PACKAGES) to GENERATE ?= $(PACKAGES) $(IMPORT)/pkg/assets
- run
make generate. This will create the pkg/assets/embed.go file (which then also defines FS and CTX from step 1).
- for your ocis-extension to deliver the static assets that now live in your embed.go, you will need an http server in your ocis-extension. If you don't have one, yet, you can just copy
pkg/server/http to your ocis-extension. The important part is, that the http server serves the assets with a Static middleware.
- compile your binary and run it (
make build and then ./bin/<extension-name> server)
- Load your web ui in your ocis-web config file, by adding it like this: Within your top level
"external_apps": [] variable inside your config.json, add a new entry:
{
"id": "<your-extension-name>",
"path": "http://localhost:<your extension http port>/settings.js"
}
Result: Your extension for ocis-web can be loaded in ocis-web (see configuration - insert docs link here). It is delivered by your ocis-extension.
More comfort with make watch
Note: this has not proven to be good DX. Needs a better solution, maybe with a webpack dev server.
- As your ocis-extension is serving compiled assets from a previously built javascript bundle, you need to follow these steps when you changed something in your Vue app and want to see it in the browser: a) run
yarn build for an updated javascript bundle, b) run make clean generate build for having a new version of your ocis-extension available, including new compiled assets, c) start your ocis-extension, d) reload the page. In order to make this a little bit easier, we have a make watch target available for you. In order to set this up, follow these steps:
- copy the
reflex.conf file from ocis-hello and adapt it to your extension name
- copy the
watch target from the Makefile of ocis-hello into your Makefile
- run
make watch
Result: Each time you save a file, your javascript app and go binary get recompiled and the new binary gets started.
Note: Especially when saving files in your Vue code, this first builds your javascript app bundle and then recompiles the go binary, so it takes a few seconds until you can reload the page in ocis-web. Please wait with the page reload until you see the Starting server xyz log line.
Generate a javascript client for your API:
- set up generating micro-web and swagger definitions in Makefile
- set endpoint annotations in rpc request definitions in .proto files
- look at
third_party folder. Depending on usages in .proto there are some .proto files that might need to be included and copied into your project
- run
make protobuf - this will generate the files defined in step 1
- run
mkdir -p ui/client/<your-extension-name>
6: run yarn generate-api - this will use the swagger.json file from step 1 to generate a javascript client (stored in ui/client//index.js)
- in pkg/server/http/server.go, register the routes of your generated micro-web handlers (look for
Register<service-name>ServiceWeb in ocis-hello for how to do this)
- set up bearer token injection, so that your requests are authenticated.
Result: You will have a JavaScript client available at ui/client/<your-extension-name>/index.js. It is generated from your .proto file and provides functions for each endpoint you defined. Internally it uses AXIOS to make the respective requests. You can now start using it in your extension for ocis-web.
General advice for building your extension for ocis-web:
- make yourself comfortable with owncloud-design-system (ODS). It should be configured as a peer depedency in your package.json and is provided by ocis-web. This gives you components that make it easier for you to comply with the look and feel of ocis-web, will adhere theming and is already built for a11y compliance. If you can't find a component in ODS, open an issue or even a PR.
- the ocis-web extension system will try to call a
loadConfig action in the vuex-store of your extension. Since this provides you with the config.server variable, which is required for all API calls, you will have to wait for that, thus loading all your extension data after the config was provided.
Prerequisites: You have an ocis-extension defining at least one service with rpc requests in a .proto file.
Goal: Your ocis-extension is now supposed to have a web UI, which can be hooked into
ocis-webas a frontend extension and is able to communicate with the service(s) in your ocis-extension.Note: All files referenced below can be copied over from ocis-hello:
Set up an empty Vue app as extension for ocis-web
helloto your extension name.yarn installui/components/App.vuein your project. This is where your web ui lives - it will be rendered within the content area ofocis-web(just having the left sidebar and the topbar) when navigating to your extension. Looking at the same file in ocis-hello or other extensions will give you an idea of what you can do here.ui/app.jsto your project. Again, you can just go through it and replacehellowith your extension name. This file will be loaded byocis-weband contains all the required information to make your extension available with it's own menu item and properly recognized in theocis-webextension system. You can export a vuex-store module here if your extension works with it, but it's not required to do so.yarn build. This will build your app and copy it to theassetsfolder of your extension.TODO: store is mandatory for ocis-web extension system! needs to have a
loadConfigaction.TODO: include
frontenddrone steps for building JS assetsResult: You have an (empty)
ocis-webextension that fulfils the requirements ofocis-webto be loaded as an external extension. Next step is to enable your ocis-extension to deliver the built assets.Enable your ocis-extension to deliver the built assets
fileb0xto generate embeddable go assets from your .js bundle.pkg/assets/, copy assets.go, option.go and embed.yml. Adapt import paths in assets.go and option.go to point to your extension instead of ocis-hello. Don't worry about the unresolvedFSandCTXvars, they will be part of generated code later on.GENERATEtarget in your Makefile fromGENERATE ?= $(PACKAGES)toGENERATE ?= $(PACKAGES) $(IMPORT)/pkg/assetsmake generate. This will create thepkg/assets/embed.gofile (which then also definesFSandCTXfrom step 1).pkg/server/httpto your ocis-extension. The important part is, that the http server serves the assets with aStaticmiddleware.make buildand then./bin/<extension-name> server)"external_apps": []variable inside your config.json, add a new entry:Result: Your extension for
ocis-webcan be loaded inocis-web(see configuration - insert docs link here). It is delivered by your ocis-extension.More comfort with
make watchNote: this has not proven to be good DX. Needs a better solution, maybe with a webpack dev server.
yarn buildfor an updated javascript bundle, b) runmake clean generate buildfor having a new version of your ocis-extension available, including new compiled assets, c) start your ocis-extension, d) reload the page. In order to make this a little bit easier, we have amake watchtarget available for you. In order to set this up, follow these steps:reflex.conffile from ocis-hello and adapt it to your extension namewatchtarget from the Makefile of ocis-hello into your Makefilemake watchResult: Each time you save a file, your javascript app and go binary get recompiled and the new binary gets started.
Note: Especially when saving files in your Vue code, this first builds your javascript app bundle and then recompiles the go binary, so it takes a few seconds until you can reload the page in ocis-web. Please wait with the page reload until you see the
Starting server xyzlog line.Generate a javascript client for your API:
third_partyfolder. Depending on usages in .proto there are some .proto files that might need to be included and copied into your projectmake protobuf- this will generate the files defined in step 1mkdir -p ui/client/<your-extension-name>6: run
yarn generate-api- this will use the swagger.json file from step 1 to generate a javascript client (stored in ui/client//index.js)Register<service-name>ServiceWebin ocis-hello for how to do this)Result: You will have a JavaScript client available at
ui/client/<your-extension-name>/index.js. It is generated from your .proto file and provides functions for each endpoint you defined. Internally it uses AXIOS to make the respective requests. You can now start using it in your extension for ocis-web.General advice for building your extension for ocis-web:
loadConfigaction in the vuex-store of your extension. Since this provides you with theconfig.servervariable, which is required for all API calls, you will have to wait for that, thus loading all your extension data after the config was provided.