Skip to content
Snippets Groups Projects
Commit 05e6350a authored by Marcel Nellesen's avatar Marcel Nellesen
Browse files

New: created quota admin page

parent 75ac6d54
No related branches found
No related tags found
1 merge request!2Sprint/2020 22
.DS_Store
node_modules
/dist
package-lock.json
# local env files
.env.local
......
stages:
- build
- test
- docs
- publish
- release
- pre_release
before_script:
- npm install
build:
stage: build
script:
- npm run build
except:
variables:
- $GITLAB_USER_ID == $GIT_BOT_USER_ID
test:
stage: test
script:
- npm run test:unit
except:
variables:
- $GITLAB_USER_ID == $GIT_BOT_USER_ID
docs:
stage: docs
script:
- .\publishDocs.ps1 $GITLAB_TOKEN
- npm run build
- npm test
except:
refs:
- master
- tags
variables:
- $GITLAB_USER_ID == $GIT_BOT_USER_ID
publish:
stage: publish
script:
- npm run build
- npm test
- npx semantic-release
only:
- master
......@@ -54,5 +41,14 @@ release:
only:
- tags
after_script:
- Cmd /C "rmdir /S /Q node_modules"
\ No newline at end of file
pre_release:
stage: pre_release
script:
- npm run build
artifacts:
paths:
- dist
when: manual
except:
- tags
- master
## ESLint Convention
Make the changes to the code and tests and then commit to your branch. Be sure to follow the commit message conventions.
Commit message summaries must follow this basic format:
```
Tag: Message (fixes #1234)
```
`Tag` should not be confused with git tag.
`Message` should not be confused with git commit message.
The `Tag` is one of the following:
* `Fix` - for a bug fix.
* `Update` - for a backwards-compatible enhancement.
* `Breaking` - for a backwards-incompatible enhancement.
* `Docs` - changes to documentation only.
* `Build` - changes to build process only.
* `New` - implemented a new feature.
* `Upgrade` - for a dependency upgrade.
The message summary should be a one-sentence description of the change. The issue number should be mentioned at the end. * The commit message should say "(fixes #1234)" at the end of the description if it closes out an existing issue (replace 1234 with the issue number). If the commit doesn't completely fix the issue, then use `(refs #1234)` instead of `(fixes #1234)`.
Here are some good commit message summary examples:
```
Build: Update Travis to only test Node 0.10 (refs #734)
Fix: Semi rule incorrectly flagging extra semicolon (fixes #840)
Upgrade: Esprima to 1.2, switch to using Esprima comment attachment (fixes #730)
```
The commit message format is important because these messages are used to create a changelog for each release. The tag and issue number help to create more consistent and useful changelogs.
Based on https://github.com/eslint/eslint.github.io/blob/master/docs/developer-guide/contributing.md#step-2-make-your-changes
[npm-image]: https://badge.fury.io/js/conventional-changelog-eslint.svg
[npm-url]: https://npmjs.org/package/conventional-changelog-eslint
[travis-image]: https://travis-ci.org/stevemao/conventional-changelog-eslint.svg?branch=master
[travis-url]: https://travis-ci.org/stevemao/conventional-changelog-eslint
[daviddm-image]: https://david-dm.org/stevemao/conventional-changelog-eslint.svg?theme=shields.io
[daviddm-url]: https://david-dm.org/stevemao/conventional-changelog-eslint
[coveralls-image]: https://coveralls.io/repos/stevemao/conventional-changelog-eslint/badge.svg
[coveralls-url]: https://coveralls.io/r/stevemao/conventional-changelog-eslint
\ No newline at end of file
# vue-template
This template includes:
* Vue.js application template
* Linting using TSLint and the Vue builders
* Automatic releases using semantic-release (ESLint Code Convention) and Gitlab CI / CD
* Automatic Unit tests using Mocha/Chai and the Vue cli
* Automatic documentation publishing using Gitlab CI / CD and a self written script which puts the docs in the docs folder to the wiki
* For public registry: Publishing of packages, for usage add the following lines to package.json, add the npm publish module in .releaserc and provide a valid NPM token:
```
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/",
"tag": "latest"
}
```
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Run your tests
```
npm run test
```
### Lints and fixes files
```
npm run lint
```
### Run your unit tests
```
npm run test:unit
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).
### Commit convention
See [Commit convention](ESLintConvention) for the commit convention.
\ No newline at end of file
This diff is collapsed.
{
"name": "ts-vue-template",
"name": "@coscine/supportadmin",
"version": "1.0.0",
"private": true,
"directories": {
......@@ -12,30 +12,42 @@
"test:unit": "vue-cli-service test:unit"
},
"dependencies": {
"vue": "^2.6.6"
"@coscine/api-connection": "^1.22.0",
"@coscine/app-util": "^1.6.0",
"@coscine/component-library": "1.3.0",
"@itcenter-layout/bootstrap": "^1.5.5",
"@itcenter-layout/masterpage": "^1.3.0",
"@types/jquery": "^3.5.2",
"bootstrap-vue": "^2.19.0",
"jquery": "^3.5.1",
"vue": "^2.6.12",
"vue-i18n": "^8.22.0",
"vue-loading-overlay": "^3.4.2",
"vue-runtime-helpers": "^1.1.2",
"vuelidate": "^0.7.5"
},
"devDependencies": {
"@semantic-release/commit-analyzer": "^6.1.0",
"@semantic-release/git": "^7.0.5",
"@semantic-release/gitlab": "^3.0.5",
"@semantic-release/npm": "^5.1.1",
"@semantic-release/release-notes-generator": "^7.1.4",
"@types/chai": "^4.1.0",
"@types/mocha": "^5.2.4",
"@vue/cli-plugin-babel": "^3.5.0",
"@vue/cli-plugin-typescript": "^3.5.0",
"@vue/cli-plugin-unit-mocha": "^3.5.0",
"@vue/cli-service": "^3.5.0",
"@vue/test-utils": "1.0.0-beta.29",
"chai": "^4.1.2",
"typescript": "^3.2.1",
"vue-template-compiler": "^2.5.21",
"semantic-release": "^15.12.0",
"semantic-release-gitlab": "^7.1.0"
"@hutson/semantic-delivery-gitlab": "^9.1.0",
"@semantic-release/commit-analyzer": "^8.0.1",
"@semantic-release/git": "^9.0.0",
"@semantic-release/gitlab": "^6.0.5",
"@semantic-release/npm": "^7.0.6",
"@semantic-release/release-notes-generator": "^9.0.1",
"@types/chai": "^4.2.13",
"@types/mocha": "^8.0.3",
"@vue/cli-plugin-babel": "^4.5.7",
"@vue/cli-plugin-typescript": "^4.5.7",
"@vue/cli-plugin-unit-mocha": "^4.5.7",
"@vue/cli-service": "^4.5.7",
"@vue/test-utils": "1.1.0",
"chai": "^4.2.0",
"semantic-release": "^17.1.2",
"typescript": "^4.0.3",
"vue-template-compiler": "^2.6.12"
},
"repository": {
"type": "git",
"url": "https://git.rwth-aachen.de/coscine/templates/vue-template.git"
"url": "https://git.rwth-aachen.de/coscine/app/quotamanagement.git"
},
"license": "ISC"
"license": "MIT"
}
......@@ -5,13 +5,13 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>ts-template</title>
<title>Support Admin Page</title>
</head>
<body>
<body class="fullwidth">
<noscript>
<strong>We're sorry but ts-template doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
<strong>We're sorry but pidpage doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<supportadmin></supportadmin>
<!-- built files will be auto injected -->
</body>
</html>
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js + TypeScript App"/>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import HelloWorld from './components/HelloWorld.vue';
export default Vue.extend({
name: 'app',
components: {
HelloWorld,
},
});
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
<template>
<div id="SupportAdmin" class="container">
<b-row>
<div class="col-sm-8">
<div>
<h4>{{ $t('headline') }}</h4>
</div>
</div>
</b-row>
<b-row>
<div class="col-sm-2"></div>
<div class="col-sm-8">
<b-form id="project_request_form" @submit.stop.prevent="onSubmit">
<b-input-group class="mt-3">
<b-form-input
id="projectId"
ref="projectId"
v-model="form.projectId"
aria-describedby="projectHelp"
:placeholder="$t('projectInputTooltip')">
</b-form-input>
<b-input-group-append>
<b-button variant="primary" id="query_project_button" @click="queryProject()">{{ $t('projectSelectButton') }}</b-button>
</b-input-group-append>
</b-input-group>
</b-form>
<h5 id='project_query_status'>{{ requestStatus }}</h5>
<b-container fluid>
<b-row class="my-1">
<b-col sm="2">
<label for="project_name">{{ $t('projectName') }}</label>
</b-col>
<b-col sm="10">
<b-form-input id="project_name" v-model="form.projectName" :readonly="true"></b-form-input>
</b-col>
</b-row>
<b-row class="my-1">
<b-col sm="2">
<label for="project_short_name">{{ $t('projectShortName') }}</label>
</b-col>
<b-col sm="10">
<b-form-input id="project_short_name" v-model="form.projectShortName" :readonly="true"></b-form-input>
</b-col>
</b-row>
<b-row class="my-1">
<b-col sm="2">
<label for="project_guid">{{ $t('projectGuid') }}</label>
</b-col>
<b-col sm="10">
<b-form-input id="project_guid" v-model="form.projectGuid" :readonly="true"></b-form-input>
</b-col>
</b-row>
</b-container>
<h5 style="text-align: left;">{{ $t('projectQuotaHeadline') }}:</h5>
<b-table
id="project_qouta_table"
:fields="headers"
:items="projectQuotas"
:busy="busy"
:locale="$i18n.locale"
:sort-by.sync="sortBy"
:sort-desc.sync="sortDesc"
:show-empty="true"
:empty-text="emptyText"
fixed
sticky-header="100%"
no-border-collapse
sort-icon-right
striped
bordered
outlined
hover
head-variant="dark">
<template #cell(newQuota)="row">
<b-form-input
id="data"
v-model="row.item.newQuota"
aria-describedby="projectHelp"
:placeholder="$t('newQuotaInputPlaceHolder')">
</b-form-input>
</template>
<template #cell(action)="row">
<button id=action v-on:click.stop.prevent="saveNewQuota(row.item)" class="btn btn-primary float-right">{{ $t('save') }}</button>
</template>
</b-table>
</div>
</b-row>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import { GuidUtil } from '@coscine/app-util';
import { AdminApi } from '@coscine/api-connection';
import { ToastPlugin } from 'bootstrap-vue';
import { error } from 'jquery';
Vue.use(ToastPlugin);
export default Vue.extend({
name: 'supportadmin',
components: {
},
data() {
return {
requestStatus: this.$t('projectNotSelected'),
form: {
projectId: '',
projectName: '',
projectShortName: '',
projectGuid: '',
},
projectQuotas: [] as any,
filter: String,
busy: false,
emptyText: 'No Quotas',
sortBy: 'resourceType',
sortDesc: false,
filteredRows: 0,
headers: [
{
label: this.$t('resourceType'),
key: 'resourceType',
sortable: true,
},
{
label: this.$t('currentQuota'),
key: 'currentQuota',
sortable: true,
},
{
label: this.$t('newQuota'),
key: 'newQuota',
sortable: true,
},
{
label: this.$t('action'),
key: 'action',
sortable: true,
},
],
};
},
methods: {
getProjectQuotas() {
AdminApi.GetProject(this.form.projectId,
(response: any) => {
this.clearResults('');
if (response.data.guid) {
this.requestStatus = this.$t('projectFound');
this.form.projectName = response.data.name;
this.form.projectShortName = response.data.shortName;
this.form.projectGuid = response.data.guid;
const quotas = response.data.quotas;
for (const d of quotas) {
this.projectQuotas.push({quotaId: d.quotaId, resourceType: d.resourceType, currentQuota: d.quota});
}
} else {
this.clearResults('projectNotFound');
}
},
(errorState: any) => {
const message = this.$t('queryProjectFailureText').toString();
this.makeToast(message, this.$t('queryProjectFailureHeadline').toString());
},
);
},
queryProject() {
// if the field is empty:
if (!this.form.projectId.trim()) {
this.clearResults('projectNotSelected');
} else {
this.getProjectQuotas();
}
},
saveNewQuota(selectedQuota: any) {
let message: string = '' + this.$t('successNotificationText');
message = message.replace('{projectName}', this.form.projectShortName);
message = message.replace('{resourceType}', selectedQuota.resourceType);
if (selectedQuota.newQuota) {
message = message.replace('{newQuota}', '' + selectedQuota.newQuota);
}
const updatedQuota = {
quotaId: selectedQuota.quotaId,
quota: selectedQuota.newQuota,
};
if (updatedQuota.quota) {
AdminApi.UpdateQuota(updatedQuota,
(response: any) => {
this.makeToast(message, this.$t('successNotificationHeadline').toString());
this.getProjectQuotas();
},
(errorState: any) => {
message = this.$t('failureNotificationText').toString();
this.makeToast(message, this.$t('failureNotificationHeadline').toString());
},
);
}
},
clearResults(headline: string) {
this.requestStatus = this.$t(headline);
this.projectQuotas = [];
this.form.projectName = '';
this.form.projectShortName = '';
this.form.projectGuid = '';
},
makeToast(text: string = 'Message', givenTitle: string = 'Title') {
this.$bvToast.toast(
text,
{
title: givenTitle,
autoHideDelay: 5000,
toaster: 'b-toaster-bottom-right',
noCloseButton: true,
},
);
},
},
});
</script>
<style scoped>
h5 {
margin-top: 0.4em;
}
</style>
\ No newline at end of file
src/assets/logo.png

6.69 KiB

<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-typescript" target="_blank" rel="noopener">typescript</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-unit-mocha" target="_blank" rel="noopener">unit-mocha</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
name: 'HelloWorld',
props: {
msg: String,
},
});
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
declare var coscine: {
i18n: {
supportadmin: {},
},
};
import jQuery from 'jquery';
import BootstrapVue from 'bootstrap-vue';
import Vue from 'vue';
import App from './App.vue';
import SupportAdmin from './SupportAdminApp.vue';
import VueI18n from 'vue-i18n';
import { LanguageUtil } from '@coscine/app-util';
Vue.config.productionTip = false;
Vue.use(BootstrapVue);
Vue.use(VueI18n);
jQuery(() => {
const i18n = new VueI18n({
locale: LanguageUtil.getLanguage(),
messages: coscine.i18n.supportadmin,
silentFallbackWarn: true,
});
new Vue({
render: (h) => h(App),
}).$mount('#app');
render: (h) => h(SupportAdmin),
i18n,
}).$mount('supportadmin');
});
......@@ -2,3 +2,7 @@ declare module '*.vue' {
import Vue from 'vue';
export default Vue;
}
declare module '@coscine/api-connection';
declare module '@coscine/app-util';
declare module '@coscine/component-library';
import { expect } from 'chai';
import { shallowMount } from '@vue/test-utils';
import HelloWorld from '@/components/HelloWorld.vue';
describe('HelloWorld.vue', () => {
it('renders props.msg when passed', () => {
const msg = 'new message';
const wrapper = shallowMount(HelloWorld, {
propsData: { msg },
});
expect(wrapper.text()).to.include(msg);
});
});
module.exports = {
devServer: {
disableHostCheck: true,
},
publicPath: './',
configureWebpack: {
devtool: 'source-map',
devServer: {
port: 9369,
}
},
filenameHashing: false,
chainWebpack: config => {
config.optimization.delete('splitChunks')
},
css: {
extract: false,
},
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment