Commit f5c6f74b authored by Reza Sahebgharan's avatar Reza Sahebgharan

Staging testgitlab

parent a986e7d0
{
"comments": false,
"presets": [
[
"@babel/preset-env",
{
"targets": [
"last 2 versions"
]
}
]
],
"plugins": [
[
"@babel/plugin-transform-async-to-generator"
],
[
"@babel/plugin-proposal-class-properties"
],
[
"@babel/plugin-proposal-object-rest-spread"
],
[
"@babel/plugin-transform-spread"
],
[
"@babel/plugin-transform-runtime",
{
"regenerator": true
}
],
[
"transform-remove-console"
]
]
}
\ No newline at end of file
node_modules/
.meteor/local/
.vscode/
coverage/
__mock__/
__test__/
cypress/screenshotsFolder
cypress/videosFolder
node_modules/
.vscode/
coverage/
cypress/screenshots
cypress/videos
variables:
TAG_VERSION: ''
stages:
- build_in_devel
- cleanup_build
- build_in_master
- build_in_staging
build_in_devel:
before_script:
- $env:TAG_VERSION=(git describe --tag --abbrev=0)
- docker login -u reza.s -p aA123456 repo.marcopacs.com
stage: build_in_devel
tags:
- shell
script:
- echo "starting build in branch"
- npm install
- npm run test-jest
- docker-compose config
- docker-compose build
- echo y | plink -ssh administrator@staging.karname.ir "exit"
- docker save -o ./scripts/karname-app.tar karname-app:$env:TAG_VERSION # save docker in scripts folder
- echo y | pscp.exe -batch -l administrator -pw $env:StagingPass ./scripts/karname-app.tar staging.karname.ir:c:/Users/administrator/karname-app.tar # save docker in remote server
- echo y | plink -batch -ssh administrator@staging.karname.ir -pw $env:StagingPass docker load -i c:/Users/administrator/karname-app.tar -q
- echo y | pscp.exe -batch -l administrator -pw $env:StagingPass ./docker-compose-staging.yml staging.karname.ir:c:/Users/administrator/docker-compose.yml # save docker-compose.yml in remote server
- Set-Variable -Name "envtext" -Value "TAG_VERSION=$env:TAG_VERSION"
- New-Item -Path '.\.env' -ItemType File
- Add-Content .\.env "$envtext"
- echo y | pscp.exe -batch -l administrator -pw $env:StagingPass ./.env staging.karname.ir:c:/Users/administrator/.env # save .env in remote server
- echo y | plink -batch -ssh administrator@staging.karname.ir -pw $env:StagingPass -m ./scripts/command.bat
# - ./scripts/command.ps1
allow_failure: true
only:
- devel
build_in_staging:
before_script:
- $env:TAG_VERSION=(git describe --tag --abbrev=0)
- $env:BRANCHFULLNAME=(git name-rev --name-only HEAD)
- $env:BRANCHNAME=$env:BRANCHFULLNAME.Split('/')[$env:BRANCHFULLNAME.Split('/').length - 1]
- echo $env:BRANCHNAME.Split('_')[1]
- docker login -u reza.s -p aA123456 repo.marcopacs.com
stage: build_in_staging
tags:
- shell
script:
- echo "starting build in devel-windows"
- npm install
# - npm run test-jest
- meteor build C:\output --directory --server-only
- Copy-Item -Path .\docker-compose.yml -Destination C:\output\bundle
- Copy-Item -Path .\docker\windows\Dockerfile -Destination C:\output\bundle
- Copy-Item -Path .\scripts\command.bat -Destination C:\output\bundle
- cd C:\output\bundle\programs\server
- npm install
- cd ../..
- docker build -t karname-app:$env:TAG_VERSION .
- echo y | plink -ssh administrator@staging.karname.ir "exit"
- docker save -o ./karname-app.tar karname-app:$env:TAG_VERSION # save docker in scripts folder
- echo y | pscp.exe -batch -l administrator -pw $env:StagingPass ./karname-app.tar staging.karname.ir:c:/Users/administrator/karname-app.tar # save docker in remote server
- echo y | plink -batch -ssh administrator@staging.karname.ir -pw $env:StagingPass docker load -i c:/Users/administrator/karname-app.tar -q
- echo y | pscp.exe -batch -l administrator -pw $env:StagingPass ./docker-compose.yml staging.karname.ir:c:/Users/administrator/docker-compose.yml # save docker-compose.yml in remote server
- Set-Variable -Name "envtext" -Value "TAG_VERSION=$env:TAG_VERSION"
- New-Item -Path '.\.env' -ItemType File
- Add-Content .\.env "$envtext"
- echo y | pscp.exe -batch -l administrator -pw $env:StagingPass ./.env staging.karname.ir:c:/Users/administrator/.env # save .env in remote server
- echo y | plink -batch -ssh administrator@staging.karname.ir -pw $env:StagingPass -m ./command.bat
# - ./scripts/command.ps1
allow_failure: true
# only:
# - devel-windows
only:
- /^.*staging_.*/
build_in_master:
before_script:
- $env:TAG_VERSION=(git describe --tag --abbrev=0)
stage: build_in_master
tags:
- shell
script:
- echo "starting build in master"
allow_failure: true
only:
- tags
except:
- /^(?!master).+@/
on_build_failure:
stage: cleanup_build
script: RD /S /Q "C:\GitLab-Runner\builds"
when: on_failure
# This file contains information which helps Meteor properly upgrade your
# app when you run 'meteor update'. You should check it into version control
# with your project.
notices-for-0.9.0
notices-for-0.9.1
0.9.4-platform-file
notices-for-facebook-graph-api-2
1.2.0-standard-minifiers-package
1.2.0-meteor-platform-split
1.2.0-cordova-changes
1.2.0-breaking-changes
1.3.0-split-minifiers-package
1.4.0-remove-old-dev-bundle-link
1.4.1-add-shell-server-package
1.4.3-split-account-service-packages
1.5-add-dynamic-import-package
1.7-split-underscore-from-meteor-base
1.8.3-split-jquery-from-blaze
local
# This file contains a token that is unique to your project.
# Check it into your repository along with the rest of this directory.
# It can be used for purposes such as:
# - ensuring you don't accidentally deploy one app on top of another
# - providing package authors with aggregated statistics
e4ijb38rb9yn.s8xf55x4kcmj
# Meteor packages used by this project, one per line.
# Check this file (and the other files in this directory) into your repository.
#
# 'meteor add' and 'meteor remove' will edit this file for you,
# but you can also edit it by hand.
meteor-base@1.4.0 # Packages every Meteor app needs to have
mobile-experience@1.0.5 # Packages for a great mobile UX
mongo@1.8.0-rc190.1 # The database Meteor supports right now
reactive-var@1.0.11 # Reactive variable for tracker
tracker@1.2.0 # Meteor's client-side reactive programming library
shell-server@0.4.0 # Server-side component of the `meteor shell` command
http@1.4.2
accounts-password@1.5.2
ardatan:webpack
ardatan:webpack-dev-middleware
android
browser
server
METEOR@1.9-rc.1
accounts-base@1.5.0-rc190.1
accounts-password@1.5.2
allow-deny@1.1.0
ardatan:webpack@0.0.13
ardatan:webpack-dev-middleware@0.0.13
autoupdate@1.6.0
babel-compiler@7.5.0-rc190.1
babel-runtime@1.5.0-rc190.1
base64@1.0.12
binary-heap@1.0.11
boilerplate-generator@1.6.0
callback-hook@1.3.0-rc190.1
check@1.3.1
ddp@1.4.0
ddp-client@2.3.3
ddp-common@1.4.0
ddp-rate-limiter@1.0.7
ddp-server@2.3.0
diff-sequence@1.1.1
dynamic-import@0.5.1
ecmascript@0.14.0-rc190.1
ecmascript-runtime@0.7.0
ecmascript-runtime-client@0.10.0-rc190.1
ecmascript-runtime-server@0.9.0-rc190.1
ejson@1.1.0
email@1.2.3
es5-shim@4.8.0
fetch@0.1.1
geojson-utils@1.0.10
hot-code-push@1.0.4
http@1.4.2
id-map@1.1.0
inter-process-messaging@0.1.0
launch-screen@1.1.1
livedata@1.0.18
localstorage@1.2.0
logging@1.1.20
meteor@1.9.3
meteor-base@1.4.0
minimongo@1.4.5
mobile-experience@1.0.5
mobile-status-bar@1.0.14
modern-browsers@0.1.4
modules@0.15.0-rc190.1
modules-runtime@0.12.0-rc190.1
mongo@1.8.0-rc190.1
mongo-decimal@0.1.1
mongo-dev-server@1.1.0
mongo-id@1.0.7
npm-bcrypt@0.9.3
npm-mongo@3.3.0-rc190.1
ordered-dict@1.1.0
promise@0.11.2
random@1.1.0
rate-limit@1.0.9
reactive-var@1.0.11
reload@1.3.0
retry@1.1.0
routepolicy@1.1.0
service-configuration@1.0.11
sha@1.0.9
shell-server@0.4.0
socket-stream-client@0.2.2
srp@1.0.12
tracker@1.2.0
underscore@1.0.10
url@1.2.0
webapp@1.8.0-rc190.1
webapp-hashing@1.0.9
*
!.meteor/
!node_modules/
!webpack.config.js
# Changelog
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
### [0.0.9](https://git.marcopacs.com/Reza.s/karname-ui/compare/v0.0.8...v0.0.9) (2019-12-22)
### Features
* **Clients ui:** writing Clients ui and methods and publications ([722a05b](https://git.marcopacs.com/Reza.s/karname-ui/commit/722a05b6eb7e4543922ad2196e883dddb87da25c))
### [0.0.8](https://git.marcopacs.com/Reza.s/karname-ui/compare/v0.0.7...v0.0.8) (2019-12-18)
### Features
* **HisLink UI and Back:** write HISLink UI and Backend ([f679152](https://git.marcopacs.com/Reza.s/karname-ui/commit/f6791526e8495de08e7bb6bf9be5e10479624d1e))
### Bug Fixes
* **background color for mobile:** set background color for mobile build ([437d73b](https://git.marcopacs.com/Reza.s/karname-ui/commit/437d73b174218a1f9ec5454c149fe687baccdd7e))
### [0.0.7](https://git.marcopacs.com/Reza.s/karname-ui/compare/v0.0.6...v0.0.7) (2019-11-09)
### Bug Fixes
* **brokerdns:** add broker dns two docker-compose ([ba21347](https://git.marcopacs.com/Reza.s/karname-ui/commit/ba213472eb2b3961bb11c8e89e38cef01927b8c0))
* **testwithfetchworklist:** test app with dockerized fetch worklist ([9c2fc47](https://git.marcopacs.com/Reza.s/karname-ui/commit/9c2fc476f22623e6e5e07cbb781171c9ec6d179b))
* **updatedockercompose:** update docker compose,readme have broker container ([f062095](https://git.marcopacs.com/Reza.s/karname-ui/commit/f06209545fbefe73d5704f09a51852ebb741e22d))
### [0.0.6](https://git.marcopacs.com/Reza.s/karname-ui/compare/v0.0.5...v0.0.6) (2019-11-04)
### Features
* **AddCypress:** add cypress app to karname app ([3312b1c](https://git.marcopacs.com/Reza.s/karname-ui/commit/3312b1ce15edadb25e7e26a3c3c1b39516aed6de))
### [0.0.5](https://git.marcopacs.com/Reza.s/karname-ui/compare/v0.0.2...v0.0.5) (2019-10-30)
### Bug Fixes
* **gitrun:** test windows based container in gitrun ([9424228](https://git.marcopacs.com/Reza.s/karname-ui/commit/9424228ccc682c831b87dbee5bfd66f2786d440f))
### [0.0.4](https://git.marcopacs.com/Reza.s/karname-ui/compare/v0.0.3...v0.0.4) (2019-10-17)
### [0.0.3](https://git.marcopacs.com/Reza.s/karname-ui/compare/v0.0.2...v0.0.3) (2019-10-13)
### Features
* **test gitlabci:** test test-jest standard-version docker-compose ([2c91f1d](https://git.marcopacs.com/Reza.s/karname-ui/commit/2c91f1d9d14b64e2c718d9f6c913c9166099e67a))
### Bug Fixes
* **fix gitlabci:** test gitlabci ([347c364](https://git.marcopacs.com/Reza.s/karname-ui/commit/347c3642f934cf9d9337b8d176d4417301841657))
* **test:** add npminstall to gitlab-ci ([c28320c](https://git.marcopacs.com/Reza.s/karname-ui/commit/c28320c77c2ca8454be830d711ce90ee1a875341))
* **test:** add on failure stage to delete files in failure ([375b277](https://git.marcopacs.com/Reza.s/karname-ui/commit/375b277a580c1401bb54ef045486b3a4ff859f4b))
* **test:** edit gitlabci ([0a01024](https://git.marcopacs.com/Reza.s/karname-ui/commit/0a0102452b353cc7cc7d7e276245152a0f235c9f))
* **test:** edit push to git and add its credentials ([15f67cd](https://git.marcopacs.com/Reza.s/karname-ui/commit/15f67cdd4a07e53b212d81aa6062798d67b67ee0))
* **test:** fix gitlab-ci for pushing changes ([92cc711](https://git.marcopacs.com/Reza.s/karname-ui/commit/92cc7115bb6d2e16044d976b2589e80341960ace))
* **test:** fix gitlab-ci for pushing to git ([7f78fcc](https://git.marcopacs.com/Reza.s/karname-ui/commit/7f78fcc898ccf275fba7ea1e36c91d3055c963a4))
* dsf ([e8b6ab1](https://git.marcopacs.com/Reza.s/karname-ui/commit/e8b6ab1260fa3dc36ab3c0a2a0818c33fc75437a))
* **test:** test standard-version & test-jest docker-compose ([a761881](https://git.marcopacs.com/Reza.s/karname-ui/commit/a7618811d65fdc83a6089503b85bd561cf7336f5))
# karname-ui
## Prerequisite
- windows version must be 1809.
- enable hyper-v and container on windows features
- install docker for desktop on windows
- go to icon tray on windows and right click on docker icon, then click on option 'switch to windows containers...'
* switching from linux to windows will restart docker, please wait until docker start again and then goto next step
- go to icon tray on windows and right click on docker icon, then click on 'settings'
- on the settings window, open the 'Daemon' tab and turn on 'advanced' option
- copy following setting into the configuration section and click on apply button on Daemon tab:
```
{
"registry-mirrors": [],
"insecure-registries": [
"repo.marcopacs.com"
],
"debug": true,
"experimental": false
}
```
* changing docker Daemon settings will restart docker, please wait until docker start again and then goto next step
## Installation Guide
- create a folder in the production server for example in the drive D(for example: D:/build)
* it is better to do not choose drive c
- navigate to created folder in previous step and create a file called docker-compose.yml (for example: D:/build/docker-compose.yml)
- open docker-compose.yml with an editor and paste following statements in the created docker compose file
```
version: "3"
services:
app:
container_name: karname-app
restart: always
image: repo.marcopacs.com/karname/karname-app
ports:
- "80:3000"
environment:
ROOT_URL: ${APP_ROOT_URL:-http://localhost}
MONGO_URL: mongodb://mongo-windows:27017/karname
PORT: 3000
METEOR_SETTINGS: '{"worklistUrl":"http://karname-broker","databusUrl":"http://databus"}'
networks:
default:
external:
name: nat
```
- navigate to Drive D and create a folder called "data"
* it is better to do not choose drive c
- navigate to D:/data and create a folder called "db"
- if you choose drive other than drive D please edit above yaml file ***volumes*** section under ***mongo*** service:
for example if you choose drive E for creating folder "db" at previous step, change
```
volumes:
- D:\data\db:C:\data\db
```
into
```
volumes:
- E:\data\db:C:\data\db
```
- open CMD
- CD to created folder in step 1 (ex: cd D:/build)
- login into repo.marcopacs.com with following command, in the following command, use your username and password that can login into repo.marcopacs.com:
docker login -u username -p password repo.marcopacs.com
- run following command:
docker-compose up -d --force-recreate
- goto localhost
\ No newline at end of file
let usersQueryResult = [];
export function __setUsersQueryResult(result) {
usersQueryResult = result;
}
export const Meteor = {
users: {
findOne: jest.fn().mockImplementation(() => usersQueryResult),
find: jest.fn().mockImplementation(() => ({
fetch: jest.fn().mockReturnValue(usersQueryResult),
count: jest.fn(),
})),
},
};
import { Mongo, MongoInternal } from 'meteor-jest-stubs/lib/meteor/mongo';
export { Mongo, MongoInternal };
// export const Mongo = {
// Collection: jest.fn().mockImplementation(() => ({
// _ensureIndex: (jest.fn()),
// })),
// };
\ No newline at end of file
module.exports = 'test-file-stub';
\ No newline at end of file
module.exports = {};
\ No newline at end of file
import { createLocalVue, mount, shallowMount } from '@vue/test-utils';
import AppFooter from '../client/components/AppFooter.vue'; // name of your Vue component
import vuetifySetting from '../client/plugins/vuetify.js';
import Vue from 'vue';
import Vuetify from 'vuetify';
import { Meteor } from 'meteor/meteor';
import { Mongo } from 'meteor/mongo';
let wrapper;
beforeEach(() => {
Vue.use(Vuetify);
wrapper = shallowMount(AppFooter, {
propsData: {},
mocks: {},
stubs: {},
methods: {},
vuetify: vuetifySetting
});
});
afterEach(() => {
wrapper.destroy();
});
describe('AppFooter', () => {
test('is a Vue instance', () => {
debugger
expect(wrapper.isVueInstance).toBeTruthy();
});
test("MARCO PACS rendered", () => {
expect(wrapper.text()).toContain(`©2005-${ new Date().getFullYear()} MARCO PACS`);
})
test("فارسی rendered", () => {
expect(wrapper.text()).toContain(`فارسی`);
})
});
\ No newline at end of file
<template>
<transition name="fade" mode="out-in">
<keep-alive>
<router-view></router-view>
</keep-alive>
</transition>
</template>
<script>
import i18n from "./plugins/i18n";
import { mapGetters } from "vuex";
export default {
data() {
return {};
},
computed: {
...mapGetters(["lang"])
},
methods: {
changeLocale(locale) {
i18n.locale = locale;
this.$vuetify.lang.current = locale;
}
},
watch: {
lang: function(newLang, oldLang) {
if (newLang == "en") {
this.$vuetify.rtl = false;
this.$vuetify.lang.current = "en";
}
if (newLang == "fa") {
this.$vuetify.rtl = true;
this.$vuetify.lang.current = "fa";
}
this.changeLocale(newLang);
}
}
};
</script>
<style>
#inspire {
font-family: "Vazir";
}
/* label,span{
font-family: Vazir;
} */
.v-messages__message {
font-family: Vazir;
font-size: 0.5rem;
}
tr.v-data-table__selected {
background-color: #b2ebf2 !important;
border-color: #b2ebf2 !important;
}
@import url(views/css/globalcss.css);
</style>
<style scoped>
.fade-enter-active,
.fade-leave-active {
transition-duration: 0.3s;
transition-property: opacity;
transition-timing-function: ease;
}
.fade-enter,
.fade-leave-active {
opacity: 0;
}
</style>
\ No newline at end of file
<template>
<v-footer
color="#c0d7d6"
height="40px"
app
elevation="24"
class="d-flex justify-center align-center text-center red--text"
>
<h5>©2005-{{ new Date().getFullYear() }} MARCO PACS</h5>
<v-menu transition="slide-x-transition">
<template v-slot:activator="{ on }">
<v-btn
class="changeLangBtn"
color="red"
dark
v-on="on"
depressed
text
>{{$t('AppFooter.appLang')}}</v-btn>
</template>
<v-list>
<v-list-item v-for="lng in langList" :key="lng.name" @click="setLang(lng.alias)">
<v-list-item-title>{{lng.name}}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-footer>
</template>
<script>
import { mapActions } from "vuex";
export default {
name: "app-footer",
data() {
return {
langList: [
{ name: "فارسی", alias: "fa" },
{ name: "English", alias: "en" }
]
};
},
methods: {
...mapActions(["setLang"])
}
};
</script>
<style scoped>
.changeLangBtn {
position: absolute;
left: 0;
}
</style>
<template>
<div>
<v-navigation-drawer v-model="drawerRight" app clipped right>
<v-list dense>
<v-list-item @click.stop="right = !right">
<v-list-item-action>
<v-icon>mdi-exit-to-app</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>Open Temporary Drawer</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
<v-app-bar app clipped-right color="blue-grey" dark>
<v-app-bar-nav-icon @click.stop="drawer = !drawer"></v-app-bar-nav-icon>
<v-toolbar-title>Toolbar</v-toolbar-title>
<div class="flex-grow-1"></div>
<v-app-bar-nav-icon @click.stop="drawerRight = !drawerRight"></v-app-bar-nav-icon>
</v-app-bar>
<v-navigation-drawer v-model="drawer" app>
<v-list dense>
<v-list-item @click.stop="left = !left">
<v-list-item-action>
<v-icon>mdi-exit-to-app</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>Open Temporary Drawer</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
<v-navigation-drawer v-model="left" fixed temporary></v-navigation-drawer>
<v-content>
<v-container class="fill-height" fluid>
<v-row justify="center" align="center">
<v-col class="shrink">
<v-tooltip right>
<template v-slot:activator="{ on }">
<v-btn :href="source" icon large target="_blank" v-on="on">
<v-icon large>mdi-code-tags</v-icon>
</v-btn>
</template>
<span>Source</span>
</v-tooltip>
<v-tooltip right>
<template v-slot:activator="{ on }">
<v-btn
icon
large
href="https://codepen.io/johnjleider/pen/QewYYx"
target="_blank"
v-on="on"
>
<v-icon large>mdi-codepen</v-icon>
</v-btn>
</template>
<span>Codepen</span>
</v-tooltip>
</v-col>
</v-row>
</v-container>
</v-content>
<v-navigation-drawer v-model="right" fixed right temporary></v-navigation-drawer>
<v-footer app color="blue-grey" class="white--text">
<span>Vuetify</span>
<div class="flex-grow-1"></div>
<span>&copy; 2019</span>
</v-footer>
</div>
</template>
\ No newline at end of file
<template>
<!-- <v-app-bar app elevation="24" color="teal lighten-3"> -->
<v-app-bar fixed app elevation="24" color="#c0d7d6">
<v-toolbar-title class="red--text">{{$t('AppHeader.appName')}}</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn text color="red red--text" :to="btnTo" :data-cy="btnToProp">
<v-icon left>{{ btnIconName }}</v-icon>
<strong>{{$t(btnLabel)}}</strong>
</v-btn>
</v-app-bar>
<!-- <v-toolbar absolute fixed app elevation="24" color="#0065613b" style="width:100%">
<v-toolbar-title class="red--text">{{$t('AppHeader.appName')}}</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn text color="red red--text" :to="btnTo">
<v-icon left>{{ btnIconName }}</v-icon>
<strong>{{$t(btnLabel)}}</strong>
</v-btn>
</v-toolbar> -->
</template>
<script>
export default {
name: "app-header",
data() {
return {
btnTo: null
};
},
props: ["btnToProp", "btnLabel", "btnIconName"],
created() {
this.btnTo = "/" + this.btnToProp;
}
};
</script>
\ No newline at end of file
<template>
<v-container>
<v-snackbar color="primary" v-model="snackbar" top>
{{$t("Client.DeleteMessage")}}
<v-btn color="pink" @click="deleteClient">{{$t("Client.YesBtn")}}</v-btn>
<v-btn color="pink" @click="snackbar = false">{{$t("Client.NoBtn")}}</v-btn>
</v-snackbar>
<v-snackbar color="primary" v-model="alertSnackbar" :timeout="2000">{{alertText}}</v-snackbar>
<v-dialog v-model="dialog" max-width="600px">
<v-card>
<v-card-title>
<span>{{newOrEdit=="new"?$t("Client.newText"):$t("Client.editText")}} {{$t("Client.clientName")}}</span>
</v-card-title>
<v-card-text>
<v-container>
<div>
<v-progress-linear :active="loading" :indeterminate="loading" color="cyan lighten-2"></v-progress-linear>
</div>
<v-row dense>
<v-col cols="12" md="6">
<v-text-field label="Caption" v-model="ClientForm.Caption"></v-text-field>
</v-col>
<v-col cols="12" md="6">
<v-text-field label="AETitle" type="text" v-model="ClientForm.AETitle"></v-text-field>
</v-col>
<v-col cols="12" md="6">
<v-text-field label="Hostname" type="text" v-model="ClientForm.Hostname"></v-text-field>
</v-col>
<v-col cols="12" md="6">
<v-text-field label="Port" type="text" v-model="ClientForm.Port"></v-text-field>
</v-col>
</v-row>
</v-container>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
color="blue darken-1"
text
@click="createOrEditClient"
>{{newOrEdit=="new"?$t("Client.createBtn"):$t("Client.editBtn")}}</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<v-row justify="center" dense class="flex-wrap mb-6">
<v-col md="7" lg="6" cols="12">
<v-card tile>
<v-card-actions>
<v-row style="margin:auto">
<v-col cols="12" class="d-flex justify-center align-center flex-wrap">
<v-btn color="rgb(94, 181, 177,.85)" class="white--text" @click="openNewDialog">
<strong>{{$t("HISLink.newBtn")}}</strong>
</v-btn>
<v-btn color="rgb(94, 181, 177,.85)" class="white--text" @click="openEditDialog">
<strong>{{$t("HISLink.editBtn")}}</strong>
</v-btn>
<v-btn color="rgb(94, 181, 177,.85)" class="white--text" @click="deleteSnackbar">
<strong>{{$t("HISLink.deleteBtn")}}</strong>
</v-btn>
</v-col>
</v-row>
</v-card-actions>
</v-card>
</v-col>
</v-row>
<v-row justify="center" dense class="flex-wrap mt-6">
<v-col md="9" cols="12">
<v-data-table
v-model="selectedItemInTable"
:headers="headerOfTable"
:items="itemsOfTable"
item-key="_id"
class="elevation-1"
style="width:100%"
fixed-header
hide-default-footer
disable-pagination
show-select
single-select
:sort-by.sync="sortByTable"
:sort-desc.sync="sortDescTable"
height="73vh"
@click:row="clickRow"
></v-data-table>
</v-col>
</v-row>
</v-container>
</template>
<script>
import Client from "../../imports/api/collections/clients.js";
import { Meteor } from "meteor/meteor";
export default {
data() {
return {
sortByTable: undefined,
sortDescTable: undefined,
selectedItemInTable: [],
dialog: false,
newOrEdit: "",
ClientForm: {
Caption: "",
AETitle: "",
Hostname: "",
Port: "",
_id: ""
},
snackbar: false,
alertSnackbar: false,
alertText: "",
loading: false
};
},
computed: {
headerOfTable() {
let headers = ["Caption", "AETitle", "Hostname", "Port"];
let headerObjs = [];
for (let header of headers) {
headerObjs.push({
text: header,
value: header,
class: "text-center",
width: 180
});
}
return headerObjs;
},
itemsOfTable() {
this.loading = false;
this.dialog = false;
if (this.clients && this.clients.length > 0) {
return this.clients;
}
return [];
}
},
methods: {
clickRow(item) {
if (
this.selectedItemInTable.length > 0 &&
this.selectedItemInTable[0]._id == item._id
) {
this.selectedItemInTable = [];
} else {
this.selectedItemInTable = [];
this.selectedItemInTable = [item];
}
},
openNewDialog() {
for (let prop in this.ClientForm) {
this.$set(this.ClientForm, prop, "");
}
this.$set(this.ClientForm, "_id", "");
this.newOrEdit = "new";
this.dialog = true;
},
openEditDialog() {
if (this.selectedItemInTable.length == 0) {
this.alertSnackbarMethod(this.$t("Client.clientSelectStatement"));
return;
}
for (let prop in this.ClientForm) {
if (this.selectedItemInTable[0][prop] != undefined) {
this.$set(this.ClientForm, prop, this.selectedItemInTable[0][prop]);
}
}
this.$set(this.ClientForm, "_id", this.selectedItemInTable[0]["_id"]);
this.newOrEdit = "edit";
this.dialog = true;
},
createOrEditClient() {
this.loading = true;
let me = this;
if (this.newOrEdit == "new") {
Meteor.call("createClient", this.ClientForm, function() {
// me.dialog = false;
});
}
if (this.newOrEdit == "edit") {
Meteor.call("editClient", this.ClientForm, function() {
// me.dialog = false;
me.selectedItemInTable = [];
});
}
},
deleteClient() {
let me = this;
this.snackbar = false;
if (this.selectedItemInTable.length == 0) {
me.alertSnackbarMethod(me.$t("Client.clientSelectStatement"));
return;
}
let deleteHislink = {};
deleteHislink._id = this.selectedItemInTable[0]["_id"];
Meteor.call("deleteClient", deleteHislink, function() {
me.alertSnackbarMethod(this.$t("Client.clientDeleteStatement"));
});
},
deleteSnackbar() {
this.snackbar = true;
},
alertSnackbarMethod(text) {
this.alertText = text;
this.alertSnackbar = true;
}
},
meteor: {
$subscribe: {
clients: []
},
clients() {
return Client.find({}).fetch();
}
}
};
</script>
<style>
</style>
\ No newline at end of file
This diff is collapsed.
<template>
<v-navigation-drawer app right clipped :width="$vuetify.breakpoint.width/3" bottom>
<v-list dense>
<v-list-item>
<v-list-item-action>
<v-icon>mdi-exit-to-app</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>Open Temporary Drawer</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
</template>
\ No newline at end of file
This diff is collapsed.
<template>
<v-dialog v-model="HisWorklistDialog" max-width="900px">
<v-card>
<v-progress-linear
:active="HisWorklistLoading"
:indeterminate="HisWorklistLoading"
absolute
top
color="cyan lighten-2"
></v-progress-linear>
<v-card-title>
<v-icon class="mr-1" @click="internalCloseDialog">close</v-icon>
<span>{{$t("HisWorklist.title")}}</span>
</v-card-title>
<v-card-text class="ma-0 pa-0" v-if="$vuetify.breakpoint.mdAndUp">
<v-container class="cyan lighten-2" style="border-radius: 5px;">
<v-card class="pa-3 pr-6 ma-4">
<!-- <v-row dense>
<v-col cols="9">
<v-autocomplete :items="itemsOfBrands" label="Brand" v-model="selectedBrand"></v-autocomplete>
</v-col>
</v-row>-->
<v-row dense>
<v-data-table
:headers="headerOfTable"
:items="itemsOfTable"
item-key="_id"
class="elevation-1"
style="width:100%"
fixed-header
disable-sort
height="600px"
></v-data-table>
</v-row>
</v-card>
</v-container>
</v-card-text>
</v-card>
</v-dialog>
</template>
<script>
import Brands from "../../imports/api/collections/brands.js";
import BrandCollections from "../../imports/api/collections/worklist4hislink.js";
import { Mongo } from "meteor/mongo";
export default {
props: ["HisWorklistDialogProp", "closeDialog", "selectedBrand"],
data: () => ({
HisWorklistLoading: false,
HisWorklistDialog: false
// selectedBrand: null
}),
computed: {
itemsOfBrands() {
if (this.brands && this.brands.length > 0) {
return this.brands.map(brand => {
return brand.Name;
});
}
return [];
},
itemsOfTable() {
if (this.worklist4hislink && this.worklist4hislink.length > 0) {
let worklistArray = [];
for (let worklist of this.worklist4hislink) {
let tempWorklist = {};
for (let prop in worklist) {
tempWorklist[prop] = JSON.stringify(worklist[prop]);
}
worklistArray.push(tempWorklist);
}
return worklistArray;
}
return [];
},
headerOfTable() {
if (this.worklist4hislink && this.worklist4hislink.length > 0) {
let headerNames = [];
let worklist = this.worklist4hislink[0];
for (let prop in worklist) {
headerNames.push({
text: prop,
value: prop,
class: "text-center",
width: 180
});
}
return headerNames;
}
return [];
}
},
watch: {
"$subReady.worklist4hislink"(ready) {
this.HisWorklistLoading = false;
},
HisWorklistDialog(newvalue, oldvalue) {
if (newvalue == false) {
this.closeDialog();
} else {
this.HisWorklistLoading = true;
}
},
HisWorklistDialogProp(newvalue, oldvalue) {
this.HisWorklistDialog = newvalue;
}
},
methods: {
internalCloseDialog() {
this.HisWorklistDialog = false;
}
},
meteor: {
$subscribe: {
// brands: [],
worklist4hislink: function() {
return [this.selectedBrand];
}
},
// brands() {
// return Brands.find({}).fetch();
// },
worklist4hislink() {
if (this.selectedBrand == null) return [];
return BrandCollections[this.selectedBrand].find({}).fetch();
}
}
};
</script>
<style scoped>
</style>
\ No newline at end of file
<template>
<div>
<v-btn color="rgb(94, 181, 177,.85)" class="white--text ma-3" @click="registerDialog=true">
<strong>{{$t("WorkList.Register")}}</strong>
</v-btn>
<v-dialog v-model="registerDialog" max-width="900px">
<v-card>
<v-progress-linear
:active="registerLoading"
:indeterminate="registerLoading"
absolute
top
color="cyan lighten-2"
></v-progress-linear>
<v-card-title>
<v-icon @click="closeRegisterPatient" class="mr-1">close</v-icon>
<span>{{$t("WorkList.RegisterPatient")}}</span>
</v-card-title>
<v-card-text class="ma-0 pa-0" v-if="$vuetify.breakpoint.mdAndUp">
<v-container class="cyan lighten-2" style="border-radius: 5px;">
<v-card class="pa-3 pr-6 ma-4">
<v-row dense>
<v-col md="4">
<v-text-field
label="FarsiFirstName"
v-model="registerPatient.FarsiFirstName"
type="text"
></v-text-field>
</v-col>
<v-col md="4">
<v-text-field
label="FarsiLastName"
v-model="registerPatient.FarsiLastName"
type="text"
></v-text-field>
</v-col>
<v-col md="4">
<v-text-field label="HISID" v-model="registerPatient.HISID" type="text"></v-text-field>
</v-col>
<v-col md="4">
<v-text-field label="Modality" v-model="registerPatient.Modality" type="text"></v-text-field>
</v-col>
<v-col md="4">
<v-text-field label="PatientAge" v-model="registerPatient.PatientAge" type="text"></v-text-field>
</v-col>
<v-col md="4">
<v-autocomplete
:items="itemsOfDeviceMap"
label="DeviceMap"
v-model="selectedDeviceMap"
item-text="GroupName"
item-value="GroupName"
return-object
></v-autocomplete>
</v-col>
</v-row>
</v-card>
</v-container>
</v-card-text>
<v-card-text class="ma-0 pa-0" v-else>
<v-container class="cyan lighten-2" style="border-radius: 5px;">
<v-card class="pa-3 pr-6 ma-4">
<v-row dense>
<v-col cols="6">
<v-text-field
label="FarsiFirstName"
type="text"
v-model="registerPatient.FarsiFirstName"
></v-text-field>
</v-col>
<v-col cols="6">
<v-text-field
label="FarsiLastName"
type="text"
v-model="registerPatient.FarsiLastName"
></v-text-field>
</v-col>
<v-col cols="6">
<v-text-field label="HISID" type="text" v-model="registerPatient.HISID"></v-text-field>
</v-col>
<v-col cols="6">
<v-text-field label="Modality" type="text" v-model="registerPatient.Modality"></v-text-field>
</v-col>
<v-col cols="6">
<v-text-field label="PatientAge" type="text" v-model="registerPatient.PatientAge"></v-text-field>
</v-col>
<v-col cols="6">
<v-autocomplete
:items="itemsOfDeviceMap"
label="DeviceMap"
v-model="selectedDeviceMap"
item-text="GroupName"
item-value="CodeInHIS"
return-object
></v-autocomplete>
</v-col>
</v-row>
</v-card>
</v-container>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
color="blue darken-1"
class="white--text"
@click="registerPatientMethod"
>{{$t("WorkList.CreatePatient")}}</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>
<script>
import Devicemap from "../../imports/api/collections/devicemap.js";
export default {
data() {
return {
registerPatient: {
FarsiFirstName: "",
FarsiLastName: "",
HISID: "",
Modality: "",
PatientAge: ""
},
registerLoading: false,
registerDialog: false,
selectedDeviceMap: null
};
},
computed: {
itemsOfDeviceMap() {
if (this.devicemaps && this.devicemaps.length > 0) {
return this.devicemaps;
}
return [];
}
},
methods: {
closeRegisterPatient() {
this.registerDialog = false;
},
registerPatientMethod(item) {
let me = this;
this.registerLoading = true;
let registerPatient = {
...this.registerPatient
}
if (this.selectedDeviceMap) {
registerPatient.CodeInHIS = this.selectedDeviceMap.CodeInHIS;
}
Meteor.call("Register", registerPatient, function(err, result) {
me.registerLoading = false;
me.registerPatient = {
FarsiFirstName: "",
FarsiLastName: "",
HISID: "",
Modality: "",
PatientAge: ""
};
me.closeRegisterPatient();
});
}
},
meteor: {
$subscribe: {
devicemaps: []
},
devicemaps() {
return Devicemap.find({}).fetch();
}
}
};
</script>
<style scoped>
</style>
\ No newline at end of file
<template>
<v-container>
<v-snackbar color="primary" v-model="snackbar" top>
{{$t("Users.DeleteMessage")}}
<v-btn color="pink" @click="deleteUser">{{$t("Users.YesBtn")}}</v-btn>
<v-btn color="pink" @click="snackbar = false">{{$t("Users.NoBtn")}}</v-btn>
</v-snackbar>
<v-snackbar color="primary" v-model="alertSnackbar" :timeout="2000">{{alertText}}</v-snackbar>
<v-dialog v-model="dialog" max-width="600px">
<v-card>
<v-card-title>
<span>{{newOrEdit=="new"?$t("Users.newText"):$t("Users.editText")}} {{$t("Users.UserName")}}</span>
</v-card-title>
<v-card-text>
<v-container>
<div>
<v-progress-linear :active="loading" :indeterminate="loading" color="cyan lighten-2"></v-progress-linear>
</div>
<v-row dense>
<v-col cols="12" md="6">
<v-text-field label="Username" v-model="UserForm.username"></v-text-field>
</v-col>
<v-col cols="12" md="6">
<v-text-field type="password" label="Password" v-model="UserForm.password"></v-text-field>
</v-col>
</v-row>
</v-container>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
color="blue darken-1"
text
@click="createOrEditUser"
>{{newOrEdit=="new"?$t("Users.createBtn"):$t("Users.editBtn")}}</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<v-row justify="center" dense class="flex-wrap mb-6">
<v-col md="7" lg="6" cols="12">
<v-card tile>
<v-card-actions>
<v-row style="margin:auto">
<v-col cols="12" class="d-flex justify-center align-center flex-wrap">
<v-btn color="rgb(94, 181, 177,.85)" class="white--text" @click="openNewDialog">
<strong>{{$t("HISLink.newBtn")}}</strong>
</v-btn>
<v-btn color="rgb(94, 181, 177,.85)" class="white--text" @click="openEditDialog">
<strong>{{$t("HISLink.editBtn")}}</strong>
</v-btn>
<v-btn color="rgb(94, 181, 177,.85)" class="white--text" @click="deleteSnackbar">
<strong>{{$t("HISLink.deleteBtn")}}</strong>
</v-btn>
</v-col>
</v-row>
</v-card-actions>
</v-card>
</v-col>
</v-row>
<v-row justify="center" dense class="flex-wrap mt-6">
<v-col md="9" cols="12">
<v-data-table
v-model="selectedItemInTable"
:headers="headerOfTable"
:items="itemsOfTable"
item-key="_id"
class="elevation-1"
style="width:100%"
fixed-header
hide-default-footer
disable-pagination
show-select
single-select
:sort-by.sync="sortByTable"
:sort-desc.sync="sortDescTable"
height="73vh"
@click:row="clickRow"
></v-data-table>
</v-col>
</v-row>
</v-container>
</template>
<script>
import { Meteor } from "meteor/meteor";
export default {
data() {
return {
sortByTable: undefined,
sortDescTable: undefined,
selectedItemInTable: [],
dialog: false,
newOrEdit: "",
UserForm: {
username: "",
password: "",
_id: ""
},
snackbar: false,
alertSnackbar: false,
alertText: "",
loading: false
};
},
computed: {
headerOfTable() {
let headers = ["username"];
let headerObjs = [];
for (let header of headers) {
headerObjs.push({
text: header,
value: header,
class: "text-center",
width: 180
});
}
return headerObjs;
},
itemsOfTable() {
this.loading = false;
this.dialog = false;
if (this.users && this.users.length > 0) {
return this.users;
}
return [];
}
},
methods: {
clickRow(item) {
if (
this.selectedItemInTable.length > 0 &&
this.selectedItemInTable[0]._id == item._id
) {
this.selectedItemInTable = [];
} else {
this.selectedItemInTable = [];
this.selectedItemInTable = [item];
}
},
openNewDialog() {
for (let prop in this.UserForm) {
this.$set(this.UserForm, prop, "");
}
this.$set(this.UserForm, "_id", "");
this.newOrEdit = "new";
this.dialog = true;
},
openEditDialog() {
if (this.selectedItemInTable.length == 0) {
this.alertSnackbarMethod(this.$t("Users.userSelectStatement"));
return;
}
for (let prop in this.UserForm) {
if (this.selectedItemInTable[0][prop] != undefined) {
this.$set(this.UserForm, prop, this.selectedItemInTable[0][prop]);
}
}
this.$set(this.UserForm, "_id", this.selectedItemInTable[0]["_id"]);
this.newOrEdit = "edit";
this.dialog = true;
},
createOrEditUser() {
this.loading = true;
let me = this;
if (this.newOrEdit == "new") {
Meteor.call("createUser1", this.UserForm, function() {
// me.dialog = false;
});
}
if (this.newOrEdit == "edit") {
Meteor.call("editUser1", this.UserForm, function() {
// me.dialog = false;
me.selectedItemInTable = [];
});
}
},
deleteUser() {
debugger;
let me = this;
this.snackbar = false;
if (this.selectedItemInTable.length == 0) {
me.alertSnackbarMethod(this.$t("Users.userSelectStatement"));
return;
}
let deleteUser = {};
deleteUser._id = this.selectedItemInTable[0]["_id"];
Meteor.call("deleteUser1", deleteUser, function() {
me.alertSnackbarMethod(this.$t("Users.userDeleteStatement"));
});
},
deleteSnackbar() {
this.snackbar = true;
},
alertSnackbarMethod(text) {
this.alertText = text;
this.alertSnackbar = true;
}
// beforeRouteEnter(to, from, next) {
// next(vm => {
// if (
// Meteor.userId() &&
// Meteor.users.findOne({ _id: Meteor.userId() }).username !=
// "marcoadmin"
// ) {
// vm.$router.push("/main/worklist");
// } else {
// vm.$router.push("/signin");
// }
// });
// }
},
meteor: {
$subscribe: {
users: []
},
users() {
return Meteor.users.find({ username: { $ne: "marcoadmin" } }).fetch();
}
}
};
</script>
<style>
</style>
\ No newline at end of file
This diff is collapsed.
<head>
<link rel="shortcut icon" type="image/png" href="/img/logo.png" />
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
<title>کارنامه</title>
</head>
<body>
<div id="app"></div>
</body>
\ No newline at end of file
import Vue from 'vue';
import App from './App.vue';
import { Meteor } from 'meteor/meteor';
import vuetify from './plugins/vuetify';
import VueMeteorTracker from 'vue-meteor-tracker';
Vue.use(VueMeteorTracker);
import VueRouter from 'vue-router';
Vue.use(VueRouter);
import { Plugin } from 'vue-fragment'
Vue.use(Plugin);
import routes from './plugins/routes';
const router = new VueRouter({
mode: 'history',
routes
});
import { store } from './store/store';
import i18n from './plugins/i18n';
Meteor.startup(() => {
new Vue({
i18n,
router,
vuetify,
store,
el: "#app",
render: h => h(App)
});
});
\ No newline at end of file
This diff is collapsed.
// const Login = () =>
// import ('../views/Login.vue')
// const Home = () =>
// import ('../views/Home.vue')
// const Register = () =>
// import ('../views/Register.vue')
// const ChangePassword = () =>
// import ('../views/ChangePassword.vue')
// const Main = () =>
// import ('../views/Main.vue')
// const EditWorkList = () =>
// import ('../components/EditWorkList.vue')
// const WorkList = () =>
// import ('../components/Worklist.vue')
// import Login from '../views/Login.vue';
// import Home from '../views/Home.vue';
// import Register from '../views/Register.vue';
// import ChangePassword from '../views/ChangePassword.vue';
// import Main from '../views/Main.vue';
// import EditWorkList from '../components/EditWorkList.vue';
// import WorkList from '../components/Worklist.vue';
// import AppVersion from '../views/AppVersion.vue';
// const routes = [{
// path: '/',
// component: () =>
// import ('../views/Home.vue'),
// name: 'Home'
// },
// {
// path: '/appversion',
// component: AppVersion,
// name: 'AppVersion'
// },
// {
// path: '/signin',
// component: () =>
// import ('../views/Login.vue'),
// name: 'signin'
// },
// {
// path: '/signup',
// component: () =>
// import ('../views/Register.vue'),
// name: 'signup'
// },
// {
// path: '/changePassword',
// component: () =>
// import ('../views/ChangePassword.vue'),
// name: 'changePassword'
// }, {
// path: '/main',
// component: () =>
// import ('../views/Main.vue'),
// name: 'main',
// children: [{
// path: "worklist",
// name: "worklist",
// components: {
// default: () =>
// import ('../components/Worklist.vue'),
// edit_worklist: () =>
// import ('../components/EditWorkList.vue')
// }
// }]
// }
// ];
// export default routes;
import Login from '../views/Login.vue';
import Home from '../views/Home.vue';
import Register from '../views/Register.vue';
import ChangePassword from '../views/ChangePassword.vue';
import Main from '../views/Main.vue';
import EditWorkList from '../components/EditWorkList.vue';
import RegisterPatient from '../components/RegisterPatient.vue';
import WorkList from '../components/Worklist.vue';
import HisLink from '../components/HisLink.vue';
import DeviceMap from '../components/DeviceMap.vue';
import Client from '../components/Client.vue';
import Users from '../components/Users.vue';
import AppVersion from '../views/AppVersion.vue';
const routes = [{
path: '/',
component: Home,
name: 'Home'
},
{
path: '/appversion',
component: AppVersion,
name: 'AppVersion'
},
{
path: '/signin',
component: Login,
name: 'signin'
},
{
path: '/signup',
component: Register,
name: 'signup'
},
{
path: '/changePassword',
component: ChangePassword,
name: 'changePassword'
}, {
path: '/main',
component: Main,
name: 'main',
children: [{
path: "worklist",
name: "worklist",
components: {
default: WorkList,
register_patient: RegisterPatient
// edit_worklist: WorkList
}
}, {
path: "hislink",
name: "hislink",
component: HisLink
}, {
path: "devicemap",
name: "devicemap",
component: DeviceMap
}, {
path: "client",
name: "client",
component: Client
}, {
path: "users",
name: "users",
component: Users
}]
}
];
export default routes;
\ No newline at end of file
// import '@mdi/font/css/materialdesignicons.css';
import 'vuetify/dist/vuetify.min.css';
import '@mdi/font/css/materialdesignicons.css';
import 'material-design-icons-iconfont/dist/material-design-icons.css';
import Vue from 'vue';
import Vuetify from 'vuetify';
import '../../public/fonts/font.css';
Vue.use(Vuetify);
import fa from 'vuetify/es5/locale/fa';
import en from 'vuetify/es5/locale/en';
export default new Vuetify({
lang: {
locales: { fa, en },
current: 'en'
},
icons: {
iconfont: 'mdi', // default - only for display purposes
},
rtl: false,
});
\ No newline at end of file
const state = {
lang: 'en'
}
const mutations = {
'SET_LANG' (state, lang) {
state.lang = lang;
}
}
const actions = {
setLang({ commit }, lang) {
commit('SET_LANG', lang);
},
}
const getters = {
lang: state => {
return state.lang;
}
}
export default {
state,
mutations,
getters,
actions
};
\ No newline at end of file
import Vue from 'vue';
import Vuex from 'vuex';
import appSettings from './modules/appSetting';
Vue.use(Vuex);
export const store = new Vuex.Store({
modules: {
appSettings
}
});
\ No newline at end of file
<template>
<div>
<div>FullVersion: {{FullVersion}}</div>
<div>Version: {{Version}}</div>
<div>CommitHash: {{CommitHash}}</div>
<div>BRANCH: {{Branch}}</div>
<div>MAJOR: {{Major}}</div>
<div>MINOR: {{Minor}}</div>
<div>PATCH: {{Patch}}</div>
</div>
</template>
<script>
export default {
data() {
return {
Version: VERSION,
CommitHash: COMMITHASH,
Branch: BRANCH,
Major: MAJOR,
Minor: MINOR,
Patch: PATCH,
FullVersion: FULLVERSION
};
}
};
</script>
\ No newline at end of file
<template>
<v-app id="inspire">
<auth-header btnToProp="signin" btnLabel="Register.loginBtn" btnIconName="mdi-login"></auth-header>
<v-content>
<v-container
style="background-color:rgb(94, 181, 177,.85)"
fluid
class="align-center fill-height backgroundImg"
>
<v-row justify="center" class="loginCard">
<v-col xs="8" sm="6" md="4" lg="3">
<v-card class="elevation-12 roundedCard" light elevation="24">
<v-toolbar color="rgb(94, 181, 177,.85)" dark>
<v-icon class="ma-3">mdi-lock-reset</v-icon>
<v-toolbar-title>{{$t('ChangePassword.formHeader')}}</v-toolbar-title>
</v-toolbar>
<v-card-text>
<v-form>
<v-container fluid class="flex-wrap">
<v-row>
<v-col cols="12">
<v-text-field
:label="$t('ChangePassword.username')"
prepend-icon="mdi-account-circle"
:rules="[rules.required]"
v-model="username"
ref="usernameTextField"
persistent-hint
:hint="this.usernameAlert?`${$t('ChangePassword.usernameAlert')}`:''"
@keyup.enter="changePassword()"
/>
</v-col>
<v-col cols="12">
<v-text-field
:type="!showPassword1?'password' :'text'"
:label="$t('ChangePassword.oldPassword')"
prepend-icon="mdi-lock"
@click:append="showPassword1 = !showPassword1"
:append-icon="showPassword1 ? 'mdi-eye': 'mdi-eye-off'"
v-model="oldPass"
:rules="[rules.required, rules.min]"
ref="oldPassTextField"
persistent-hint
:hint="this.oldPassAlert?`${$t('ChangePassword.oldPasswordAlert')}`:''"
@keyup.enter="changePassword()"
/>
</v-col>
<v-col cols="12">
<v-text-field
:type="!showPassword2?'password' :'text'"
:label="$t('ChangePassword.newPassword')"
prepend-icon="mdi-lock"
@click:append="showPassword2 = !showPassword2"
:append-icon="showPassword2 ? 'mdi-eye': 'mdi-eye-off'"
v-model="newPass"
:rules="[rules.required, rules.matchPass]"
ref="newPassTextField"
persistent-hint
:hint="this.newPassAlert?`${$t('ChangePassword.newPasswordAlert')}`:''"
@keyup.enter="changePassword()"
/>
</v-col>
</v-row>
</v-container>
</v-form>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
style="width:100%"
class="white--text"
color="rgb(94, 181, 177,.85)"
rounded
:loading="loading"
:disabled="loading"
@click="changePassword()"
>
<v-icon left>mdi-lock-question</v-icon>
<small>{{$t('ChangePassword.changePasswordBtn')}}</small>
<template v-slot:loader>
<span>{{$t('ChangePassword.loadingText')}}</span>
</template>
</v-btn>
</v-card-actions>
</v-card>
</v-col>
</v-row>
<ul class="bubble-boxes">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<v-snackbar v-model="snackbar" :color="snackbarColor" :timeout="2000">{{ snackbarText }}</v-snackbar>
</v-container>
</v-content>
<app-footer></app-footer>
</v-app>
</template>
<script>
import AppFooter from "../components/AppFooter.vue";
import AuthHeader from "../components/AuthHeader.vue";
import { Accounts } from "meteor/accounts-base";
import { Meteor } from "meteor/meteor";
export default {
components: {
"app-footer": AppFooter,
"auth-header": AuthHeader
},
data() {
return {
snackbar: false,
snackbarText: "",
snackbarColor: "red",
loading: false,
username: null,
usernameAlert: false,
oldPass: null,
oldPassAlert: false,
newPass: null,
newPassAlert: false,
showPassword1: false,
showPassword2: false,
rules: {
required: value => !!value || this.$t("ChangePassword.required"),
min: v => {
if (v == undefined) return true;
return v.length >= 8 || this.$t("ChangePassword.min8Character");
},
matchPass: v => {
return (
this.oldPass !== this.newPass || this.$t("ChangePassword.matchPass")
);
}
}
};
},
methods: {
changePassword() {
const that = this;
if (this.username == null || this.username.length == 0) {
this.$refs.usernameTextField.focus();
this.usernameAlert = true;
return;
}
if (this.oldPass == null || this.oldPass.length == 0) {
this.$refs.oldPassTextField.focus();
this.oldPassAlert = true;
return;
}
if (this.newPass == null || this.newPass.length == 0) {
this.$refs.newPassTextField.focus();
this.newPassAlert = true;
return;
}
if (this.oldPass == this.newPass) {
return;
}
this.loading = true;
Meteor.call(
"changePass",
this.username,
this.oldPass,
this.newPass,
function(error, result) {
if (error) {
that.loading = false;
if (error.error == "NotFoundUser") {
that.snackbarColor = "red";
that.snackbarText = that.$t("ChangePassword.NotFoundUser");
that.snackbar = true;
return;
}
if (error.error == "CheckPassError") {
that.snackbarColor = "red";
that.snackbarText = that.$t("ChangePassword.CheckPassError");
that.snackbar = true;
return;
}
that.snackbarColor = "red";
that.snackbarText = that.$t("ChangePassword.internalServerError");
that.snackbar = true;
return;
}
Meteor.setTimeout(() => {
that.loading = false;
that.snackbarColor = "rgb(94, 181, 177,.85)";
that.snackbarText = that.$t("ChangePassword.SuccessChangePass");
that.snackbar = true;
}, 1000);
}
);
}
}
};
</script>
<style scoped>
.backgroundImg {
background-color: #abdae4ad;
background-image: linear-gradient(
141deg,
#9fb8ad 0%,
#1fc8db 51%,
#2ce8ceb0 75%
);
}
img {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
overflow-y: hidden;
opacity: 0.6;
filter: grayscale(0.5) blur(2px);
z-index: 0;
}
.loginCard {
z-index: 1;
}
.backgroundImg {
overflow-y: hidden;
}
.roundedCard {
border-radius: 20px;
}
/* loader */
@-moz-keyframes loader {
from {
transform: rotate(0);
}
to {
transform: rotate(360deg);
}
}
@-webkit-keyframes loader {
from {
transform: rotate(0);
}
to {
transform: rotate(360deg);
}
}
@-o-keyframes loader {
from {
transform: rotate(0);
}
to {
transform: rotate(360deg);
}
}
@keyframes loader {
from {
transform: rotate(0);
}
to {
transform: rotate(360deg);
}
}
</style>
\ No newline at end of file
<template>
<div>Home Page</div>
</template>
<script>
import { Meteor } from "meteor/meteor";
export default {
beforeRouteEnter(to, from, next) {
next(vm => {
if (Meteor.userId()) {
vm.$router.push("/main/worklist");
} else {
vm.$router.push("/signin");
}
});
}
};
</script>
\ No newline at end of file
<template>
<!-- <div style="height:100%"> -->
<v-app id="inspire">
<auth-header btnToProp="signup" btnLabel="Login.registerBtn" btnIconName="mdi-account-plus"></auth-header>
<v-content>
<v-container
style="background-color:rgb(94, 181, 177,.85)"
fluid
fill-height
class="align-center backgroundImg"
>
<v-row justify="center" class="loginCard">
<v-col xs="8" sm="6" md="4" lg="3">
<v-card class="elevation-12 roundedCard" light elevation="24">
<v-toolbar color="rgb(94, 181, 177,.85)" dark>
<v-icon class="ma-3">mdi-login</v-icon>
<v-toolbar-title>{{$t('Login.loginHeader')}}</v-toolbar-title>
</v-toolbar>
<v-card-text class="d-flex align-center justify-center">
<v-img
src="/img/0.png"
contain
:height="$vuetify.breakpoint.mdAndUp?150:100"
:width="$vuetify.breakpoint.mdAndUp?150:100"
></v-img>
<v-form>
<v-container fluid>
<v-row>
<v-col cols="12">
<v-text-field
data-cy="username"
:label="$t('Login.username')"
prepend-icon="mdi-account-circle"
:rules="[rules.required]"
v-model="username"
ref="usernameTextField"
:hint="this.usernameAlert?`${$t('Login.usernameAlert')}`:''"
@keyup.enter="loginUser()"
/>
</v-col>
<v-col cols="12">
<v-text-field
data-cy="password"
:type="!showPassword?'password' :'text'"
:label="$t('Login.password')"
prepend-icon="mdi-lock"
@click:append="showPassword = !showPassword"
:append-icon="showPassword ? 'mdi-eye': 'mdi-eye-off'"
:hint="this.passwordAlert?$t('Login.passwordAlert'):$t('Login.passwordHint')"
:rules="[rules.required, rules.min]"
v-model="password"
ref="passwordTextField"
@keyup.enter="loginUser()"
/>
</v-col>
</v-row>
</v-container>
</v-form>
</v-card-text>
<v-card-actions class="flex-wrap">
<v-btn
style="width:100%"
color="rgb(94, 181, 177,.85)"
rounded
class="white--text mb-2"
@click="loginUser()"
:loading="loading"
:disabled="loading"
>
<v-icon left>mdi-login</v-icon>
<small>{{$t('Login.loginBtn')}}</small>
</v-btn>
<v-btn
text
rounded
color="green"
x-small
to="/changePassword"
>{{$t('Login.changePassword')}}</v-btn>
</v-card-actions>
</v-card>
</v-col>
</v-row>
<ul class="bubble-boxes">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<v-snackbar v-model="snackbar" :color="snackbarColor" :timeout="2000">{{ snackbarText }}</v-snackbar>
</v-container>
</v-content>
<app-footer></app-footer>
<!-- </div> -->
</v-app>
</template>
<script>
import AppFooter from "../components/AppFooter.vue";
import AuthHeader from "../components/AuthHeader.vue";
import { Meteor } from "meteor/meteor";
export default {
components: {
"app-footer": AppFooter,
"auth-header": AuthHeader
},
mounted() {
let self = this;
this.username = null;
this.password = null;
},
data() {
return {
loading: false,
snackbar: false,
snackbarColor: "red",
snackbarText: "",
showPassword: false,
username: null,
usernameAlert: false,
password: null,
passwordAlert: false,
rules: {
required: value => !!value || this.$t("Login.required"),
min: v => {
if (v == undefined) return true;
return v.length >= 8 || this.$t("Login.min8Character");
}
}
};
},
methods: {
loginUser() {
const that = this;
if (this.username == null || this.username.length == 0) {
this.$refs.usernameTextField.focus();
this.usernameAlert = true;
return;
}
if (this.password == null || this.password.length == 0) {
this.$refs.passwordTextField.focus();
this.passwordAlert = true;
return;
}
this.loading = true;
Meteor.loginWithPassword(this.username, this.password, function(
error,
result
) {
if (error) {
that.loading = false;
if (error.reason == "Incorrect password") {
that.snackbarText = that.$t("Login.errorIncorrectPassword");
that.snackbarColor = "red";
that.snackbar = true;
}
if (error.reason == "User not found") {
that.snackbarText = that.$t("Login.errorUserNotFound");
that.snackbarColor = "red";
that.snackbar = true;
}
} else {
Meteor.setTimeout(() => {
that.loading = false;
that.$router.push("/main/worklist");
}, 1000);
}
});
}
},
beforeRouteEnter(to, from, next) {
next(vm => {
// if (Meteor.userId()) {
// vm.$router.push("/main/worklist");
// }
});
}
};
</script>
<style scoped>
.backgroundImg {
background-image: -moz-linear-gradient(
141deg,
#9fb8ad 0%,
#1fc8db 51%,
#2ce8ceb0 75%
);
background-image: -webkit-linear-gradient(
141deg,
#9fb8ad 0%,
#1fc8db 51%,
#2ce8ceb0 75%
);
}
div.backgroundImg {
background-color: #abdae4ad !important;
}
img {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
overflow-y: hidden;
opacity: 0.6;
filter: grayscale(0.5) blur(2px);
z-index: 0;
}
.backgroundSheet {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
overflow-y: hidden;
z-index: 0;
}
.loginCard {
z-index: 1;
}
.backgroundImg {
overflow-y: hidden;
}
.roundedCard {
border-radius: 20px;
}
@import url("./css/bubbles.css");
/* loader */
@-moz-keyframes loader {
from {
transform: rotate(0);
}
to {
transform: rotate(360deg);
}
}
@-webkit-keyframes loader {
from {
transform: rotate(0);
}
to {
transform: rotate(360deg);
}
}
@-o-keyframes loader {
from {
transform: rotate(0);
}
to {
transform: rotate(360deg);
}
}
@keyframes loader {
from {
transform: rotate(0);
}
to {
transform: rotate(360deg);
}
}
</style>
\ No newline at end of file
<template>
<v-app id="inspire">
<template v-if="!$vuetify.rtl">
<v-app-bar app clipped-left color="teal lighten-3" dark>
<v-app-bar-nav-icon @click.stop="drawer = !drawer"></v-app-bar-nav-icon>
<v-toolbar-title class="red--text">Karname</v-toolbar-title>
<router-view name="register_patient"></router-view>
<v-spacer></v-spacer>
</v-app-bar>
<v-navigation-drawer v-model="drawer" app clipped>
<v-list nav dense>
<v-list-item-group v-model="item" color="primary">
<v-list-item v-for="(item, i) in updatedItems" :key="i" :to="item.url">
<!-- <v-list-item-icon>
<v-icon v-text="item.icon"></v-icon>
</v-list-item-icon>-->
<v-list-item-content>
<v-list-item-title v-text="item.text"></v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list-item-group>
</v-list>
</v-navigation-drawer>
</template>
<template v-if="$vuetify.rtl">
<v-app-bar app clipped-right color="teal lighten-3" dark>
<v-app-bar-nav-icon @click.stop="drawer = !drawer"></v-app-bar-nav-icon>
<v-toolbar-title class="red--text">Karname</v-toolbar-title>
<v-spacer></v-spacer>
</v-app-bar>
<v-navigation-drawer v-model="drawer" app clipped right>
<v-list nav dense>
<v-list-item-group v-model="item" color="primary">
<v-list-item v-for="(item, i) in updatedItems" :key="i" :to="item.url">
<!-- <v-list-item-icon>
<v-icon v-text="item.icon"></v-icon>
</v-list-item-icon>-->
<v-list-item-content>
<v-list-item-title v-text="item.text"></v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list-item-group>
</v-list>
</v-navigation-drawer>
</template>
<v-content>
<transition name="fade" mode="out-in">
<router-view></router-view>
</transition>
<!-- <transition name="fade" mode="out-in">
<keep-alive>
<router-view name="edit_worklist"></router-view>
</keep-alive>
</transition> -->
</v-content>
<app-footer></app-footer>
</v-app>
</template>
<script>
import { Fragment } from "vue-fragment";
import AppFooter from "../components/AppFooter.vue";
import { Meteor } from "meteor/meteor";
import RegisterPatient from "../components/RegisterPatient.vue";
export default {
components: {
"app-footer": AppFooter,
fragment: Fragment,
RegisterPatient
},
props: {
source: String
},
methods:{
},
computed: {
// getCurrentRoute(){
// debugger
// return this.$router.currentRoute.name == "worklist"
// },
updatedItems() {
if (
Meteor.userId() &&
this.users.length > 0 &&
Meteor.users.findOne({ _id: Meteor.userId() }).username == "marcoadmin"
) {
if (this.items.findIndex(item => item.text == "Users") < 0)
this.items.push({ text: "Users", url: "/main/users" });
}
return this.items;
}
},
data: () => ({
drawer: null,
drawerRight: null,
right: false,
left: false,
item: 0,
items: [
{ text: "Worklist", url: "/main/worklist", icon: "mdi-folder" },
{ text: "HISLink", url: "/main/hislink", icon: "mdi-account-multiple" },
{ text: "DeviceMap", url: "/main/devicemap", icon: "mdi-star" },
{ text: "Client", url: "/main/client" }
]
}),
meteor: {
$subscribe: {
users: []
},
users() {
return Meteor.users.find({});
}
}
};
</script>
<style scoped>
.fade-enter-active,
.fade-leave-active {
transition-duration: 0.3s;
transition-property: opacity;
transition-timing-function: ease;
}
.fade-enter,
.fade-leave-active {
opacity: 0;
}
</style>
\ No newline at end of file
<template>
<v-app id="inspire">
<auth-header btnToProp="signin" btnLabel="Register.loginBtn" btnIconName="mdi-login"></auth-header>
<v-content>
<v-container
style="background-color:rgb(94, 181, 177,.85)"
fluid
class="align-center fill-height backgroundImg"
>
<v-row justify="center" class="loginCard">
<v-col xs="8" sm="6" md="4" lg="3">
<v-card class="elevation-12 roundedCard" light elevation="24">
<v-toolbar color="rgb(94, 181, 177,.85)" dark>
<v-icon class="ma-3">mdi-account-plus</v-icon>
<v-toolbar-title>{{$t('Register.registerHeader')}}</v-toolbar-title>
</v-toolbar>
<v-card-text>
<v-form>
<v-container fluid>
<v-row>
<v-col cols="12">
<v-text-field
:label="$t('Register.username')"
prepend-icon="mdi-account-circle"
:rules="[rules.required]"
v-model="username"
ref="usernameTextField"
:hint="this.usernameAlert?`${$t('Register.usernameAlert')}`:''"
@keyup.enter="createAccount()"
/>
</v-col>
<v-col cols="12">
<v-text-field
:type="!showPassword1?'password' :'text'"
:label="$t('Register.password')"
prepend-icon="mdi-lock"
@click:append="showPassword1 = !showPassword1"
:append-icon="showPassword1 ? 'mdi-eye': 'mdi-eye-off'"
v-model="firstPass"
:rules="[rules.required, rules.min]"
ref="firstPassTextField"
:hint="this.firstPassAlert?`${$t('Register.firstPassAlert')}`:''"
@keyup.enter="createAccount()"
/>
</v-col>
<v-col cols="12">
<v-text-field
:type="!showPassword2?'password' :'text'"
:label="$t('Register.repeatPassword')"
prepend-icon="mdi-lock"
@click:append="showPassword2 = !showPassword2"
:append-icon="showPassword2 ? 'mdi-eye': 'mdi-eye-off'"
v-model="secondPass"
:rules="[rules.required, rules.matchPass]"
ref="secondPassTextField"
:hint="this.secondPassAlert?`${$t('Register.secondPassAlert')}`:''"
@keyup.enter="createAccount()"
/>
</v-col>
</v-row>
</v-container>
</v-form>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
style="width:100%"
class="white--text"
color="rgb(94, 181, 177,.85)"
rounded
@click="createAccount()"
:loading="loading"
:disabled="loading"
>
<v-icon left>mdi-login</v-icon>
<small>{{$t('Register.registerBtn')}}</small>
<template v-slot:loader>
<span>{{$t('Register.loadingText')}}</span>
</template>
</v-btn>
</v-card-actions>
</v-card>
</v-col>
</v-row>
<ul class="bubble-boxes">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<v-snackbar v-model="snackbar" :color="snackbarColor" :timeout="2000">{{ snackbarText }}</v-snackbar>
</v-container>
</v-content>
<app-footer></app-footer>
</v-app>
</template>
<script>
import AppFooter from "../components/AppFooter.vue";
import AuthHeader from "../components/AuthHeader.vue";
import { Accounts } from "meteor/accounts-base";
export default {
components: {
"app-footer": AppFooter,
"auth-header": AuthHeader
},
data() {
return {
snackbar: false,
snackbarText: "",
snackbarColor: "red",
loading: false,
username: null,
usernameAlert: false,
firstPass: null,
firstPassAlert: false,
secondPass: null,
secondPassAlert: false,
showPassword1: false,
showPassword2: false,
rules: {
required: value => !!value || this.$t("Register.required"),
min: v => {
if (v == undefined) return true;
return v.length >= 8 || this.$t("Register.min8Character");
},
matchPass: v => {
return (
this.firstPass === this.secondPass || this.$t("Register.matchPass")
);
}
}
};
},
methods: {
createAccount() {
const username = this.username;
const password = this.firstPass;
const that = this;
if (this.username == null || this.username.length == 0) {
this.$refs.usernameTextField.focus();
this.usernameAlert = true;
return;
}
if (this.firstPass == null || this.firstPass.length == 0) {
this.$refs.firstPassTextField.focus();
this.firstPassAlert = true;
return;
}
if (this.secondPass == null || this.secondPass.length == 0) {
this.$refs.secondPassTextField.focus();
this.secondPassAlert = true;
return;
}
if (this.firstPass != this.secondPass) {
return;
}
if (this.firstPass == this.secondPass && this.username != null) {
this.loading = true;
Accounts.createUser(
{
username: this.username,
password: this.firstPass
},
function(error, result) {
if (error) {
that.loading = false;
if (error.error == 403) {
that.snackbarColor = "red";
that.snackbarText = that.$t("Register.error403");
that.snackbar = true;
}
} else {
that.snackbarColor = "rgb(94, 181, 177,.85)";
that.snackbarText = that.$t("Register.userCreated");
that.snackbar = true;
Meteor.setTimeout(() => {
that.loading = false;
that.$router.push("/main/worklist");
}, 1000);
}
}
);
}
}
}
};
</script>
<style scoped>
.backgroundImg {
background-color: #abdae4ad;
background-image: linear-gradient(
141deg,
#9fb8ad 0%,
#1fc8db 51%,
#2ce8ceb0 75%
);
}
img {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
overflow-y: hidden;
opacity: 0.6;
filter: grayscale(0.5) blur(2px);
z-index: 0;
}
.loginCard {
z-index: 1;
}
.backgroundImg {
overflow-y: hidden;
}
.roundedCard {
border-radius: 20px;
}
/* loader */
@-moz-keyframes loader {
from {
transform: rotate(0);
}
to {
transform: rotate(360deg);
}
}
@-webkit-keyframes loader {
from {
transform: rotate(0);
}
to {
transform: rotate(360deg);
}
}
@-o-keyframes loader {
from {
transform: rotate(0);
}
to {
transform: rotate(360deg);
}
}
@keyframes loader {
from {
transform: rotate(0);
}
to {
transform: rotate(360deg);
}
}
</style>
\ No newline at end of file
/*Bubble Boxes Animation CSS*/
.bubble-boxes {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 40%;
}
.bubble-boxes li {
position: absolute;
list-style: none;
display: flex;
width: 20px;
height: 20px;
background: rgba(255, 255, 255, .2);
animation: animate 25s linear infinite;
bottom: -800px;
}
.bubble-boxes li:nth-child(1) {
left: 25%;
width: 80px;
height: 80px;
animation-delay: 0;
}
.bubble-boxes li:nth-child(2) {
left: 10%;
width: 20px;
height: 20px;
animation-delay: 2s;
animation-duration: 12s;
}
.bubble-boxes li:nth-child(3) {
left: 70%;
width: 20px;
height: 20px;
animation-delay: 4s;
}
.bubble-boxes li:nth-child(4) {
left: 40%;
width: 60px;
height: 60px;
animation-delay: 0s;
animation-duration: 18s;
}
.bubble-boxes li:nth-child(5) {
left: 65%;
width: 20px;
height: 20px;
animation-delay: 0s;
}
.bubble-boxes li:nth-child(6) {
left: 75%;
width: 110px;
height: 110px;
animation-delay: 3s;
}
.bubble-boxes li:nth-child(7) {
left: 35%;
width: 150px;
height: 150px;
animation-delay: 7s;
}
.bubble-boxes li:nth-child(8) {
left: 50%;
width: 25px;
height: 25px;
animation-delay: 15s;
animation-duration: 45s;
}
.bubble-boxes li:nth-child(9) {
left: 20%;
width: 15px;
height: 15px;
animation-delay: 2s;
animation-duration: 35s;
}
.bubble-boxes li:nth-child(10) {
left: 85%;
width: 150px;
height: 150px;
animation-delay: 0s;
animation-duration: 12s;
}
@keyframes animate {
0% {
transform: translateY(0) rotate(0deg);
opacity: 1;
border-radius: 0;
}
100% {
transform: translateY(-1000px) rotate(720deg);
opacity: 1;
border-radius: 50%;
}
}
\ No newline at end of file
html {
overflow-y: auto !important;
}
body {
overflow: hidden !important;
}
.application {
height: 100%;
}
main {
height: calc(100% - 56px - 36px);
}
.container {
height: 100%;
overflow: auto;
}
\ No newline at end of file
{
"baseUrl": "http://localhost:3000",
"defaultCommandTimeout": 10000
}
\ No newline at end of file
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}
\ No newline at end of file
/// <reference types="Cypress" />
describe('The Login Page', function() {
this.beforeEach(function() {
cy.visit('/signin');
});
it('login test', function() {
cy.get("[data-cy=username]").debug().type("reza.s");
cy.get("[data-cy=password]").type(`1{enter}`);
cy.url().should('include', '/main/worklist');
});
it("register page", function() {
cy.get("[data-cy=signup]").click();
cy.url().should('include', '/signup');
});
});
\ No newline at end of file
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************
// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
}
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add("login", (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import './commands'
// Alternatively you can use CommonJS syntax:
// require('./commands')
version: '3'
services:
app:
container_name: karname-app
restart: on-failure
build:
context: .
dockerfile: docker/linux/Dockerfile
image: 'karname/app:${TAG_VERSION}'
ports:
- '80:3000'
depends_on:
- mongo
links:
- mongo
environment:
ROOT_URL: ${APP_ROOT_URL:-http://localhost}
MONGO_URL: mongodb://mongo:27017/karname
PORT: 3000
METEOR_SETTINGS: '{"worklistUrl":"http://192.168.0.163"}'
mongo:
image: repo.marcopacs.com/kelishe/mongo:4.2.0
command:
- --storageEngine=wiredTiger
volumes:
- data:/data/db
volumes:
data:
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
FROM mcr.microsoft.com/windows/nanoserver:1809
RUN mkdir "C:\\node" && curl.exe -o "C:\\node\\node.zip" https://nodejs.org/dist/v12.9.1/node-v12.9.1-win-x64.zip && \
mkdir "C:\\Program Files\\node" && \
tar.exe -xf "C:\\node\\node.zip" -C "C:\\Program Files\\node" --strip-components=1
ENV PATH "C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C:\\Program Files\\node"
COPY "." "C:\\app"
CMD ["node.exe", "C:\\app\\main.js"]
\ No newline at end of file
import { Mongo } from 'meteor/mongo';
import { Meteor } from 'meteor/meteor';
let Brands;
if (Meteor.isClient || Meteor.isCordova) {
Brands = new Mongo.Collection('brands');
}
if (Meteor.isServer) {
Brands = new Mongo.Collection('brands', { connection: null });
}
export default Brands;
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
File added
File added
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment