diff --git a/client/web/compose/.browserslistrc b/client/web/compose/.browserslistrc new file mode 100644 index 000000000..6c7fda681 --- /dev/null +++ b/client/web/compose/.browserslistrc @@ -0,0 +1,5 @@ +Chrome >= 60 +Safari >= 10.1 +iOS >= 10.3 +Firefox >= 54 +Edge >= 15 diff --git a/client/web/compose/.editorconfig b/client/web/compose/.editorconfig new file mode 100644 index 000000000..7b9d410f0 --- /dev/null +++ b/client/web/compose/.editorconfig @@ -0,0 +1,16 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +# Tab indentation (no size specified) +[Makefile] +indent_style = tab diff --git a/client/web/compose/.eslintrc.js b/client/web/compose/.eslintrc.js new file mode 100644 index 000000000..63a01b4cf --- /dev/null +++ b/client/web/compose/.eslintrc.js @@ -0,0 +1,23 @@ +module.exports = { + root: true, + env: { + es6: true, + node: true, + mocha: true, + }, + extends: [ + 'plugin:vue/recommended', + '@vue/standard', + ], + rules: { + 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', + 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', + 'vue/order-in-components': ['error'], + 'comma-dangle': ['error', 'always-multiline'], + // https://github.com/vuejs/eslint-plugin-vue/blob/master/docs/rules/order-in-components.md + 'vue/no-v-html': 'off', + }, + parserOptions: { + parser: 'babel-eslint', + }, +} diff --git a/client/web/compose/.gitignore b/client/web/compose/.gitignore new file mode 100644 index 000000000..c07682e05 --- /dev/null +++ b/client/web/compose/.gitignore @@ -0,0 +1,20 @@ +.DS_Store +node_modules +dist +*.log + +# Editor directories and files +.idea +.vscode +*.iml +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw* + +.nyc_output +coverage + +/.act* +/workflow diff --git a/client/web/compose/Dockerfile b/client/web/compose/Dockerfile new file mode 100644 index 000000000..b983de379 --- /dev/null +++ b/client/web/compose/Dockerfile @@ -0,0 +1,37 @@ +# build-stage +FROM node:12.14-alpine as build-stage + +ENV PATH /app/node_modules/.bin:$PATH + +WORKDIR /app + +RUN apk update && apk add --no-cache git + +COPY package.json ./ +COPY yarn.lock ./ + +RUN yarn install + +COPY . ./ + +RUN yarn build + + +# deploy stage +FROM nginx:stable-alpine + +WORKDIR /usr/share/nginx/html + +COPY --from=build-stage /app/dist /usr/share/nginx/html +COPY nginx.conf /etc/nginx/nginx.conf +COPY CONTRIBUTING.* DCO LICENSE README.* ./ +COPY entrypoint.sh /entrypoint.sh + +RUN chmod +x /entrypoint.sh + +EXPOSE 80 + +HEALTHCHECK --interval=30s --start-period=10s --timeout=30s \ + CMD wget --quiet --tries=1 --spider "http://127.0.0.1:80/config.js" || exit 1 + +ENTRYPOINT ["/entrypoint.sh"] diff --git a/client/web/compose/Makefile b/client/web/compose/Makefile new file mode 100644 index 000000000..601453d6f --- /dev/null +++ b/client/web/compose/Makefile @@ -0,0 +1,42 @@ +.PHONY: dep test build release upload + + +YARN_FLAGS ?= --non-interactive --no-progress --silent --emoji false +YARN = yarn $(YARN_FLAGS) + +REPO_NAME ?= corteza-webapp-compose + +BUILD_FLAVOUR ?= corteza +BUILD_FLAGS ?= --production +BUILD_DEST_DIR = dist +BUILD_TIME ?= $(shell date +%FT%T%z) +BUILD_VERSION ?= $(shell git describe --tags --abbrev=0) + +BUILD_NAME = $(REPO_NAME)-$(BUILD_VERSION) + +RELEASE_NAME = $(BUILD_NAME).tar.gz +RELEASE_EXTRA_FILES ?= README.md LICENSE CONTRIBUTING.md DCO +RELEASE_PKEY ?= .upload-rsa + +dep: + $(YARN) install + +test: + $(YARN) lint + $(YARN) test:unit + +build: + export BUILD_VERSION=${BUILD_VERSION} && $(YARN) build $(BUILD_FLAGS) + +release: + @ echo $(RELEASE_NAME) + @ cp $(RELEASE_EXTRA_FILES) $(BUILD_DEST_DIR) + @ tar -C $(BUILD_DEST_DIR) -czf $(RELEASE_NAME) $(dir $(BUILD_DEST_DIR)) + +upload: $(RELEASE_PKEY) + @ echo "put *.tar.gz" | sftp -q -o "StrictHostKeyChecking no" -i $(RELEASE_PKEY) $(RELEASE_SFTP_URI) + @ rm -f $(RELEASE_PKEY) + +$(RELEASE_PKEY): + @ echo $(RELEASE_SFTP_KEY) | base64 -d > $(RELEASE_PKEY) + @ chmod 0400 $@ diff --git a/client/web/compose/babel.config.js b/client/web/compose/babel.config.js new file mode 100644 index 000000000..895e7ddc2 --- /dev/null +++ b/client/web/compose/babel.config.js @@ -0,0 +1,13 @@ +module.exports = { + presets: [ + ['@vue/app', { useBuiltIns: 'entry' }], + ], + + env: { + test: { + plugins: [ + ['istanbul', { useInlineSourceMaps: false }], + ], + }, + }, +} diff --git a/client/web/compose/entrypoint.sh b/client/web/compose/entrypoint.sh new file mode 100644 index 000000000..d26330247 --- /dev/null +++ b/client/web/compose/entrypoint.sh @@ -0,0 +1,42 @@ +#!/bin/sh + +set -eu + +if [ ! -z "${1:-}" ]; then + exec "$@" +else + # check if config.js is present (via volume) + # or if it's missing + if [ ! -f "./config.js" ]; then + # config.js missing, generate it + if [ ! -z "${CONFIGJS:-}" ]; then + # use $CONFIGJS variable that might be passed to the container: + # --env CONFIGJS="$(cat public/config.example.js)" + echo "${CONFIGJS}" > ./config.js + else + # Try to guess where the API is located by using DOMAIN or VIRTUAL_HOST and prefix it with "api." + API_HOST=${API_HOST:-"api.${VIRTUAL_HOST:-"${DOMAIN:-"local.cortezaproject.org"}"}"} + API_BASEURL=${API_FULL_URL:-"//${API_HOST}"} + + echo "window.CortezaAPI = '${API_BASEURL}'" > ./config.js + fi + fi + + BASE_PATH=${BASE_PATH:-"/"} + if [ $BASE_PATH != "/" ]; then + BASE_PATH_LENGTH=${#BASE_PATH} + BASE_PATH_LAST_CHAR=${BASE_PATH:BASE_PATH_LENGTH-1:1} + + if [ $BASE_PATH_LAST_CHAR != "/" ]; then + BASE_PATH="$BASE_PATH/" + fi + fi + + sed -i "s|||g" ./index.html + sed -i "s|||g" ./index.html + + sed -i "s|{{BASE_PATH}}|$BASE_PATH|g" /etc/nginx/nginx.conf + + + nginx -g "daemon off;" +fi diff --git a/client/web/compose/nginx.conf b/client/web/compose/nginx.conf new file mode 100644 index 000000000..c1be54219 --- /dev/null +++ b/client/web/compose/nginx.conf @@ -0,0 +1,46 @@ +user nginx; +worker_processes 1; + +error_log /dev/stdout warn; + +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format json escape=json + '{' + '"@timestamp":"$time_iso8601",' + '"remote_addr":"$remote_addr",' + '"request":"$request",' + '"status":$status,' + '"body_bytes_sent":$body_bytes_sent,' + '"request_time":$request_time,' + '"http_referrer":"$http_referer",' + '"http_user_agent":"$http_user_agent"' + '}'; + + access_log /dev/stdout json; + + sendfile on; + keepalive_timeout 300; + + server { + listen 80 default_server; + listen [::]:80 default_server; + server_name _; + + index index.html; + + root /usr/share/nginx/html; + + location {{BASE_PATH}} { + try_files $uri {{BASE_PATH}}index.html; + } + } +} diff --git a/client/web/compose/package.json b/client/web/compose/package.json new file mode 100644 index 000000000..47b7f5181 --- /dev/null +++ b/client/web/compose/package.json @@ -0,0 +1,160 @@ +{ + "name": "corteza-webapp-compose", + "description": "Corteza Compose WebApp", + "version": "2022.9.2", + "license": "Apache-2.0", + "contributors": [ + "Denis Arh " + ], + "private": true, + "scripts": { + "serve": "vue-cli-service serve", + "dev-env": "vue-cli-service serve src/dev-env.js", + "build": "vue-cli-service build --mode production", + "lint": "vue-cli-service lint && stylelint '**/*.{vue,scss}' --fix", + "test:unit": "vue-cli-service test:unit", + "test:unit:cc": "nyc vue-cli-service test:unit", + "cdeps": "yarn upgrade @cortezaproject/corteza-js @cortezaproject/corteza-vue" + }, + "gitHooks": { + "pre-commit": "yarn lint" + }, + "stylelint": { + "plugins": [ + "stylelint-scss" + ], + "extends": "stylelint-config-standard", + "rules": { + "color-hex-case": null, + "color-hex-length": null, + "no-empty-source": null, + "selector-list-comma-newline-after": null + } + }, + "dependencies": { + "@cortezaproject/corteza-js": "^2022.9.2", + "@cortezaproject/corteza-vue": "^2022.9.2", + "@fortawesome/fontawesome-svg-core": "^1.2.21", + "@fortawesome/free-regular-svg-icons": "^5.10.1", + "@fortawesome/free-solid-svg-icons": "^5.10.1", + "@fortawesome/vue-fontawesome": "^0.1.9", + "@fullcalendar/bootstrap": "^4.3.0", + "@fullcalendar/core": "^4.3.1", + "@fullcalendar/daygrid": "^4.3.0", + "@fullcalendar/list": "^4.3.0", + "@fullcalendar/timegrid": "^4.3.0", + "@fullcalendar/vue": "^4.3.1", + "@popperjs/core": "^2.4.0", + "axios": "^0.21.2", + "bootstrap-vue": "^2.21.2", + "c3": "^0.7.12", + "compact-timezone-list": "^1.0.6", + "echarts": "^5.3.3", + "ejs": "^3.1.7", + "file-saver": "^2.0.2", + "flush-promises": "^1.0.2", + "fstream": "^1.0.12", + "hex-rgb": "^4.1.0", + "highlight.js": "^10.4.1", + "html-parse-stringify": "^2.0.3", + "i": "^0.3.7", + "jquery": "^3.5.0", + "js-yaml": "^3.13.1", + "json-bigint": "^1.0.0", + "leaflet": "^1.7.1", + "lodash": "^4.17.19", + "markdown-it": "^12.3.2", + "mixin-deep": "^1.3.2", + "moment": "2.29.2", + "numeral": "^2.0.6", + "portal-vue": "^2.1.7", + "postcss-rtl": "^1.7.3", + "prosemirror-model": "^1.11.2", + "resolve-url-loader": "^3.1.0", + "set-value": "^4.0.1", + "v-tooltip": "^2.0.2", + "vue": "2.6.14", + "vue-echarts": "^6.2.3", + "vue-grid-layout": "^2.3.3", + "vue-native-websocket": "^2.0.14", + "vue-router": "3.1.5", + "vue-select": "^3.1.0", + "vue-sortable-tree": "^1.2.2", + "vue-tweet-embed": "^2.3.0", + "vue2-brace-editor": "^2.0.2", + "vue2-dropzone": "^3.6.0", + "vue2-leaflet": "^2.7.1", + "vuedraggable": "^2.23.0", + "vuex": "^3.1.1", + "vuex-router-sync": "^5.0.0" + }, + "devDependencies": { + "@babel/core": "^7.0.0", + "@emotion/core": "^10.0.15", + "@types/lodash": "^4.14.136", + "@vue/cli-plugin-babel": "^3.10.0", + "@vue/cli-plugin-eslint": "^4.1.2", + "@vue/cli-plugin-unit-mocha": "^3.10.0", + "@vue/cli-service": "^3.10.0", + "@vue/composition-api": "^1.7.0", + "@vue/eslint-config-prettier": "^6.0.0", + "@vue/eslint-config-standard": "^5.1.0", + "@vue/test-utils": "^1.0.0-beta.20", + "babel-eslint": "^10.0.3", + "babel-loader": "^7.0.0", + "babel-plugin-istanbul": "^5.2.0", + "babel-preset-vue": "^2.0.2", + "chai": "^4.1.2", + "chai-as-promised": "^7.1.1", + "css-loader": "*", + "eslint": "^6.8.0", + "eslint-plugin-import": "^2.20.0", + "eslint-plugin-node": "^11.0.0", + "eslint-plugin-prettier": "^3.1.0", + "eslint-plugin-promise": "^4.2.1", + "eslint-plugin-standard": "^4.0.1", + "eslint-plugin-vue": "^6.1.2", + "null-loader": "^4.0.1", + "nyc": "^14.1.1", + "sass": "^1.49.9", + "sass-loader": "^10", + "sinon": "^7.3.2", + "stylelint": "^8.0.0", + "stylelint-config-standard": "^18.3.0", + "stylelint-scss": "^3.14.2", + "stylelint-webpack-plugin": "^0.10.5", + "vue-loader": "^15.8.3", + "vue-template-compiler": "2.6.14", + "webpack": "^4.41.5" + }, + "resolutions": { + "**/**/highlight.js": "^10.4.1", + "**/**/moment": "2.29.2", + "**/**/prosemirror-model": "^1.11.2", + "**/**/chart.js": "2.9.3" + }, + "nyc": { + "all": true, + "reporter": [ + "lcov", + "text" + ], + "include": [ + "src/**/*.{js,vue}" + ], + "exclude": [ + "**/index.js", + "**/*.spec.js" + ], + "extension": [ + ".js", + ".vue" + ], + "check-coverage": true, + "per-file": true, + "branches": 0, + "lines": 0, + "functions": 0, + "statements": 0 + } +} diff --git a/client/web/compose/postcss.config.js b/client/web/compose/postcss.config.js new file mode 100644 index 000000000..cf97eecae --- /dev/null +++ b/client/web/compose/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + autoprefixer: {}, + 'postcss-rtl': {}, + }, +} diff --git a/client/web/compose/public/.gitignore b/client/web/compose/public/.gitignore new file mode 100644 index 000000000..a2d72a240 --- /dev/null +++ b/client/web/compose/public/.gitignore @@ -0,0 +1 @@ +config.js \ No newline at end of file diff --git a/client/web/compose/public/config.example.js b/client/web/compose/public/config.example.js new file mode 100644 index 000000000..25c0e7ef6 --- /dev/null +++ b/client/web/compose/public/config.example.js @@ -0,0 +1,18 @@ +// Corteza API location +window.CortezaAPI = 'https://api.cortezaproject.your-domain.tld'; + +// CortezaAuth can be autoconfigured by replacing /api with /auth in CortezaAPI +// or by appending /auth to the end of CortezaAPI string +// When this is not possible and your configuration is more exotic you can set it +// explicitly: +// window.CortezaAuth = 'https://api.cortezaproject.your-domain.tld/auth'; + +// Configure CortezaWebapp when your web applications are not placed on the root. +// This is autoconfigured from the value of tag href attribute in most cases. +// window.CortezaWebapp = 'https://cortezaproject.your-domain.tld'; + + +// Set to true to enable i18next-pseudo +// Used to test translation string in a development environment +// Even if set to true, it will be disabled in production +window.i18nPseudoModeEnabled = false diff --git a/client/web/compose/public/favicon32x32x.png b/client/web/compose/public/favicon32x32x.png new file mode 100644 index 000000000..dab993d7e Binary files /dev/null and b/client/web/compose/public/favicon32x32x.png differ diff --git a/client/web/compose/public/index.html b/client/web/compose/public/index.html new file mode 100644 index 000000000..f749418ea --- /dev/null +++ b/client/web/compose/public/index.html @@ -0,0 +1,31 @@ + + + + + + + + + + + <%= FLAVOUR %> + + + +
+ + + + diff --git a/client/web/compose/src/app.js b/client/web/compose/src/app.js new file mode 100644 index 000000000..4226edbcd --- /dev/null +++ b/client/web/compose/src/app.js @@ -0,0 +1,183 @@ +import Vue from 'vue' + +import './config-check' +import './console-splash' + +import './filters' +import './plugins' +import './mixins' +import './components' + +import store from './store' +import router from './router' + +import { compose } from '@cortezaproject/corteza-js' +import { mixins, corredor, websocket, i18n } from '@cortezaproject/corteza-vue' + +const notProduction = (process.env.NODE_ENV !== 'production') +const verboseEventbus = window.location.search.includes('verboseEventbus') + +export default (options = {}) => { + options = { + el: '#app', + name: 'compose', + template: '
', + + mixins: [ + mixins.corredor, + ], + + data: () => ({ + loaded: false, + i18nLoaded: false, + }), + + async created () { + this.$i18n.i18next.on('loaded', () => { + this.i18nLoaded = true + }) + + this.websocket() + + return this.$auth.vue(this).handle().then(({ user }) => { + // switch the page directionality on body based on language + document.body.setAttribute('dir', this.textDirectionality(user.meta.preferredLanguage)) + + if (user.meta.preferredLanguage) { + // After user is authenticated, get his preferred language + // and instruct i18next to change it + this.$i18n.i18next.changeLanguage(user.meta.preferredLanguage) + + /** + * Let the API know what kind of language do we accept and send + */ + this.$ComposeAPI + .setHeader('Accept-Language', user.meta.preferredLanguage) + .setHeader('Content-Language', user.meta.preferredLanguage) + } + + // ref to vue is needed inside compose helper + // load and register bundle and list of client/server scripts + + const bundleLoaderOpt = { + // Name of the bundle to load + bundle: 'compose', + + // Debug logging + verbose: notProduction || verboseEventbus, + + // Context for exec function (client scripts only!) + // + // Extended with additional helpers + ctx: new corredor.ComposeCtx( + { + $invoker: this.$auth.user, + authToken: this.$auth.accessToken, + }, + this, + ), + } + + // Load all pending prompts: + this.$store.dispatch('wfPrompts/update') + + // Load effective permissions + this.$store.dispatch('rbac/load') + + // Initializes reminders subsystems, do prefetch of all pending reminders + this.$Reminder.init(this, { filter: { assignedTo: user.userID } }) + + this.loadBundle(bundleLoaderOpt) + .then(() => this.$ComposeAPI.automationList({ excludeInvalid: true })) + .then(this.makeAutomationScriptsRegistrator( + // compose specific handler that routes onManual events for server-scripts + // to the proper endpoint on the API + compose.TriggerComposeServerScriptOnManual(this.$ComposeAPI), + )) + + this.$Settings.init({ api: this.$SystemAPI }).finally(() => { + this.loaded = true + + // This bit removes code from the query params + // + // Vue router can't be used here because when on any child route there is no + // guarantee that the route has loaded and so it may redirect us to the root page. + // + // @todo dig a bit deeper if there is a better vue-like solution; atm none were ok. + const url = new URL(window.location.href) + if (url.searchParams.get('code')) { + url.searchParams.delete('code') + window.location.replace(url.toString()) + } + }) + }).catch((err) => { + if (err instanceof Error && err.message === 'Unauthenticated') { + // user not logged-in, + // start with authentication flow + this.$auth.startAuthenticationFlow() + return + } + + throw err + }) + }, + + methods: { + /** + * Registers event listener for websocket messages and + * routes them depending on their type + */ + websocket () { + // cross-link auth & websocket so that ws can use the right access token + + websocket.init(this) + + // register event listener for workflow messages + this.$on('websocket-message', ({ data }) => { + const msg = JSON.parse(data) + switch (msg['@type']) { + case 'workflowSessionPrompt': + this.$store.dispatch('wfPrompts/new', msg['@value']) + break + + case 'workflowSessionResumed': + this.$store.dispatch('wfPrompts/clear', msg['@value']) + break + + case 'reminder': + this.$Reminder.enqueueRaw(msg['@value']) + break + + case 'error': + console.error('websocket message with error', msg['@value']) + } + }) + }, + }, + + router, + store, + i18n: i18n(Vue, + { app: 'corteza-webapp-compose' }, + 'block', + 'chart', + 'field', + 'general', + 'module', + 'namespace', + 'navigation', + 'notification', + 'onboarding', + 'page', + 'permissions', + 'preview', + 'sidebar', + 'resource-translator', + ), + + // Any additional options we want to merge + ...options, + } + + return new Vue(options) +} diff --git a/client/web/compose/src/assets/PageBlocks/Automation.png b/client/web/compose/src/assets/PageBlocks/Automation.png new file mode 100644 index 000000000..e5b53d84e Binary files /dev/null and b/client/web/compose/src/assets/PageBlocks/Automation.png differ diff --git a/client/web/compose/src/assets/PageBlocks/Calendar.png b/client/web/compose/src/assets/PageBlocks/Calendar.png new file mode 100644 index 000000000..8e5ca0624 Binary files /dev/null and b/client/web/compose/src/assets/PageBlocks/Calendar.png differ diff --git a/client/web/compose/src/assets/PageBlocks/Chart.png b/client/web/compose/src/assets/PageBlocks/Chart.png new file mode 100644 index 000000000..88f130ee9 Binary files /dev/null and b/client/web/compose/src/assets/PageBlocks/Chart.png differ diff --git a/client/web/compose/src/assets/PageBlocks/Comment.png b/client/web/compose/src/assets/PageBlocks/Comment.png new file mode 100644 index 000000000..1367ce32a Binary files /dev/null and b/client/web/compose/src/assets/PageBlocks/Comment.png differ diff --git a/client/web/compose/src/assets/PageBlocks/Content.png b/client/web/compose/src/assets/PageBlocks/Content.png new file mode 100644 index 000000000..5430d5b73 Binary files /dev/null and b/client/web/compose/src/assets/PageBlocks/Content.png differ diff --git a/client/web/compose/src/assets/PageBlocks/File.png b/client/web/compose/src/assets/PageBlocks/File.png new file mode 100644 index 000000000..ae7033305 Binary files /dev/null and b/client/web/compose/src/assets/PageBlocks/File.png differ diff --git a/client/web/compose/src/assets/PageBlocks/IFrame.png b/client/web/compose/src/assets/PageBlocks/IFrame.png new file mode 100644 index 000000000..a47a6a12e Binary files /dev/null and b/client/web/compose/src/assets/PageBlocks/IFrame.png differ diff --git a/client/web/compose/src/assets/PageBlocks/Metric.png b/client/web/compose/src/assets/PageBlocks/Metric.png new file mode 100644 index 000000000..0ba004937 Binary files /dev/null and b/client/web/compose/src/assets/PageBlocks/Metric.png differ diff --git a/client/web/compose/src/assets/PageBlocks/Progress.png b/client/web/compose/src/assets/PageBlocks/Progress.png new file mode 100644 index 000000000..49bc0855e Binary files /dev/null and b/client/web/compose/src/assets/PageBlocks/Progress.png differ diff --git a/client/web/compose/src/assets/PageBlocks/Record.png b/client/web/compose/src/assets/PageBlocks/Record.png new file mode 100644 index 000000000..abf6efd45 Binary files /dev/null and b/client/web/compose/src/assets/PageBlocks/Record.png differ diff --git a/client/web/compose/src/assets/PageBlocks/RecordList.png b/client/web/compose/src/assets/PageBlocks/RecordList.png new file mode 100644 index 000000000..9cb79dd2a Binary files /dev/null and b/client/web/compose/src/assets/PageBlocks/RecordList.png differ diff --git a/client/web/compose/src/assets/PageBlocks/RecordOrganizer.png b/client/web/compose/src/assets/PageBlocks/RecordOrganizer.png new file mode 100644 index 000000000..bf958dbfc Binary files /dev/null and b/client/web/compose/src/assets/PageBlocks/RecordOrganizer.png differ diff --git a/client/web/compose/src/assets/PageBlocks/RecordRevisions.png b/client/web/compose/src/assets/PageBlocks/RecordRevisions.png new file mode 100644 index 000000000..e2a4655ae Binary files /dev/null and b/client/web/compose/src/assets/PageBlocks/RecordRevisions.png differ diff --git a/client/web/compose/src/assets/PageBlocks/Report.png b/client/web/compose/src/assets/PageBlocks/Report.png new file mode 100644 index 000000000..80dccbf5e Binary files /dev/null and b/client/web/compose/src/assets/PageBlocks/Report.png differ diff --git a/client/web/compose/src/assets/PageBlocks/SocialFeed.png b/client/web/compose/src/assets/PageBlocks/SocialFeed.png new file mode 100644 index 000000000..c81f1fc75 Binary files /dev/null and b/client/web/compose/src/assets/PageBlocks/SocialFeed.png differ diff --git a/client/web/compose/src/assets/PageBlocks/index.js b/client/web/compose/src/assets/PageBlocks/index.js new file mode 100644 index 000000000..4dcc96c55 --- /dev/null +++ b/client/web/compose/src/assets/PageBlocks/index.js @@ -0,0 +1,15 @@ +export const Content = require('./Content.png') +export const Chart = require('./Chart.png') +export const SocialFeed = require('./SocialFeed.png') +export const Record = require('./Record.png') +export const RecordList = require('./RecordList.png') +export const Automation = require('./Automation.png') +export const Calendar = require('./Calendar.png') +export const File = require('./File.png') +export const RecordOrganizer = require('./RecordOrganizer.png') +export const RecordRevisions = require('./RecordRevisions.png') +export const IFrame = require('./IFrame.png') +export const Metric = require('./Metric.png') +export const Comment = require('./Comment.png') +export const Report = require('./Report.png') +export const Progress = require('./Progress.png') diff --git a/client/web/compose/src/common/scripts.js b/client/web/compose/src/common/scripts.js new file mode 100644 index 000000000..20cc44eda --- /dev/null +++ b/client/web/compose/src/common/scripts.js @@ -0,0 +1,14 @@ +export const rgbaRegex = /^rgba\((\d+),.*?(\d+),.*?(\d+),.*?(\d*\.?\d*)\)$/ + +const ln = (n) => Math.round(n < 0 ? 255 + n : (n > 255) ? n - 255 : n) +export const toRGBA = ([r, g, b, a]) => + `rgba(${ln(r)}, ${ln(g)}, ${ln(b)}, ${a})` + +export const removeDup = (set, key) => { + const exists = new Set() + return set.filter(s => { + const isN = !exists.has(s[key]) + exists.add(s[key]) + return isN + }) +} diff --git a/client/web/compose/src/components/Admin/C3.js b/client/web/compose/src/components/Admin/C3.js new file mode 100644 index 000000000..6ca324248 --- /dev/null +++ b/client/web/compose/src/components/Admin/C3.js @@ -0,0 +1,3 @@ +export { default as FieldRowEdit } from './Module/FieldRowEdit.c3' +// disabled: uses store +// export { default as Tree } from './Page/Tree.c3' diff --git a/client/web/compose/src/components/Admin/EditorToolbar.c3.js b/client/web/compose/src/components/Admin/EditorToolbar.c3.js new file mode 100644 index 000000000..ccc24e745 --- /dev/null +++ b/client/web/compose/src/components/Admin/EditorToolbar.c3.js @@ -0,0 +1,24 @@ +// eslint-disable-next-line +import { default as component } from './EditorToolbar.vue' +import { components } from '@cortezaproject/corteza-vue' +const { checkbox } = components.C3.controls + +const props = { + backLink: {}, + hideDelete: false, + hideSave: false, + disableSave: false, +} + +export default { + name: 'Editor toolbar', + group: ['Admin'], + component, + props, + + controls: [ + checkbox('Hide delete', 'hideDelete'), + checkbox('Hide save', 'hideSave'), + checkbox('Disable save', 'disableSave'), + ], +} diff --git a/client/web/compose/src/components/Admin/EditorToolbar.vue b/client/web/compose/src/components/Admin/EditorToolbar.vue new file mode 100644 index 000000000..273bd7a89 --- /dev/null +++ b/client/web/compose/src/components/Admin/EditorToolbar.vue @@ -0,0 +1,161 @@ + + + diff --git a/client/web/compose/src/components/Admin/Export.vue b/client/web/compose/src/components/Admin/Export.vue new file mode 100644 index 000000000..ec98c30c1 --- /dev/null +++ b/client/web/compose/src/components/Admin/Export.vue @@ -0,0 +1,46 @@ + + + diff --git a/client/web/compose/src/components/Admin/Import.vue b/client/web/compose/src/components/Admin/Import.vue new file mode 100644 index 000000000..62d7dabdb --- /dev/null +++ b/client/web/compose/src/components/Admin/Import.vue @@ -0,0 +1,225 @@ + + + + diff --git a/client/web/compose/src/components/Admin/Module/DalFieldStoreEncoding.vue b/client/web/compose/src/components/Admin/Module/DalFieldStoreEncoding.vue new file mode 100644 index 000000000..dc19fa47d --- /dev/null +++ b/client/web/compose/src/components/Admin/Module/DalFieldStoreEncoding.vue @@ -0,0 +1,174 @@ + + diff --git a/client/web/compose/src/components/Admin/Module/DalSettings.vue b/client/web/compose/src/components/Admin/Module/DalSettings.vue new file mode 100644 index 000000000..9027ef6a7 --- /dev/null +++ b/client/web/compose/src/components/Admin/Module/DalSettings.vue @@ -0,0 +1,223 @@ + + + diff --git a/client/web/compose/src/components/Admin/Module/DataPrivacySettings.vue b/client/web/compose/src/components/Admin/Module/DataPrivacySettings.vue new file mode 100644 index 000000000..58f8a0a61 --- /dev/null +++ b/client/web/compose/src/components/Admin/Module/DataPrivacySettings.vue @@ -0,0 +1,72 @@ + + + diff --git a/client/web/compose/src/components/Admin/Module/DiscoverySettings.vue b/client/web/compose/src/components/Admin/Module/DiscoverySettings.vue new file mode 100644 index 000000000..fb5fb6fe9 --- /dev/null +++ b/client/web/compose/src/components/Admin/Module/DiscoverySettings.vue @@ -0,0 +1,193 @@ + + + + + diff --git a/client/web/compose/src/components/Admin/Module/FederationSettings.vue b/client/web/compose/src/components/Admin/Module/FederationSettings.vue new file mode 100644 index 000000000..7089b0a3e --- /dev/null +++ b/client/web/compose/src/components/Admin/Module/FederationSettings.vue @@ -0,0 +1,734 @@ + + + + diff --git a/client/web/compose/src/components/Admin/Module/FieldBoolTranslator.vue b/client/web/compose/src/components/Admin/Module/FieldBoolTranslator.vue new file mode 100644 index 000000000..af314616b --- /dev/null +++ b/client/web/compose/src/components/Admin/Module/FieldBoolTranslator.vue @@ -0,0 +1,136 @@ + + + diff --git a/client/web/compose/src/components/Admin/Module/FieldRowEdit.c3.js b/client/web/compose/src/components/Admin/Module/FieldRowEdit.c3.js new file mode 100644 index 000000000..2f96e1f0b --- /dev/null +++ b/client/web/compose/src/components/Admin/Module/FieldRowEdit.c3.js @@ -0,0 +1,72 @@ +// eslint-disable-next-line +import { default as component } from './FieldRowEdit.vue' +import { compose } from '@cortezaproject/corteza-js' +import { components } from '@cortezaproject/corteza-vue' +const { checkbox } = components.C3.controls + +const props = { + value: { + name: 'Name', + label: 'Label', + kind: 'String', + cap: { + configurable: true, + multi: true, + required: true, + private: false, + }, + isMulti: true, + isRequired: true, + fieldId: '453534534534343', + isValid: true, + }, + module: new compose.Module({ + namespaceID: '3242343234', + moduleID: '999999442', + }), + isDuplicate: false, + canGrant: true, + hasRecords: false, +} + +export default { + name: 'Field row edit', + group: ['Admin', 'Module'], + component, + props, + controls: [ + checkbox('configurable', 'cap.configurable'), + checkbox('multi', 'value.cap.multi'), + checkbox('required', 'value.cap.required'), + checkbox('private', 'value.cap.private'), + checkbox('isMulti', 'value.isMulti'), + checkbox('isRequired', 'value.isRequired'), + checkbox('isValid', 'value.isValid'), + ], + + scenarios: [ + { + label: 'Full form', + props, + }, + { + label: 'Empty form', + props: { + ...props, + canGrant: false, + hasRecords: true, + value: { + cap: { + configurable: false, + multi: false, + required: false, + private: false, + }, + isMulti: false, + isRequired: false, + isValid: false, + }, + }, + }, + ], +} diff --git a/client/web/compose/src/components/Admin/Module/FieldRowEdit.vue b/client/web/compose/src/components/Admin/Module/FieldRowEdit.vue new file mode 100644 index 000000000..24b4c7bdf --- /dev/null +++ b/client/web/compose/src/components/Admin/Module/FieldRowEdit.vue @@ -0,0 +1,195 @@ + + + + diff --git a/client/web/compose/src/components/Admin/Module/FieldRowView.vue b/client/web/compose/src/components/Admin/Module/FieldRowView.vue new file mode 100644 index 000000000..b95f9260c --- /dev/null +++ b/client/web/compose/src/components/Admin/Module/FieldRowView.vue @@ -0,0 +1,26 @@ + + + diff --git a/client/web/compose/src/components/Admin/Module/FieldSelectTranslator.vue b/client/web/compose/src/components/Admin/Module/FieldSelectTranslator.vue new file mode 100644 index 000000000..467788c60 --- /dev/null +++ b/client/web/compose/src/components/Admin/Module/FieldSelectTranslator.vue @@ -0,0 +1,147 @@ + + + diff --git a/client/web/compose/src/components/Admin/Module/FieldTranslator.vue b/client/web/compose/src/components/Admin/Module/FieldTranslator.vue new file mode 100644 index 000000000..87e55f4fc --- /dev/null +++ b/client/web/compose/src/components/Admin/Module/FieldTranslator.vue @@ -0,0 +1,130 @@ + + + diff --git a/client/web/compose/src/components/Admin/Module/ModuleTranslator.vue b/client/web/compose/src/components/Admin/Module/ModuleTranslator.vue new file mode 100644 index 000000000..a5ee98a20 --- /dev/null +++ b/client/web/compose/src/components/Admin/Module/ModuleTranslator.vue @@ -0,0 +1,113 @@ + + + diff --git a/client/web/compose/src/components/Admin/Module/RecordRevisionsSettings.vue b/client/web/compose/src/components/Admin/Module/RecordRevisionsSettings.vue new file mode 100644 index 000000000..85efbfeb4 --- /dev/null +++ b/client/web/compose/src/components/Admin/Module/RecordRevisionsSettings.vue @@ -0,0 +1,43 @@ + + + diff --git a/client/web/compose/src/components/Admin/Module/Records/ColumnPicker.vue b/client/web/compose/src/components/Admin/Module/Records/ColumnPicker.vue new file mode 100644 index 000000000..274e9f6ad --- /dev/null +++ b/client/web/compose/src/components/Admin/Module/Records/ColumnPicker.vue @@ -0,0 +1,85 @@ + + + + + diff --git a/client/web/compose/src/components/Admin/Module/RelatedPages.vue b/client/web/compose/src/components/Admin/Module/RelatedPages.vue new file mode 100644 index 000000000..457c52f3a --- /dev/null +++ b/client/web/compose/src/components/Admin/Module/RelatedPages.vue @@ -0,0 +1,184 @@ + + + + + diff --git a/client/web/compose/src/components/Admin/Module/Validation.vue b/client/web/compose/src/components/Admin/Module/Validation.vue new file mode 100644 index 000000000..ad9be7b78 --- /dev/null +++ b/client/web/compose/src/components/Admin/Module/Validation.vue @@ -0,0 +1,124 @@ + + + diff --git a/client/web/compose/src/components/Admin/Module/encoding-strategy.js b/client/web/compose/src/components/Admin/Module/encoding-strategy.js new file mode 100644 index 000000000..e22220797 --- /dev/null +++ b/client/web/compose/src/components/Admin/Module/encoding-strategy.js @@ -0,0 +1,54 @@ + +export const types = { + Omit: 'omit', + Plain: 'plain', + Alias: 'alias', + JSON: 'json', +} + +// default for system fields means null! +export function systemFieldStrategyConfig (strategy, config) { + switch (strategy) { + case types.JSON: + return { [strategy]: { ident: config.ident } } + case types.Alias: + return { [strategy]: { ident: config.ident } } + case types.Omit: + return { [strategy]: true } + + default: + return null + } +} + +// default for module fields means JSON! +export function moduleFieldStrategyConfig (strategy, config) { + switch (strategy) { + case types.Plain: + return { [types.Plain]: {} } + case types.Alias: + return { [strategy]: { ident: config.ident } } + case types.JSON: + return { [strategy]: { ident: config.ident } } + case types.Omit: + return { [strategy]: true } + + default: + return null + } +} + +// extract ident from config +export function defaultConfigDraft (config, ident) { + if (typeof config !== 'object') { + return { ident, def: 1 } + } + + for (const t of [types.Alias, types.JSON]) { + if (config[t] && config[t].ident) { + return { ...config[t] } + } + } + + return { ident, def: 2 } +} diff --git a/client/web/compose/src/components/Admin/Page/Builder/Selector.vue b/client/web/compose/src/components/Admin/Page/Builder/Selector.vue new file mode 100644 index 000000000..636cd9cd9 --- /dev/null +++ b/client/web/compose/src/components/Admin/Page/Builder/Selector.vue @@ -0,0 +1,146 @@ + + diff --git a/client/web/compose/src/components/Admin/Page/PageTranslator.vue b/client/web/compose/src/components/Admin/Page/PageTranslator.vue new file mode 100644 index 000000000..51d03c24c --- /dev/null +++ b/client/web/compose/src/components/Admin/Page/PageTranslator.vue @@ -0,0 +1,223 @@ + + + diff --git a/client/web/compose/src/components/Admin/Page/Tree.c3.js b/client/web/compose/src/components/Admin/Page/Tree.c3.js new file mode 100644 index 000000000..97b7cd9cd --- /dev/null +++ b/client/web/compose/src/components/Admin/Page/Tree.c3.js @@ -0,0 +1,69 @@ +// eslint-disable-next-line +import { default as component } from './Tree.vue' +import { compose } from '@cortezaproject/corteza-js' +// import { components } from '@cortezaproject/corteza-vue' +// const { checkbox, input } = components.C3.controls + +// TypeError: Cannot read property 'getters' of undefined at VueComponent.mappedGetter +const props = { + namespace: new compose.Namespace({ + canCreatePage: true, + canGrant: true, + namespaceID: '', + }), + value: [ + { + pageID: '44444444444', + moduleID: '324234324', + title: 'Home', + handle: 'Home', + visible: true, + canGrant: true, + canUpdatePage: true, + blocks: [{ + kind: 'RecordList', + title: 'My New Leads', + }], + }, + { + pageID: '456454644444', + moduleID: '004234324', + title: 'Test', + handle: 'Test', + visible: true, + canGrant: true, + canUpdatePage: true, + blocks: [{ + kind: 'RecordList', + title: 'My New Leads', + }], + }, + ], + parentID: '', + level: 0, +} + +export default { + name: 'Tree WIP', + group: ['Admin', 'Page'], + component, + props, + controls: [], + // controls: [ + // checkbox('', ''), + // input(' of step', ''), + // ], + + // scenarios: [ + // { + // label: 'Full form', + // props, + // }, + // { + // label: 'Empty form', + // props: { + // ...props, + // }, + // }, + // ], +} diff --git a/client/web/compose/src/components/Admin/Page/Tree.vue b/client/web/compose/src/components/Admin/Page/Tree.vue new file mode 100644 index 000000000..f53d109e2 --- /dev/null +++ b/client/web/compose/src/components/Admin/Page/Tree.vue @@ -0,0 +1,253 @@ + + + + diff --git a/client/web/compose/src/components/C3.js b/client/web/compose/src/components/C3.js new file mode 100644 index 000000000..e4baab832 --- /dev/null +++ b/client/web/compose/src/components/C3.js @@ -0,0 +1,25 @@ +import * as admin from './Admin/C3' +import * as chart from './Chart/C3' +import * as common from './Common/C3' +import * as moduleFields from './ModuleFields/C3' +import * as namespace from './Namespaces/C3' +import * as publicCmps from './Public/C3' +import * as translator from './Translator/C3' +import { pageBlockBase, pageBlockConfigurators } from './PageBlocks/C3' + +import FileConfigurator from './Admin/EditorToolbar.c3' +// import * as C3 from '@cortezaproject/corteza-vue' + +export default { + ...admin, + ...chart, + ...common, + ...moduleFields, + ...namespace, + ...pageBlockConfigurators, + ...pageBlockBase, + ...publicCmps, + ...translator, + FileConfigurator, + // ...C3, +} diff --git a/client/web/compose/src/components/Chart/C3.js b/client/web/compose/src/components/Chart/C3.js new file mode 100644 index 000000000..a10917af5 --- /dev/null +++ b/client/web/compose/src/components/Chart/C3.js @@ -0,0 +1,2 @@ +export { default as ReportEdit } from './Report/ReportEdit.c3' +export { default as ReportItem } from './ReportItem.c3' diff --git a/client/web/compose/src/components/Chart/ChartTranslator.vue b/client/web/compose/src/components/Chart/ChartTranslator.vue new file mode 100644 index 000000000..4b5f48fe0 --- /dev/null +++ b/client/web/compose/src/components/Chart/ChartTranslator.vue @@ -0,0 +1,145 @@ + + + diff --git a/client/web/compose/src/components/Chart/Report/FunnelChart.vue b/client/web/compose/src/components/Chart/Report/FunnelChart.vue new file mode 100644 index 000000000..2faeb79b5 --- /dev/null +++ b/client/web/compose/src/components/Chart/Report/FunnelChart.vue @@ -0,0 +1,82 @@ + + + + + diff --git a/client/web/compose/src/components/Chart/Report/GaugeChart.vue b/client/web/compose/src/components/Chart/Report/GaugeChart.vue new file mode 100644 index 000000000..6f5bedf69 --- /dev/null +++ b/client/web/compose/src/components/Chart/Report/GaugeChart.vue @@ -0,0 +1,116 @@ + + + diff --git a/client/web/compose/src/components/Chart/Report/GenericChart.vue b/client/web/compose/src/components/Chart/Report/GenericChart.vue new file mode 100644 index 000000000..4f1d642e7 --- /dev/null +++ b/client/web/compose/src/components/Chart/Report/GenericChart.vue @@ -0,0 +1,251 @@ + + + + diff --git a/client/web/compose/src/components/Chart/Report/ReportEdit.c3.js b/client/web/compose/src/components/Chart/Report/ReportEdit.c3.js new file mode 100644 index 000000000..c1cde41bb --- /dev/null +++ b/client/web/compose/src/components/Chart/Report/ReportEdit.c3.js @@ -0,0 +1,89 @@ +// eslint-disable-next-line +import { default as component } from './ReportEdit.vue' + +const props = { + report: { + moduleID: '', + filter: '', + colorScheme: '#fffff', + metrics: [ + { + aggregate: 'AVG', + field: 'count', + moduleID: '', + }, + ], + dimensions: [{ + field: 'Rating', + modifier: '(no grouping / buckets)', + skipMissing: true, + default: '', + }], + }, + modules: [ + { + moduleID: '', + handle: 'Pool', + name: 'Pool', + fields: [{ + kind: 'String', + name: 'Sample', + options: { + multiLine: false, + useRichTextEditor: false, + }, + }], + }, + { + moduleID: '', + handle: 'Party', + name: 'Party', + fields: [{ + kind: 'String', + name: 'Party', + options: { + multiLine: false, + useRichTextEditor: false, + }, + }], + }, + { + moduleID: '', + handle: 'Test', + name: 'Test', + fields: [{ + kind: 'String', + name: 'Test', + options: { + multiLine: false, + useRichTextEditor: false, + }, + }], + }, + ], + supportedMetrics: -1, + dimensionFieldKind: ['DateTime', 'Select', 'Number', 'Bool', 'String'], + unSkippable: false, +} + +export default { + name: 'Edit', + group: ['Chart', 'Report'], + component, + props, + controls: [], + + scenarios: [ + { + label: 'Full form', + props, + }, + { + label: 'Empty form', + props: { + ...props, + modules: [], + }, + }, + ], +} diff --git a/client/web/compose/src/components/Chart/Report/ReportEdit.vue b/client/web/compose/src/components/Chart/Report/ReportEdit.vue new file mode 100644 index 000000000..ece3578e6 --- /dev/null +++ b/client/web/compose/src/components/Chart/Report/ReportEdit.vue @@ -0,0 +1,430 @@ + + + diff --git a/client/web/compose/src/components/Chart/Report/base.vue b/client/web/compose/src/components/Chart/Report/base.vue new file mode 100644 index 000000000..d17032c8b --- /dev/null +++ b/client/web/compose/src/components/Chart/Report/base.vue @@ -0,0 +1,59 @@ + diff --git a/client/web/compose/src/components/Chart/Report/index.js b/client/web/compose/src/components/Chart/Report/index.js new file mode 100644 index 000000000..dc04a90cf --- /dev/null +++ b/client/web/compose/src/components/Chart/Report/index.js @@ -0,0 +1,9 @@ +import FunnelChart from './FunnelChart' +import GenericChart from './GenericChart' +import GaugeChart from './GaugeChart' + +export default { + FunnelChart, + GenericChart, + GaugeChart, +} diff --git a/client/web/compose/src/components/Chart/ReportItem.c3.js b/client/web/compose/src/components/Chart/ReportItem.c3.js new file mode 100644 index 000000000..4825e05d7 --- /dev/null +++ b/client/web/compose/src/components/Chart/ReportItem.c3.js @@ -0,0 +1,16 @@ +// eslint-disable-next-line +import { default as component } from './ReportItem.vue' + +const props = { + report: {}, + fixed: true, +} + +export default { + name: 'Report item', + group: ['Chart'], + component, + props, + controls: [ + ], +} diff --git a/client/web/compose/src/components/Chart/ReportItem.vue b/client/web/compose/src/components/Chart/ReportItem.vue new file mode 100644 index 000000000..b3ad8a36e --- /dev/null +++ b/client/web/compose/src/components/Chart/ReportItem.vue @@ -0,0 +1,58 @@ + + + + + diff --git a/client/web/compose/src/components/Chart/index.vue b/client/web/compose/src/components/Chart/index.vue new file mode 100644 index 000000000..28ea3a70b --- /dev/null +++ b/client/web/compose/src/components/Chart/index.vue @@ -0,0 +1,198 @@ + + + diff --git a/client/web/compose/src/components/Common/C3.js b/client/web/compose/src/components/Common/C3.js new file mode 100644 index 000000000..b57a7412b --- /dev/null +++ b/client/web/compose/src/components/Common/C3.js @@ -0,0 +1,7 @@ +export { default as CircleStep } from './CircleStep.c3' +export { default as Grid } from './Grid.c3' +export { default as Hint } from './Hint.c3' +// disabled: waiting for TJ to explain te use +// export { default as ItemPicker } from './ItemPicker.c3' +export { default as RecordListFilter } from './RecordListFilter.c3' +export { default as FieldPicker } from './FieldPicker.c3' diff --git a/client/web/compose/src/components/Common/CircleStep.c3.js b/client/web/compose/src/components/Common/CircleStep.c3.js new file mode 100644 index 000000000..9ff7949b4 --- /dev/null +++ b/client/web/compose/src/components/Common/CircleStep.c3.js @@ -0,0 +1,26 @@ +// eslint-disable-next-line +import { default as component } from './CircleStep.vue' +import { components } from '@cortezaproject/corteza-vue' +const { checkbox, input } = components.C3.controls + +const props = { + done: true, + disabled: false, + optional: false, + small: false, + stepNumber: '111', +} + +export default { + name: 'Circle step', + group: ['Common'], + component, + props, + + controls: [ + checkbox('Done', 'done'), + checkbox('Disabled', 'disabled'), + checkbox('Small', 'small'), + input('Number of step', 'stepNumber'), + ], +} diff --git a/client/web/compose/src/components/Common/CircleStep.vue b/client/web/compose/src/components/Common/CircleStep.vue new file mode 100644 index 000000000..957975715 --- /dev/null +++ b/client/web/compose/src/components/Common/CircleStep.vue @@ -0,0 +1,84 @@ + + + + + diff --git a/client/web/compose/src/components/Common/FieldPicker.c3.js b/client/web/compose/src/components/Common/FieldPicker.c3.js new file mode 100644 index 000000000..b516c9f99 --- /dev/null +++ b/client/web/compose/src/components/Common/FieldPicker.c3.js @@ -0,0 +1,31 @@ +// eslint-disable-next-line +import { default as component } from './FieldPicker.vue' +import { compose } from '@cortezaproject/corteza-js' +import { components } from '@cortezaproject/corteza-vue' +const { checkbox } = components.C3.controls + +const f1 = new compose.ModuleField({ name: 'f1', label: 'Field One Label' }) +const f2 = new compose.ModuleField({ name: 'f2' }) +const f3 = new compose.ModuleField({ name: 'f3', isRequired: true }) +const f4 = new compose.ModuleField({ name: 'f4', label: 'required with label', isRequired: true }) + +const module = new compose.Module({ + name: 'modName', + fields: [f1, f2, f3, f4], +}) + +const props = { + module, + fields: [f2, f4], + disableSystemFields: false, +} + +export default { + name: 'FieldPicker', + group: ['Picker'], + component, + props, + controls: [ + checkbox('Disabled system fields', 'disableSystemFields'), + ], +} diff --git a/client/web/compose/src/components/Common/FieldPicker.vue b/client/web/compose/src/components/Common/FieldPicker.vue new file mode 100644 index 000000000..9e2fdefa5 --- /dev/null +++ b/client/web/compose/src/components/Common/FieldPicker.vue @@ -0,0 +1,186 @@ + + + diff --git a/client/web/compose/src/components/Common/Grid.c3.js b/client/web/compose/src/components/Common/Grid.c3.js new file mode 100644 index 000000000..7d58783b8 --- /dev/null +++ b/client/web/compose/src/components/Common/Grid.c3.js @@ -0,0 +1,53 @@ +// eslint-disable-next-line +import { default as component } from './Grid.vue' +import { components } from '@cortezaproject/corteza-vue' +const { checkbox } = components.C3.controls + +const props = { + editable: true, + blocks: [ + { + description: 'Description', + kind: 'Chart', + options: { chartID: '242313186186166275' }, + style: { + variants: { + bodyBg: 'white', + border: 'primary', + headerBg: 'white', + headerText: 'primary', + }, + title: 'Title', + wrap: { + kind: 'card', + }, + }, + title: 'Leads by type', + xywh: [9, 32, 3, 8], + }, + ], +} + +export default { + name: 'Grid', + group: ['Common'], + component, + props, + controls: [ + checkbox('Editable', 'editable'), + ], + + scenarios: [ + { + label: 'Full form', + props, + }, + { + label: 'Empty form', + props: { + ...props, + editable: false, + }, + }, + ], +} diff --git a/client/web/compose/src/components/Common/Grid.vue b/client/web/compose/src/components/Common/Grid.vue new file mode 100644 index 000000000..206168540 --- /dev/null +++ b/client/web/compose/src/components/Common/Grid.vue @@ -0,0 +1,200 @@ + + + + diff --git a/client/web/compose/src/components/Common/Hint.c3.js b/client/web/compose/src/components/Common/Hint.c3.js new file mode 100644 index 000000000..ed545b0f2 --- /dev/null +++ b/client/web/compose/src/components/Common/Hint.c3.js @@ -0,0 +1,15 @@ +// eslint-disable-next-line +import { default as component } from './Hint.vue' + +const props = { + text: 'I\'m the hint!', + id: '34324', +} + +export default { + name: 'Hint', + group: ['Common'], + component, + props, + controls: [], +} diff --git a/client/web/compose/src/components/Common/Hint.vue b/client/web/compose/src/components/Common/Hint.vue new file mode 100644 index 000000000..f22b108aa --- /dev/null +++ b/client/web/compose/src/components/Common/Hint.vue @@ -0,0 +1,36 @@ + + + diff --git a/client/web/compose/src/components/Common/Module/FieldExpressions.vue b/client/web/compose/src/components/Common/Module/FieldExpressions.vue new file mode 100644 index 000000000..42439cc94 --- /dev/null +++ b/client/web/compose/src/components/Common/Module/FieldExpressions.vue @@ -0,0 +1,51 @@ + + diff --git a/client/web/compose/src/components/Common/RecordListFilter.c3.js b/client/web/compose/src/components/Common/RecordListFilter.c3.js new file mode 100644 index 000000000..6fb7c5906 --- /dev/null +++ b/client/web/compose/src/components/Common/RecordListFilter.c3.js @@ -0,0 +1,31 @@ +// eslint-disable-next-line +import { default as component } from './RecordListFilter.vue' +import { compose } from '@cortezaproject/corteza-js' + +const props = { + selectedField: { name: 'CaseNumber' }, + namespace: new compose.Namespace(), + module: new compose.Module({ + fields: [ + { + isMulti: false, + label: 'Account Name', + name: 'AccountId', + }, + ], + }), + recordListFilter: [{ + groupCondition: '', + filter: [{ + name: '', + }], + }], +} + +export default { + name: 'Record list filter', + group: ['Common'], + component, + props, + controls: [], +} diff --git a/client/web/compose/src/components/Common/RecordListFilter.vue b/client/web/compose/src/components/Common/RecordListFilter.vue new file mode 100644 index 000000000..f9f1ffd8e --- /dev/null +++ b/client/web/compose/src/components/Common/RecordListFilter.vue @@ -0,0 +1,588 @@ + + + + + + diff --git a/client/web/compose/src/components/Common/RecordToolbar.vue b/client/web/compose/src/components/Common/RecordToolbar.vue new file mode 100644 index 000000000..e995f6f0f --- /dev/null +++ b/client/web/compose/src/components/Common/RecordToolbar.vue @@ -0,0 +1,218 @@ + + + + diff --git a/client/web/compose/src/components/ModuleFields/C3.js b/client/web/compose/src/components/ModuleFields/C3.js new file mode 100644 index 000000000..8945dbc54 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/C3.js @@ -0,0 +1,2 @@ +export { default as Pagination } from './Common/Pagination.c3' +// export { default as Configurator } from './Configurator/Configurator.c3' diff --git a/client/web/compose/src/components/ModuleFields/Common/Pagination.c3.js b/client/web/compose/src/components/ModuleFields/Common/Pagination.c3.js new file mode 100644 index 000000000..85cfbdf88 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Common/Pagination.c3.js @@ -0,0 +1,34 @@ +// eslint-disable-next-line +import { default as component } from './Pagination.vue' +import { components } from '@cortezaproject/corteza-vue' +const { checkbox } = components.C3.controls + +const props = { + hasPrevPage: true, + hasNextPage: true, +} + +export default { + name: 'Pagination', + group: ['ModuleFields'], + component, + props, + controls: [ + checkbox('HasPrevPage', 'hasPrevPage'), + checkbox('HasNextPage', 'hasNextPage'), + ], + + scenarios: [ + { + label: 'Full form', + props, + }, + { + label: 'Empty form', + props: { + hasPrevPage: false, + hasNextPage: false, + }, + }, + ], +} diff --git a/client/web/compose/src/components/ModuleFields/Common/Pagination.vue b/client/web/compose/src/components/ModuleFields/Common/Pagination.vue new file mode 100644 index 000000000..eab29a021 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Common/Pagination.vue @@ -0,0 +1,42 @@ + + + diff --git a/client/web/compose/src/components/ModuleFields/Configurator/Bool.vue b/client/web/compose/src/components/ModuleFields/Configurator/Bool.vue new file mode 100644 index 000000000..590117c9d --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Configurator/Bool.vue @@ -0,0 +1,71 @@ + + + diff --git a/client/web/compose/src/components/ModuleFields/Configurator/Configurator.c3.js b/client/web/compose/src/components/ModuleFields/Configurator/Configurator.c3.js new file mode 100644 index 000000000..7dd08b7e6 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Configurator/Configurator.c3.js @@ -0,0 +1,23 @@ +// eslint-disable-next-line +import { compose } from '@cortezaproject/corteza-js' +import * as fieldTypes from './loader' + +console.error({ ...fieldTypes }) +const props = { + namespace: new compose.Namespace(), + module: new compose.Module(), + field: new compose.ModuleFieldBool({ + options: { + trueLabel: 'true', + falseLabel: 'false', + }, + }), +} + +export default { + name: { ...fieldTypes }, + group: ['ModuleFields', 'Configurator'], + ...fieldTypes, + props, + controls: [], +} diff --git a/client/web/compose/src/components/ModuleFields/Configurator/DateTime.vue b/client/web/compose/src/components/ModuleFields/Configurator/DateTime.vue new file mode 100644 index 000000000..054bb55c9 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Configurator/DateTime.vue @@ -0,0 +1,71 @@ + + + diff --git a/client/web/compose/src/components/ModuleFields/Configurator/Email.vue b/client/web/compose/src/components/ModuleFields/Configurator/Email.vue new file mode 100644 index 000000000..6cf98cebe --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Configurator/Email.vue @@ -0,0 +1,19 @@ + + + diff --git a/client/web/compose/src/components/ModuleFields/Configurator/File.vue b/client/web/compose/src/components/ModuleFields/Configurator/File.vue new file mode 100644 index 000000000..68439a199 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Configurator/File.vue @@ -0,0 +1,76 @@ + + + diff --git a/client/web/compose/src/components/ModuleFields/Configurator/Geometry.vue b/client/web/compose/src/components/ModuleFields/Configurator/Geometry.vue new file mode 100644 index 000000000..3e1a389d5 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Configurator/Geometry.vue @@ -0,0 +1,50 @@ + + + diff --git a/client/web/compose/src/components/ModuleFields/Configurator/Number.vue b/client/web/compose/src/components/ModuleFields/Configurator/Number.vue new file mode 100644 index 000000000..26a7aa08b --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Configurator/Number.vue @@ -0,0 +1,378 @@ + + + diff --git a/client/web/compose/src/components/ModuleFields/Configurator/Record.vue b/client/web/compose/src/components/ModuleFields/Configurator/Record.vue new file mode 100644 index 000000000..7d24fb2e5 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Configurator/Record.vue @@ -0,0 +1,207 @@ + + + diff --git a/client/web/compose/src/components/ModuleFields/Configurator/Select.vue b/client/web/compose/src/components/ModuleFields/Configurator/Select.vue new file mode 100644 index 000000000..788d4aa22 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Configurator/Select.vue @@ -0,0 +1,162 @@ + + + diff --git a/client/web/compose/src/components/ModuleFields/Configurator/String.vue b/client/web/compose/src/components/ModuleFields/Configurator/String.vue new file mode 100644 index 000000000..bd266c950 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Configurator/String.vue @@ -0,0 +1,23 @@ + + + diff --git a/client/web/compose/src/components/ModuleFields/Configurator/Url.vue b/client/web/compose/src/components/ModuleFields/Configurator/Url.vue new file mode 100644 index 000000000..1c92c7e62 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Configurator/Url.vue @@ -0,0 +1,41 @@ + + + diff --git a/client/web/compose/src/components/ModuleFields/Configurator/User.vue b/client/web/compose/src/components/ModuleFields/Configurator/User.vue new file mode 100644 index 000000000..e2e15fb45 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Configurator/User.vue @@ -0,0 +1,73 @@ + + + diff --git a/client/web/compose/src/components/ModuleFields/Configurator/base.vue b/client/web/compose/src/components/ModuleFields/Configurator/base.vue new file mode 100644 index 000000000..ffb15c11e --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Configurator/base.vue @@ -0,0 +1,34 @@ + diff --git a/client/web/compose/src/components/ModuleFields/Configurator/basic.vue b/client/web/compose/src/components/ModuleFields/Configurator/basic.vue new file mode 100644 index 000000000..024a6ff43 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Configurator/basic.vue @@ -0,0 +1,393 @@ + + + diff --git a/client/web/compose/src/components/ModuleFields/Configurator/index.vue b/client/web/compose/src/components/ModuleFields/Configurator/index.vue new file mode 100644 index 000000000..9ff39cc74 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Configurator/index.vue @@ -0,0 +1,128 @@ + + + + diff --git a/client/web/compose/src/components/ModuleFields/Configurator/loader.js b/client/web/compose/src/components/ModuleFields/Configurator/loader.js new file mode 100644 index 000000000..7d7fae280 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Configurator/loader.js @@ -0,0 +1,11 @@ +export { default as Record } from './Record' +export { default as Select } from './Select' +export { default as String } from './String' +export { default as Number } from './Number' +export { default as DateTime } from './DateTime' +export { default as Bool } from './Bool' +export { default as Url } from './Url' +export { default as Email } from './Email' +export { default as User } from './User' +export { default as File } from './File' +export { default as Geometry } from './Geometry' diff --git a/client/web/compose/src/components/ModuleFields/Configurator/multi.vue b/client/web/compose/src/components/ModuleFields/Configurator/multi.vue new file mode 100644 index 000000000..dddc557a1 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Configurator/multi.vue @@ -0,0 +1,47 @@ + + + diff --git a/client/web/compose/src/components/ModuleFields/Configurator/validation.vue b/client/web/compose/src/components/ModuleFields/Configurator/validation.vue new file mode 100644 index 000000000..ec63133fa --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Configurator/validation.vue @@ -0,0 +1,198 @@ + + + diff --git a/client/web/compose/src/components/ModuleFields/Editor/Bool.c3.js b/client/web/compose/src/components/ModuleFields/Editor/Bool.c3.js new file mode 100644 index 000000000..82cb714d1 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Editor/Bool.c3.js @@ -0,0 +1,46 @@ +// eslint-disable-next-line +import { default as component } from './Bool.vue' +import { compose } from '@cortezaproject/corteza-js' +import * as fieldTypes from './loader' + +console.log(fieldTypes) +// const namespace = ({ +// canCreateChart: true, +// canCreateModule: true, +// canCreatePage: true, +// canDeleteNamespace: true, +// canGrant: true, +// canManageNamespace: true, +// canUpdateNamespace: true, +// createdAt: 'Fri Jul 30 2021 18:25:13 GMT+0300 (Eastern European Summer Time)', +// deletedAt: undefined, +// enabled: true, +// // labels: Object (empty), +// meta: { +// iconID: '0', +// logoID: '0', +// }, +// name: 'CRM', +// namespaceID: '242313184189546499', +// slug: 'crm', +// }) + +const props = { + // compose.Namespace + namespace: new compose.Namespace(), + // compose.Module + module: new compose.Module(), + // compose.ModuleField + field: new compose.ModuleFieldBool({ + options: { trueLabel: 'foo' }, + }), + // options +} + +export default { + name: 'Bool', + group: ['ModuleFields', '/Configurator'], + component, + props, + controls: [], +} diff --git a/client/web/compose/src/components/ModuleFields/Editor/Bool.vue b/client/web/compose/src/components/ModuleFields/Editor/Bool.vue new file mode 100644 index 000000000..130d025f8 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Editor/Bool.vue @@ -0,0 +1,37 @@ + + diff --git a/client/web/compose/src/components/ModuleFields/Editor/DateTime.vue b/client/web/compose/src/components/ModuleFields/Editor/DateTime.vue new file mode 100644 index 000000000..f27e8dc32 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Editor/DateTime.vue @@ -0,0 +1,88 @@ + + diff --git a/client/web/compose/src/components/ModuleFields/Editor/Email.vue b/client/web/compose/src/components/ModuleFields/Editor/Email.vue new file mode 100644 index 000000000..41ebebe6a --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Editor/Email.vue @@ -0,0 +1,63 @@ + + diff --git a/client/web/compose/src/components/ModuleFields/Editor/File.vue b/client/web/compose/src/components/ModuleFields/Editor/File.vue new file mode 100644 index 000000000..15dbaa908 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Editor/File.vue @@ -0,0 +1,128 @@ + + diff --git a/client/web/compose/src/components/ModuleFields/Editor/Geometry.vue b/client/web/compose/src/components/ModuleFields/Editor/Geometry.vue new file mode 100644 index 000000000..9d85f1a35 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Editor/Geometry.vue @@ -0,0 +1,233 @@ + + diff --git a/client/web/compose/src/components/ModuleFields/Editor/Number.vue b/client/web/compose/src/components/ModuleFields/Editor/Number.vue new file mode 100644 index 000000000..e3463fc59 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Editor/Number.vue @@ -0,0 +1,70 @@ + + diff --git a/client/web/compose/src/components/ModuleFields/Editor/Record.vue b/client/web/compose/src/components/ModuleFields/Editor/Record.vue new file mode 100644 index 000000000..36a3e575f --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Editor/Record.vue @@ -0,0 +1,507 @@ + + diff --git a/client/web/compose/src/components/ModuleFields/Editor/Select.vue b/client/web/compose/src/components/ModuleFields/Editor/Select.vue new file mode 100644 index 000000000..201d80197 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Editor/Select.vue @@ -0,0 +1,134 @@ + + diff --git a/client/web/compose/src/components/ModuleFields/Editor/String.vue b/client/web/compose/src/components/ModuleFields/Editor/String.vue new file mode 100644 index 000000000..2523e3f56 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Editor/String.vue @@ -0,0 +1,102 @@ + + + diff --git a/client/web/compose/src/components/ModuleFields/Editor/Url.vue b/client/web/compose/src/components/ModuleFields/Editor/Url.vue new file mode 100644 index 000000000..2790dcf48 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Editor/Url.vue @@ -0,0 +1,89 @@ + + diff --git a/client/web/compose/src/components/ModuleFields/Editor/User.vue b/client/web/compose/src/components/ModuleFields/Editor/User.vue new file mode 100644 index 000000000..42b981193 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Editor/User.vue @@ -0,0 +1,360 @@ + + diff --git a/client/web/compose/src/components/ModuleFields/Editor/base.vue b/client/web/compose/src/components/ModuleFields/Editor/base.vue new file mode 100644 index 000000000..375abe22d --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Editor/base.vue @@ -0,0 +1,144 @@ + + diff --git a/client/web/compose/src/components/ModuleFields/Editor/index.vue b/client/web/compose/src/components/ModuleFields/Editor/index.vue new file mode 100644 index 000000000..f27bb67b4 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Editor/index.vue @@ -0,0 +1,43 @@ + diff --git a/client/web/compose/src/components/ModuleFields/Editor/loader.js b/client/web/compose/src/components/ModuleFields/Editor/loader.js new file mode 100644 index 000000000..3ec9a11e5 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Editor/loader.js @@ -0,0 +1,11 @@ +export { default as String } from './String' +export { default as Bool } from './Bool' +export { default as Email } from './Email' +export { default as Number } from './Number' +export { default as Select } from './Select' +export { default as DateTime } from './DateTime' +export { default as Url } from './Url' +export { default as User } from './User' +export { default as Record } from './Record' +export { default as File } from './File' +export { default as Geometry } from './Geometry' diff --git a/client/web/compose/src/components/ModuleFields/Editor/multi.vue b/client/web/compose/src/components/ModuleFields/Editor/multi.vue new file mode 100644 index 000000000..27ce65d3b --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Editor/multi.vue @@ -0,0 +1,133 @@ + + + diff --git a/client/web/compose/src/components/ModuleFields/Viewer/Bool.vue b/client/web/compose/src/components/ModuleFields/Viewer/Bool.vue new file mode 100644 index 000000000..7fe30fc63 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Viewer/Bool.vue @@ -0,0 +1,21 @@ + diff --git a/client/web/compose/src/components/ModuleFields/Viewer/DateTime.vue b/client/web/compose/src/components/ModuleFields/Viewer/DateTime.vue new file mode 100644 index 000000000..f4ae6afa0 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Viewer/DateTime.vue @@ -0,0 +1,19 @@ + diff --git a/client/web/compose/src/components/ModuleFields/Viewer/Email.vue b/client/web/compose/src/components/ModuleFields/Viewer/Email.vue new file mode 100644 index 000000000..0e291f0c5 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Viewer/Email.vue @@ -0,0 +1,38 @@ + + diff --git a/client/web/compose/src/components/ModuleFields/Viewer/File.vue b/client/web/compose/src/components/ModuleFields/Viewer/File.vue new file mode 100644 index 000000000..fe4fd25da --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Viewer/File.vue @@ -0,0 +1,33 @@ + + diff --git a/client/web/compose/src/components/ModuleFields/Viewer/Geometry.vue b/client/web/compose/src/components/ModuleFields/Viewer/Geometry.vue new file mode 100644 index 000000000..3fa5a2bcf --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Viewer/Geometry.vue @@ -0,0 +1,106 @@ + + diff --git a/client/web/compose/src/components/ModuleFields/Viewer/Number.vue b/client/web/compose/src/components/ModuleFields/Viewer/Number.vue new file mode 100644 index 000000000..4ced7bf40 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Viewer/Number.vue @@ -0,0 +1,89 @@ + + + diff --git a/client/web/compose/src/components/ModuleFields/Viewer/Record.vue b/client/web/compose/src/components/ModuleFields/Viewer/Record.vue new file mode 100644 index 000000000..bd9ac4dee --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Viewer/Record.vue @@ -0,0 +1,164 @@ + + + + + diff --git a/client/web/compose/src/components/ModuleFields/Viewer/Select.vue b/client/web/compose/src/components/ModuleFields/Viewer/Select.vue new file mode 100644 index 000000000..665da6fe1 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Viewer/Select.vue @@ -0,0 +1,37 @@ + diff --git a/client/web/compose/src/components/ModuleFields/Viewer/String.vue b/client/web/compose/src/components/ModuleFields/Viewer/String.vue new file mode 100644 index 000000000..e4ce4f82e --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Viewer/String.vue @@ -0,0 +1,23 @@ + + diff --git a/client/web/compose/src/components/ModuleFields/Viewer/Url.vue b/client/web/compose/src/components/ModuleFields/Viewer/Url.vue new file mode 100644 index 000000000..a1e6ad209 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Viewer/Url.vue @@ -0,0 +1,59 @@ + + diff --git a/client/web/compose/src/components/ModuleFields/Viewer/User.vue b/client/web/compose/src/components/ModuleFields/Viewer/User.vue new file mode 100644 index 000000000..08595b6a2 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Viewer/User.vue @@ -0,0 +1,43 @@ + diff --git a/client/web/compose/src/components/ModuleFields/Viewer/base.vue b/client/web/compose/src/components/ModuleFields/Viewer/base.vue new file mode 100644 index 000000000..45db523f4 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Viewer/base.vue @@ -0,0 +1,78 @@ + + + + diff --git a/client/web/compose/src/components/ModuleFields/Viewer/index.vue b/client/web/compose/src/components/ModuleFields/Viewer/index.vue new file mode 100644 index 000000000..79b0cda19 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Viewer/index.vue @@ -0,0 +1,38 @@ + diff --git a/client/web/compose/src/components/ModuleFields/Viewer/loader.js b/client/web/compose/src/components/ModuleFields/Viewer/loader.js new file mode 100644 index 000000000..0d3c29157 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/Viewer/loader.js @@ -0,0 +1,11 @@ +export { default as Number } from './Number' +export { default as String } from './String' +export { default as Bool } from './Bool' +export { default as Email } from './Email' +export { default as Select } from './Select' +export { default as DateTime } from './DateTime' +export { default as Url } from './Url' +export { default as User } from './User' +export { default as Record } from './Record' +export { default as File } from './File' +export { default as Geometry } from './Geometry' diff --git a/client/web/compose/src/components/ModuleFields/errors.vue b/client/web/compose/src/components/ModuleFields/errors.vue new file mode 100644 index 000000000..e84807278 --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/errors.vue @@ -0,0 +1,41 @@ + + diff --git a/client/web/compose/src/components/ModuleFields/url.js b/client/web/compose/src/components/ModuleFields/url.js new file mode 100644 index 000000000..153d9e19d --- /dev/null +++ b/client/web/compose/src/components/ModuleFields/url.js @@ -0,0 +1,71 @@ +/** + * Processes a given URL and returns a URL object + * @param {String} url URL to process + * @returns {URL} + */ +function makeURL (url) { + if (!(/^http(s)?:\/\//.test(url))) { + url = 'https://' + url + } + return new URL(url) +} + +/** + * Removes URL's fragment + * @param {String} url URL to process + * @returns {String} + */ +export function trimUrlFragment (url) { + if (!url) { + return url + } + + url = makeURL(url) + url.hash = '' + return url.toString() +} + +/** + * Removes URL's query + * @param {String} url URL to process + * @returns {String} + */ +export function trimUrlQuery (url) { + if (!url) { + return url + } + + url = makeURL(url) + url.search = '' + return url.toString() +} + +/** + * Removes URL's path + * @param {String} url URL to process + * @returns {String} + */ +export function trimUrlPath (url) { + if (!url) { + return url + } + + url = makeURL(url) + url.pathname = '' + return url.toString() +} + +/** + * Assures that the given URL will provide a https schema + * @param {String} url URL to process + * @returns {String} + */ +export function onlySecureUrl (url) { + if (!url) { + return url + } + + url = makeURL(url) + url.protocol = 'https' + return url.toString() +} diff --git a/client/web/compose/src/components/Namespaces/C3.js b/client/web/compose/src/components/Namespaces/C3.js new file mode 100644 index 000000000..d7c19c832 --- /dev/null +++ b/client/web/compose/src/components/Namespaces/C3.js @@ -0,0 +1,3 @@ +export { default as NamespaceItem } from './NamespaceItem.c3' +// disabled: uses store +// export { default as NamespaceSidebar } from './NamespaceSidebar.c3' diff --git a/client/web/compose/src/components/Namespaces/Importer/FileUpload.vue b/client/web/compose/src/components/Namespaces/Importer/FileUpload.vue new file mode 100644 index 000000000..727b358ae --- /dev/null +++ b/client/web/compose/src/components/Namespaces/Importer/FileUpload.vue @@ -0,0 +1,71 @@ + + + + + diff --git a/client/web/compose/src/components/Namespaces/Importer/ImportConfiguration.vue b/client/web/compose/src/components/Namespaces/Importer/ImportConfiguration.vue new file mode 100644 index 000000000..8da55beb2 --- /dev/null +++ b/client/web/compose/src/components/Namespaces/Importer/ImportConfiguration.vue @@ -0,0 +1,100 @@ + + + diff --git a/client/web/compose/src/components/Namespaces/Importer/index.vue b/client/web/compose/src/components/Namespaces/Importer/index.vue new file mode 100644 index 000000000..590916be7 --- /dev/null +++ b/client/web/compose/src/components/Namespaces/Importer/index.vue @@ -0,0 +1,121 @@ + + + diff --git a/client/web/compose/src/components/Namespaces/NamespaceItem.c3.js b/client/web/compose/src/components/Namespaces/NamespaceItem.c3.js new file mode 100644 index 000000000..4e377e594 --- /dev/null +++ b/client/web/compose/src/components/Namespaces/NamespaceItem.c3.js @@ -0,0 +1,50 @@ +// eslint-disable-next-line +import { default as component } from './NamespaceItem.vue' +import { components } from '@cortezaproject/corteza-vue' +const { checkbox, input } = components.C3.controls + +const props = { + namespace: { + meta: { + subtitle: 'Subtitle', + description: 'Lorem ipsum dolor', + }, + name: 'CRM', + enabled: true, + canUpdateNamespace: true, + }, +} + +export default { + name: 'Item', + group: ['Namespaces'], + component, + props, + controls: [ + input('Subtitle', 'namespace.meta.subtitle'), + input('Description', 'namespace.meta.description'), + input('Name', 'namespace.name'), + checkbox('Enable visit namespace button', 'namespace.enabled'), + checkbox('Update namespace button', 'namespace.canUpdateNamespace'), + ], + + scenarios: [ + { + label: 'Full form', + props, + }, + { + label: 'Empty form', + props: { + ...props, + meta: { + subtitle: '', + description: '', + }, + name: 'CRM', + enabled: false, + canUpdateNamespace: false, + }, + }, + ], +} diff --git a/client/web/compose/src/components/Namespaces/NamespaceItem.vue b/client/web/compose/src/components/Namespaces/NamespaceItem.vue new file mode 100644 index 000000000..0c07cdd03 --- /dev/null +++ b/client/web/compose/src/components/Namespaces/NamespaceItem.vue @@ -0,0 +1,137 @@ + + + + diff --git a/client/web/compose/src/components/Namespaces/NamespaceSidebar.c3.js b/client/web/compose/src/components/Namespaces/NamespaceSidebar.c3.js new file mode 100644 index 000000000..18e7b5e23 --- /dev/null +++ b/client/web/compose/src/components/Namespaces/NamespaceSidebar.c3.js @@ -0,0 +1,24 @@ +// eslint-disable-next-line +import { default as component } from './NamespaceSidebar.vue' + +// TypeError: Cannot read property 'getters' of undefined +const props = { + namespaces: [ + { + namespaceID: '1111111111', + meta: { + subtitle: 'Subtitle', + description: 'Lorem ipsum dolor', + }, + name: 'CRM', + }, + ], +} + +export default { + name: 'Sidebar', + group: ['Namespaces'], + component, + props, + controls: [], +} diff --git a/client/web/compose/src/components/Namespaces/NamespaceSidebar.vue b/client/web/compose/src/components/Namespaces/NamespaceSidebar.vue new file mode 100644 index 000000000..855fb1f95 --- /dev/null +++ b/client/web/compose/src/components/Namespaces/NamespaceSidebar.vue @@ -0,0 +1,418 @@ + + + + + diff --git a/client/web/compose/src/components/Namespaces/NamespaceTranslator.vue b/client/web/compose/src/components/Namespaces/NamespaceTranslator.vue new file mode 100644 index 000000000..f39bf4180 --- /dev/null +++ b/client/web/compose/src/components/Namespaces/NamespaceTranslator.vue @@ -0,0 +1,124 @@ + + + diff --git a/client/web/compose/src/components/Namespaces/Reminders/Edit.c3.js b/client/web/compose/src/components/Namespaces/Reminders/Edit.c3.js new file mode 100644 index 000000000..3a6711f8b --- /dev/null +++ b/client/web/compose/src/components/Namespaces/Reminders/Edit.c3.js @@ -0,0 +1,45 @@ +// eslint-disable-next-line +import { default as component } from './Edit.vue' +import { components } from '@cortezaproject/corteza-vue' +const { input } = components.C3.controls + +const props = { + edit: { + payload: { + title: 'Reminder', + notes: 'Urgent!', + }, + }, + myID: '242313586825756675', + users: [], +} + +export default { + name: 'Edit reminder', + group: ['Right Panel'], + component, + props, + controls: [ + input('Title', 'edit.payload.title'), + input('Notes', 'edit.payload.notes'), + ], + + scenarios: [ + { + label: 'Full form', + props, + }, + { + label: 'Empty form', + props: { + ...props, + edit: { + payload: { + title: '', + notes: '', + }, + }, + }, + }, + ], +} diff --git a/client/web/compose/src/components/Namespaces/Reminders/Edit.vue b/client/web/compose/src/components/Namespaces/Reminders/Edit.vue new file mode 100644 index 000000000..a809d6568 --- /dev/null +++ b/client/web/compose/src/components/Namespaces/Reminders/Edit.vue @@ -0,0 +1,221 @@ + + + diff --git a/client/web/compose/src/components/Namespaces/Reminders/List.c3.js b/client/web/compose/src/components/Namespaces/Reminders/List.c3.js new file mode 100644 index 000000000..9421a9165 --- /dev/null +++ b/client/web/compose/src/components/Namespaces/Reminders/List.c3.js @@ -0,0 +1,25 @@ +// eslint-disable-next-line +import { default as component } from './List.vue' + +const props = { + reminders: [ + { + payload: { + notes: 'Urgent!', + remindAt: 1800000, + title: 'Remind me', + }, + remindAt: 'Thu Aug 12 2021 13:09:40 GMT+0300 (Eastern European Summer Time)', + reminderID: '244162818700476418', + snoozeCount: 0, + }, + ], +} + +export default { + name: 'List reminder', + group: ['Right Panel'], + component, + props, + controls: [], +} diff --git a/client/web/compose/src/components/Namespaces/Reminders/List.vue b/client/web/compose/src/components/Namespaces/Reminders/List.vue new file mode 100644 index 000000000..2dc7fbdbc --- /dev/null +++ b/client/web/compose/src/components/Namespaces/Reminders/List.vue @@ -0,0 +1,132 @@ + + + diff --git a/client/web/compose/src/components/Namespaces/Reminders/index.vue b/client/web/compose/src/components/Namespaces/Reminders/index.vue new file mode 100644 index 000000000..eca371bb6 --- /dev/null +++ b/client/web/compose/src/components/Namespaces/Reminders/index.vue @@ -0,0 +1,115 @@ + + + diff --git a/client/web/compose/src/components/PageBlocks/AutomationBase.vue b/client/web/compose/src/components/PageBlocks/AutomationBase.vue new file mode 100644 index 000000000..7ccf1292d --- /dev/null +++ b/client/web/compose/src/components/PageBlocks/AutomationBase.vue @@ -0,0 +1,67 @@ + + diff --git a/client/web/compose/src/components/PageBlocks/AutomationConfigurator.vue b/client/web/compose/src/components/PageBlocks/AutomationConfigurator.vue new file mode 100644 index 000000000..7aaa97a6c --- /dev/null +++ b/client/web/compose/src/components/PageBlocks/AutomationConfigurator.vue @@ -0,0 +1,20 @@ + + diff --git a/client/web/compose/src/components/PageBlocks/C3.js b/client/web/compose/src/components/PageBlocks/C3.js new file mode 100644 index 000000000..c37c1916f --- /dev/null +++ b/client/web/compose/src/components/PageBlocks/C3.js @@ -0,0 +1,115 @@ +import { compose } from '@cortezaproject/corteza-js' +import PageBlockFactory from './index.js' + +const options = { + Automation: { + buttons: [ + // { enabled: true, label: 'Enabled script', script: 'someScript' }, + { enabled: true, label: 'Enabled workflow', workflowID: '42' }, + { enabled: false, label: 'Disabled workflow', workflowID: '42' }, + ], + }, + + Chart: {}, + + Content: { + body: '

Lorem ipsum

...', + }, + + File: { + set: [ + { + attachmentID: 'string', + }, + ], + }, +} + +export const pageBlockConfigurators = Object.fromEntries([ + // all page block kinds + ...compose.PageBlockRegistry.keys(), +].map(name => { + const BlockClass = compose.PageBlockRegistry.get(name) + const block = new BlockClass({ options: (options[name] || {}) }) + const module = new compose.Module({ + fields: [ + { + name: 'field1', + canUpdateRecordValue: true, + canReadRecordValue: true, + }, + ], + canUpdateModule: true, + canDeleteModule: true, + canCreateRecord: true, + canReadRecord: true, + canUpdateRecord: true, + canDeleteRecord: true, + canGrant: true, + }) + + /** + * @todo This approach still raises errors with store, plugins and mixins + * Find a way how to inject them OR rewrite components to handle + * c3 environment without crashing + */ + return [name + 'Configurator', { + name, + wip: true, + group: ['Page blocks', 'Configurator'], + component: PageBlockFactory, + controls: [], + props: { + block, + mode: 'configurator', + namespace: new compose.Namespace(), + module, + page: new compose.Page(), + record: new compose.Record(module), + }, + }] +})) + +export const pageBlockBase = Object.fromEntries([ + // all page block kinds + ...compose.PageBlockRegistry.keys(), +].map(name => { + const BlockClass = compose.PageBlockRegistry.get(name) + const block = new BlockClass({ options: (options[name] || {}) }) + const module = new compose.Module({ + fields: [ + { + name: 'field1', + canUpdateRecordValue: true, + canReadRecordValue: true, + }, + ], + canUpdateModule: true, + canDeleteModule: true, + canCreateRecord: true, + canReadRecord: true, + canUpdateRecord: true, + canDeleteRecord: true, + canGrant: true, + }) + + /** + * @todo This approach still raises errors with store, plugins and mixins + * Find a way how to inject them OR rewrite components to handle + * c3 environment without crashing + */ + return [name, { + name, + wip: true, + group: ['Page blocks', 'View-mode'], + component: PageBlockFactory, + controls: [], + props: { + block, + namespace: new compose.Namespace(), + module, + page: new compose.Page(), + record: new compose.Record(module), + }, + }] +})) diff --git a/client/web/compose/src/components/PageBlocks/CalendarBase.vue b/client/web/compose/src/components/PageBlocks/CalendarBase.vue new file mode 100644 index 000000000..a5ada3e2b --- /dev/null +++ b/client/web/compose/src/components/PageBlocks/CalendarBase.vue @@ -0,0 +1,365 @@ + + + + + diff --git a/client/web/compose/src/components/PageBlocks/CalendarConfigurator/CalendarDisplay.c3.js b/client/web/compose/src/components/PageBlocks/CalendarConfigurator/CalendarDisplay.c3.js new file mode 100644 index 000000000..67a334e68 --- /dev/null +++ b/client/web/compose/src/components/PageBlocks/CalendarConfigurator/CalendarDisplay.c3.js @@ -0,0 +1,56 @@ +// eslint-disable-next-line +import { default as component } from './CalendarDisplay.vue' +import { compose } from '@cortezaproject/corteza-js' + +const props = { + block: new compose.PageBlock({ + options: { + header: { + hide: false, + hidePrevNext: 'true', + hideTitle: true, + hideToday: true, + }, + defaultView: 'dayGridMonth', + }, + }), + blockIndex: 7, + boundingRect: {}, + mode: 'configurator', + module: null, + namespace: new compose.Namespace(), + page: new compose.Page(), + record: null, +} + +export default { + name: 'Calendar display', + group: ['PageBlocks', 'Calendar configurator'], + component, + props, + controls: [], + + scenarios: [ + { + label: 'Full form', + props, + }, + { + label: 'Empty form', + props: { + ...props, + block: new compose.PageBlock({ + options: { + header: { + hide: false, + hidePrevNext: 'false', + hideTitle: false, + hideToday: false, + }, + defaultView: '', + }, + }), + }, + }, + ], +} diff --git a/client/web/compose/src/components/PageBlocks/CalendarConfigurator/CalendarDisplay.vue b/client/web/compose/src/components/PageBlocks/CalendarConfigurator/CalendarDisplay.vue new file mode 100644 index 000000000..1a02047be --- /dev/null +++ b/client/web/compose/src/components/PageBlocks/CalendarConfigurator/CalendarDisplay.vue @@ -0,0 +1,80 @@ + + diff --git a/client/web/compose/src/components/PageBlocks/CalendarConfigurator/FeedSource/configs/Record.c3.js b/client/web/compose/src/components/PageBlocks/CalendarConfigurator/FeedSource/configs/Record.c3.js new file mode 100644 index 000000000..63fa87571 --- /dev/null +++ b/client/web/compose/src/components/PageBlocks/CalendarConfigurator/FeedSource/configs/Record.c3.js @@ -0,0 +1,75 @@ +// eslint-disable-next-line +import { default as component } from './Record.vue' + +// TypeError: this.module.systemFields is not a function or its return value is not iterable +const props = { + feed: { + options: { + color: '#9d5c5c', + moduleID: '5555555', + prefilter: '', + }, + allDay: true, + endField: 'LastViewedDate', + startField: 'LastViewedDate', + titleField: 'BillingCity', + }, + modules: [ + { + moduleID: '242313186336833539', + handle: 'Pool', + name: 'Pool', + fields: [ + { label: 'Pool', name: 'Pool', kind: 'String' }, + ], + }, + { + moduleID: '242313186335633539', + handle: 'Party', + name: 'Party', + fields: [ + { label: 'Party', name: 'Party', kind: 'String' }, + ], + }, + { + moduleID: '242356786336833539', + handle: 'Cool', + name: 'Cool', + fields: [ + { label: 'Cool', name: 'Cool', kind: 'String' }, + ], + }, + ], +} + +export default { + name: 'Record', + group: ['PageBlocks', 'Feed Source'], + component, + props, + controls: [], + + scenarios: [ + { + label: 'Full form', + props, + }, + { + label: 'Empty form', + props: { + ...props, + feed: { + options: { + color: '#ffff', + moduleID: '5555555', + prefilter: '', + }, + allDay: false, + endField: '', + startField: '', + titleField: '', + }, + }, + }, + ], +} diff --git a/client/web/compose/src/components/PageBlocks/CalendarConfigurator/FeedSource/configs/Record.vue b/client/web/compose/src/components/PageBlocks/CalendarConfigurator/FeedSource/configs/Record.vue new file mode 100644 index 000000000..079d64a42 --- /dev/null +++ b/client/web/compose/src/components/PageBlocks/CalendarConfigurator/FeedSource/configs/Record.vue @@ -0,0 +1,212 @@ + + + diff --git a/client/web/compose/src/components/PageBlocks/CalendarConfigurator/FeedSource/configs/Reminder.c3.js b/client/web/compose/src/components/PageBlocks/CalendarConfigurator/FeedSource/configs/Reminder.c3.js new file mode 100644 index 000000000..d35c7a054 --- /dev/null +++ b/client/web/compose/src/components/PageBlocks/CalendarConfigurator/FeedSource/configs/Reminder.c3.js @@ -0,0 +1,33 @@ +// eslint-disable-next-line +import { default as component } from './Reminder.vue' + +const props = { + feed: { + options: { color: '#9d5c5c' }, + }, + modules: [], +} + +export default { + name: 'Reminder', + group: ['PageBlocks', 'Feed Source'], + component, + props, + controls: [], + + scenarios: [ + { + label: 'Full form', + props, + }, + { + label: 'Empty form', + props: { + ...props, + feed: { + options: { color: '#ffff' }, + }, + }, + }, + ], +} diff --git a/client/web/compose/src/components/PageBlocks/CalendarConfigurator/FeedSource/configs/Reminder.vue b/client/web/compose/src/components/PageBlocks/CalendarConfigurator/FeedSource/configs/Reminder.vue new file mode 100644 index 000000000..3dba4b3bb --- /dev/null +++ b/client/web/compose/src/components/PageBlocks/CalendarConfigurator/FeedSource/configs/Reminder.vue @@ -0,0 +1,31 @@ + + + diff --git a/client/web/compose/src/components/PageBlocks/CalendarConfigurator/FeedSource/configs/base.vue b/client/web/compose/src/components/PageBlocks/CalendarConfigurator/FeedSource/configs/base.vue new file mode 100644 index 000000000..f597ce7b5 --- /dev/null +++ b/client/web/compose/src/components/PageBlocks/CalendarConfigurator/FeedSource/configs/base.vue @@ -0,0 +1,36 @@ + diff --git a/client/web/compose/src/components/PageBlocks/CalendarConfigurator/FeedSource/configs/index.js b/client/web/compose/src/components/PageBlocks/CalendarConfigurator/FeedSource/configs/index.js new file mode 100644 index 000000000..2bdecb1ce --- /dev/null +++ b/client/web/compose/src/components/PageBlocks/CalendarConfigurator/FeedSource/configs/index.js @@ -0,0 +1,2 @@ +export { default as record } from './Record' +export { default as reminder } from './Reminder' diff --git a/client/web/compose/src/components/PageBlocks/CalendarConfigurator/FeedSource/index.vue b/client/web/compose/src/components/PageBlocks/CalendarConfigurator/FeedSource/index.vue new file mode 100644 index 000000000..7fd8c47b2 --- /dev/null +++ b/client/web/compose/src/components/PageBlocks/CalendarConfigurator/FeedSource/index.vue @@ -0,0 +1,135 @@ + + diff --git a/client/web/compose/src/components/PageBlocks/CalendarConfigurator/index.vue b/client/web/compose/src/components/PageBlocks/CalendarConfigurator/index.vue new file mode 100644 index 000000000..0d4065694 --- /dev/null +++ b/client/web/compose/src/components/PageBlocks/CalendarConfigurator/index.vue @@ -0,0 +1,35 @@ + + + diff --git a/client/web/compose/src/components/PageBlocks/ChartBase.vue b/client/web/compose/src/components/PageBlocks/ChartBase.vue new file mode 100644 index 000000000..8aa7a5fff --- /dev/null +++ b/client/web/compose/src/components/PageBlocks/ChartBase.vue @@ -0,0 +1,77 @@ + + diff --git a/client/web/compose/src/components/PageBlocks/ChartConfigurator.vue b/client/web/compose/src/components/PageBlocks/ChartConfigurator.vue new file mode 100644 index 000000000..ad5c3b147 --- /dev/null +++ b/client/web/compose/src/components/PageBlocks/ChartConfigurator.vue @@ -0,0 +1,42 @@ + + diff --git a/client/web/compose/src/components/PageBlocks/CommentBase.vue b/client/web/compose/src/components/PageBlocks/CommentBase.vue new file mode 100644 index 000000000..ec05a5f57 --- /dev/null +++ b/client/web/compose/src/components/PageBlocks/CommentBase.vue @@ -0,0 +1,351 @@ +