diff --git a/.env.example b/.env.example index 852bd600c..1e040d2e6 100644 --- a/.env.example +++ b/.env.example @@ -51,9 +51,11 @@ STORAGE_BUCKET= # Disabling default schema won't work if custom schema does not exist. ENABLE_DEFAULT_SCHEMA=1 -# String template that will be interpolated on the client using two route params, -# repositoryId and activityId. -PREVIEW_URL=https://myserver.com/repository/{repositoryId}/activity/{activityId} +# LMS preview route +PREVIEW_URL=https://boutique.localhost/api/v1/preview/ + +# Logger +LOG_LEVEL='info' # Terminal (forcefully enable color) FORCE_COLOR=1 diff --git a/.eslintrc.js b/.eslintrc.js index 457171f30..b82e62433 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,3 +1,5 @@ +'use strict'; + const isDev = process.env.NODE_ENV === 'development'; module.exports = { @@ -29,10 +31,9 @@ module.exports = { anonymous: 'always', named: 'never' }], - // 'sort-imports': ['error', { - // 'ignoreCase': true, - // 'ignoreMemberSort': false - // }] + 'sort-imports': ['error', { + 'ignoreCase': true + }], // Vue rules 'vue/html-self-closing': 'off', 'vue/attribute-hyphenation': 'off', diff --git a/README.md b/README.md index 711ab41f7..85aae43f1 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![Known Vulnerabilities](https://snyk.io/test/github/ExtensionEngine/tailor/develop/badge.svg)](https://snyk.io/test/github/ExtensionEngine/tailor) [![GitHub license](https://badgen.net/github/license/ExtensionEngine/tailor)](https://github.com/ExtensionEngine/tailor/blob/develop/LICENSE) [![js semistandard style](https://badgen.net/badge/code%20style/semistandard/pink)](https://github.com/Flet/semistandard) -[![Open Source Love](https://badges.frapsoft.com/os/v2/open-source.svg?v=102)](https://github.com/ellerbrock/open-source-badge/) +[![Open Source Love](https://badgen.net/badge/Open%20Source/%E2%9D%A4/3eaf8e)](https://github.com/ellerbrock/open-source-badge/) Adaptive course authoring platform. diff --git a/build/plugins/html-version-spec.js b/build/plugins/html-version-spec.js index 0ec005053..5e48bb681 100644 --- a/build/plugins/html-version-spec.js +++ b/build/plugins/html-version-spec.js @@ -14,21 +14,21 @@ exports.apply = ({ config, pkg }) => { return getVersion(pkg); } }; - if (isObject(config.html)) { - return Object.assign(config.html, { meta }); - } if (isObject(config.pages)) { return forEach(config.pages, page => Object.assign(page, { meta })); } + const { output } = config; + output.html = output.html || {}; + Object.assign(output.html, { meta }); }; function getVersion(pkg) { - const semver = pkg.data.version; + const { codename, version } = pkg.data; try { const rev = execSync('git', ['rev-parse', '--short', 'HEAD']); - return `${semver}-rev-${rev}`; + return `${version}-rev-${rev} (${codename})`; } catch (err) { console.error(err); } - return `${semver}`; + return `${version} (${codename})`; } diff --git a/client/App.vue b/client/App.vue index 404165ed8..7ae3b77a3 100644 --- a/client/App.vue +++ b/client/App.vue @@ -11,14 +11,16 @@ @@ -29,48 +27,41 @@ export default { } .auth-panel { - width: 440px; + width: 480px; margin: auto; background-color: #fff; - box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23); border-radius: 4px; - transition: all 0.3s cubic-bezier(0.25,0.8,0.25,1); - - &:hover { - box-shadow: 0 6px 10px rgba(0,0,0,0.2), 0 6px 8px rgba(0,0,0,0.22); - } - - img { - width: 130px; - margin: 15px 0 10px; - } h1 { margin: 0; color: white; font-size: 22px; - line-height: 18px; } .auth-header { padding-bottom: 20px; - background: linear-gradient(90deg, $brandColor 65%, $altBrandColor); + background-color: var(--v-primary-darken1); border-radius: 4px 4px 0 0; + + .logo { + width: 75px; + margin: 30px 0; + } } .auth-body { - padding: 20px 30px; + padding: 25px 30px; a { color: inherit; - font-weight: 500; + font-weight: 400; } } .message { min-height: 16px; margin-bottom: 20px; - color: #da126d; + color: var(--v-secondary-base); font-size: 16px; line-height: 16px; } diff --git a/client/components/auth/ForgotPassword.vue b/client/components/auth/ForgotPassword.vue index b5e4eea07..396505ba9 100644 --- a/client/components/auth/ForgotPassword.vue +++ b/client/components/auth/ForgotPassword.vue @@ -1,61 +1,71 @@ diff --git a/client/components/auth/ResetPassword.vue b/client/components/auth/ResetPassword.vue index 24b471697..e86d7adee 100644 --- a/client/components/auth/ResetPassword.vue +++ b/client/components/auth/ResetPassword.vue @@ -1,44 +1,42 @@ + + diff --git a/client/components/catalog/Card/Stat.vue b/client/components/catalog/Card/Stat.vue deleted file mode 100644 index 70bf359e2..000000000 --- a/client/components/catalog/Card/Stat.vue +++ /dev/null @@ -1,27 +0,0 @@ - - - - - diff --git a/client/components/catalog/Card/index.vue b/client/components/catalog/Card/index.vue deleted file mode 100644 index ed1ec6889..000000000 --- a/client/components/catalog/Card/index.vue +++ /dev/null @@ -1,113 +0,0 @@ - - - - - diff --git a/client/components/catalog/Container.vue b/client/components/catalog/Container.vue index 2098d507f..16e4a00d5 100644 --- a/client/components/catalog/Container.vue +++ b/client/components/catalog/Container.vue @@ -1,115 +1,171 @@ diff --git a/client/components/catalog/Create.vue b/client/components/catalog/Create.vue index 16fdbe767..95152a142 100644 --- a/client/components/catalog/Create.vue +++ b/client/components/catalog/Create.vue @@ -3,13 +3,24 @@ v-hotkey="{ esc: hide }" v-if="isAdmin" v-model="isVisible" - width="600px"> - + width="700px"> + mdi-plus - Create repository + + + mdi-folder-plus-outline + + New + Cancel - - Create - + Create @@ -54,13 +62,13 @@ diff --git a/client/components/catalog/SelectOrder.vue b/client/components/catalog/SelectOrder.vue new file mode 100644 index 000000000..a271aab92 --- /dev/null +++ b/client/components/catalog/SelectOrder.vue @@ -0,0 +1,53 @@ + + + + + diff --git a/client/components/common/ActivityBrowser/SelectActivity.vue b/client/components/common/ActivityBrowser/SelectActivity.vue index 689ce11e4..27fe83ba9 100644 --- a/client/components/common/ActivityBrowser/SelectActivity.vue +++ b/client/components/common/ActivityBrowser/SelectActivity.vue @@ -31,14 +31,14 @@ + + diff --git a/client/components/common/InputAsset.vue b/client/components/common/InputAsset.vue index 664ebd241..61a878df8 100644 --- a/client/components/common/InputAsset.vue +++ b/client/components/common/InputAsset.vue @@ -11,6 +11,7 @@ mdi-open-in-new + :placeholder="allowFileUpload ? 'or paste a URL' : 'Paste a URL'"/> + + diff --git a/client/components/content-elements/tce-html/edit/index.vue b/client/components/content-elements/tce-html/edit/index.vue index c989b106b..63eb1e940 100644 --- a/client/components/content-elements/tce-html/edit/index.vue +++ b/client/components/content-elements/tce-html/edit/index.vue @@ -23,12 +23,13 @@ diff --git a/client/components/course/Outline/reorderMixin.js b/client/components/course/Outline/reorderMixin.js index 83ba43544..69f445316 100644 --- a/client/components/course/Outline/reorderMixin.js +++ b/client/components/course/Outline/reorderMixin.js @@ -1,8 +1,8 @@ -import { mapActions } from 'vuex-module'; +import { mapActions } from 'vuex'; export default { methods: { - ...mapActions({ updatePosition: 'reorder' }, 'activities'), + ...mapActions('activities', { updatePosition: 'reorder' }), reorder({ newIndex: newPosition }, items) { const activity = items[newPosition]; const isFirstChild = newPosition === 0; diff --git a/client/components/course/Revisions/EntitySidebar.vue b/client/components/course/Revisions/EntitySidebar.vue index 8e1cc4344..10bad10a3 100644 --- a/client/components/course/Revisions/EntitySidebar.vue +++ b/client/components/course/Revisions/EntitySidebar.vue @@ -56,6 +56,11 @@ export default { diff --git a/client/components/system-settings/Sidebar.vue b/client/components/system-settings/Sidebar.vue new file mode 100644 index 000000000..c786fe2a9 --- /dev/null +++ b/client/components/system-settings/Sidebar.vue @@ -0,0 +1,32 @@ + + + diff --git a/client/components/system-settings/StructureTypes.vue b/client/components/system-settings/StructureTypes.vue new file mode 100644 index 000000000..1fc7d18a5 --- /dev/null +++ b/client/components/system-settings/StructureTypes.vue @@ -0,0 +1,63 @@ + + + + + diff --git a/client/components/system-settings/UserManagement/UserDialog.vue b/client/components/system-settings/UserManagement/UserDialog.vue new file mode 100644 index 000000000..4a336a0d5 --- /dev/null +++ b/client/components/system-settings/UserManagement/UserDialog.vue @@ -0,0 +1,129 @@ + + + diff --git a/client/components/system-settings/UserManagement/index.vue b/client/components/system-settings/UserManagement/index.vue new file mode 100644 index 000000000..1955d0f89 --- /dev/null +++ b/client/components/system-settings/UserManagement/index.vue @@ -0,0 +1,186 @@ + + + + + diff --git a/client/components/system-settings/index.vue b/client/components/system-settings/index.vue new file mode 100644 index 000000000..a3d595917 --- /dev/null +++ b/client/components/system-settings/index.vue @@ -0,0 +1,56 @@ + + + + + diff --git a/client/main.js b/client/main.js index cc8e80654..841b6d45b 100644 --- a/client/main.js +++ b/client/main.js @@ -1,3 +1,4 @@ +/* eslint-disable sort-imports */ import '@babel/polyfill'; import 'dom-shims/shim/Element.classList'; import 'dom-shims/shim/Element.mutation'; @@ -8,8 +9,10 @@ import 'vue-directive-tooltip/css/index.css'; import assetsApi from '@/api/asset'; import colors from 'vuetify/es5/util/colors'; import ElementRegistry from './ElementRegistry'; +import fecha from 'fecha'; import FileFilter from '@/directives/file-filter'; import QuestionContainer from 'tce-core/QuestionContainer'; +import { sync } from 'vuex-router-sync'; import Timeago from 'vue-timeago'; import Tooltip from 'vue-directive-tooltip'; import VeeValidate from './utils/validation'; @@ -17,14 +20,15 @@ import Vue from 'vue'; import VueHotkey from 'v-hotkey'; import Vuetify from 'vuetify'; import VuetifySnackbar from '@/plugins/vuetify-snackbar'; -import { sync } from 'vuex-router-sync'; import store from './store'; import router from './router'; import App from './App'; Vue.component('tce-question-container', QuestionContainer); - +Vue.filter('formatDate', (value, dateFormat = 'MM/DD/YY HH:mm') => { + return value && fecha.format(new Date(value), dateFormat); +}); Vue.use(FileFilter); Vue.use(VueHotkey); Vue.use(Vuetify, { @@ -32,6 +36,9 @@ Vue.use(Vuetify, { theme: { primary: colors.blueGrey.darken2, secondary: colors.pink + }, + options: { + customProperties: true } }); Vue.use(VuetifySnackbar); diff --git a/client/plugins/vuetify-snackbar/Snackbar.vue b/client/plugins/vuetify-snackbar/Snackbar.vue index 91736bd29..2360fc00c 100644 --- a/client/plugins/vuetify-snackbar/Snackbar.vue +++ b/client/plugins/vuetify-snackbar/Snackbar.vue @@ -8,8 +8,9 @@