Skip to content

Commit

Permalink
Merge pull request #59 from Poll-me/release/0.3.0
Browse files Browse the repository at this point in the history
Release 0.3.0
  • Loading branch information
mdo2 authored Sep 9, 2018
2 parents ba2d87f + ed4ff0d commit 576d136
Show file tree
Hide file tree
Showing 33 changed files with 910 additions and 144 deletions.
17 changes: 16 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,20 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

## [0.3.0] - 2018-09-09

### Added

- Add a clickable backdrop while showing the nav menu
- Add a progress bar component to display percentage data
- Create mixins and components for shared logic at creation poll components
- Add a Yes/No poll-type as a quick selection poll type
- Add a Selection poll type

### Fixed

- Parse the multiline polls descriptions correctly when sharing through WhatsApp

## [0.2.0] - 2018-06-07

### Added
Expand Down Expand Up @@ -57,6 +71,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- **Continuous deployment** (CD) using the **Netlify** service
- **PWA** app configuration for allow the users install the app on their devices

[Unreleased]: https://github.com/Poll-me/poll-me-vue/compare/v0.2.0...HEAD
[Unreleased]: https://github.com/Poll-me/poll-me-vue/compare/v0.3.0...HEAD
[0.3.0]: https://github.com/Poll-me/poll-me-vue/compare/v0.2.0...v0.3.0
[0.2.0]: https://github.com/Poll-me/poll-me-vue/compare/v0.1.0...v0.2.0
[0.1.0]: https://github.com/Poll-me/poll-me-vue/compare/v0.0.0...v0.1.0
31 changes: 31 additions & 0 deletions lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,15 @@
"submit-button": "Create"
}
},
"fill": {
"author-label": "Who are you?",
"author-placeholder": "The name to display",
"already-answered": "You are already answered!",
"get-out": "Remove vote",
"results": "Results",
"show-votes": "Show votes",
"hide-votes": "Hide votes"
},
"types": {
"1": {
"name": "Registration",
Expand All @@ -90,6 +99,28 @@
"get-in": "Hell yeah!",
"get-out": "Get out"
}
},
"2": {
"name": "Yes / No",
"description": "Ask the people for their opinion or participation in whatever.",
"yes": "Yes",
"no": "No"
},
"3": {
"name": "Selection",
"description": "List of two or more options from which people can choose.",
"choose": "Choose an option",
"options": {
"add": "Add option",
"title": "Options",
"placeholder": "Option #{number}",
"length-error": "Must add {min} options at least",
"label": {
"required-error": "The option must have a description",
"length-error": "The option must have from {min} to {max} characters",
"unique-error": "Option description must be unique"
}
}
}
},
"not-found": {
Expand Down
31 changes: 31 additions & 0 deletions lang/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,15 @@
"submit-button": "Crear"
}
},
"fill": {
"author-label": "Quién eres?",
"author-placeholder": "Nombre a mostrar",
"already-answered": "Ya has contestado!",
"get-out": "Quitar voto",
"results": "Resultados",
"show-votes": "Ver votos",
"hide-votes": "Ocultar votos"
},
"types": {
"1": {
"name": "Registro",
Expand All @@ -90,6 +99,28 @@
"get-in": "¡Dios si!",
"get-out": "Salir"
}
},
"2": {
"name": "Sí / No",
"description": "Pregunte a la gente por su opinión o participación en lo que sea.",
"yes": "",
"no": "No"
},
"3": {
"name": "Selección",
"description": "Lista de dos o más opciones de entre las cuales la gente elige una o más.",
"choose": "Elige una opción",
"options": {
"add": "Añadir opción",
"title": "Opciones",
"placeholder": "Opción #{number}",
"length-error": "Debe añadir al menos {min} opciones",
"label": {
"required-error": "La opción debe tener una descripción",
"length-error": "La opción debe tener de {min} a {max} caractéres",
"unique-error": "La descripción debe ser única"
}
}
}
},
"not-found": {
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "poll-me-vue",
"version": "0.2.0",
"version": "0.3.0",
"description": "The VueJS version of the PollMe web app",
"keywords": [
"vue",
Expand Down Expand Up @@ -105,7 +105,7 @@
"vue-style-loader": "^3.0.1",
"vue-switches": "^2.0.1",
"vue-template-compiler": "^2.5.2",
"vuelidate": "^0.6.2",
"vuelidate": "^0.7.3",
"webpack": "^3.6.0",
"webpack-bundle-analyzer": "^2.9.0",
"webpack-dev-server": "^2.9.1",
Expand Down
2 changes: 1 addition & 1 deletion src/assets/css/components/button.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

&[disabled] {
@apply .opacity-75;
@apply .cursor-not-allowed .pointer-events-none;
@apply .cursor-not-allowed;
}

&.outline {
Expand Down
1 change: 1 addition & 0 deletions src/assets/css/components/nav-list.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
@apply .text-lg;
@apply .text-white;

&.partial-match.router-link-active,
&.router-link-exact-active {
@apply .bg-primary;
@apply .rounded;
Expand Down
1 change: 1 addition & 0 deletions src/assets/css/utilities/animations/_animations.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
@import './bounce.css';
@import './fade.css';
@import './modal-dialog.css';
@import './slide-down.css';
17 changes: 17 additions & 0 deletions src/assets/css/utilities/animations/fade.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.fade-enter-active, .fade-leave-active {
transition-property: opacity;
}

.fade-enter-active {
transition-duration: .3s;
transition-timing-function: ease-out;
}

.fade-leave-active {
transition-duration: .15s;
transition-timing-function: ease-in;
}

.fade-enter, .fade-leave-to {
opacity: 0;
}
49 changes: 49 additions & 0 deletions src/components/ProgressBar.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<template>
<div class="rounded-lg overflow-hidden"
:class="bordered ? `border-2 border-${color}` : ''">
<div class="bar-fill-bg text-white h-8 flex items-center"
:class="`bg-${color}${!bordered ? ' rounded-lg' : ''}`"
:style="{ width: `${roundedValue}%` }" >
<div class="text-center truncate px-2 flex-1">{{ visibleValue }}</div>
</div>
</div>
</template>
<script>
import Vue from 'vue';
import Component from 'vue-class-component';
@Component({
props: {
value: {
type: Number,
required: true,
validator(val) { return val >= 0 && val <= 100; }
},
color: {
type: String,
default: 'primary'
},
bordered: {
type: Boolean,
default: true
}
}
})
export default class ProgressBar extends Vue {
maxVisibleValue = 20;
get roundedValue() {
const limitedValue = Math.min(Math.max(this.value, 0), 100);
return Math.round(limitedValue);
}
get visibleValue() {
return this.roundedValue >= this.maxVisibleValue ? `${this.roundedValue} %` : '';
}
}
</script>
<style scoped>
.bar-fill-bg {
transition: width .3s;
}
</style>
5 changes: 3 additions & 2 deletions src/components/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import FileUploader from './FileUploader';
import UserAvatar from './UserAvatar';
import ModalDialog from './ModalDialog';
import ProgressBar from './ProgressBar';
import UserAvatar from './UserAvatar';

export default { FileUploader, UserAvatar, ModalDialog };
export default { FileUploader, ModalDialog, ProgressBar, UserAvatar };
4 changes: 4 additions & 0 deletions src/core/MainHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
<transition name="slide-down">
<NavMenu v-if="navMenuOpen" @logout="navMenuOpen = false"></NavMenu>
</transition>
<transition name="fade">
<div v-if="navMenuOpen" class="fixed pin bg-black opacity-50"
@click="navMenuOpen = false"></div>
</transition>
</div>
</template>

Expand Down
3 changes: 2 additions & 1 deletion src/core/NavMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
</router-link>
</li>
<li>
<router-link :to="{ name: 'new-poll' }" v-t="'header.nav-menu.new-link'">
<router-link class="partial-match" v-t="'header.nav-menu.new-link'"
:to="{ name: 'new-poll' }">
</router-link>
</li>
<template v-if="isLogged">
Expand Down
75 changes: 55 additions & 20 deletions src/polls/create/CreatePoll.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,43 @@
<div class="bg-primary text-white py-4">
<div class="container">
<h1 class="text-lg font-medium text-center" v-t="'polls.new.title'"></h1>
<select v-show="!type.id" v-model="type"
id="poll-type"
class="mt-4">
<option disabled :value="{}" v-t="'polls.new.type-placeholder'"></option>
<option v-for="pollType in typesList" :key="pollType.id" :value="pollType"
<select v-show="!typeId" id="type-selector" class="mt-4"
:value="typeIdNumber"
@change="typeChanged" >
<option disabled :value="0" v-t="'polls.new.type-placeholder'"></option>
<option v-for="pollType in typesList" :key="pollType.id" :value="pollType.id"
v-t="`polls.types.${pollType.id}.name`" ></option>
</select>
</div>
</div>
<div class="flex-1 flex flex-col">
<template v-if="type.id">
<template v-if="typeExists">
<div class="bg-tertiary text-white" >
<div class="container py-4">
<div class="flex mb-2 items-center">
<div class="flex-1 font-medium" v-t="`polls.types.${type.id}.name`"></div>
<font-awesome-icon icon="undo" size="sm" class="cursor-pointer"
@click="resetType"></font-awesome-icon>
<div class="flex-1 font-medium" v-t="`polls.types.${typeId}.name`"></div>
<router-link :to="{ name: 'new-poll' }" class="text-white">
<font-awesome-icon icon="undo" size="sm" class="cursor-pointer">
</font-awesome-icon>
</router-link>
</div>
<small class="italic" v-t="`polls.types.${type.id}.description`"></small>
<small class="italic" v-t="`polls.types.${typeId}.description`"></small>
</div>
</div>
<NewPollForm :is-logged="user.isLogged"
:type="type.id" @submit="submit"></NewPollForm>
<component
:is="newPollComponent"
:type="typeIdNumber"
:is-logged="user.isLogged"
@submit="submit" >
<button type="submit" class="sticky pin-b py-4 btn btn-secondary rounded-none"
slot="submit" slot-scope="submitScope"
:disabled="submitScope.invalid" >
<div class="text-center text-xl">
<span v-t="'polls.new.form.submit-button'"></span>
<font-awesome-icon :icon="['far', 'file-alt']" class="ml-1" ></font-awesome-icon>
</div>
</button>
</component>
</template>
<div v-else class="container flex-1 flex items-center text-center" >
<div class="flex-1">
Expand All @@ -41,24 +55,45 @@ import Vue from 'vue';
import Component from 'vue-class-component';
import { mapState as mapRootState, createNamespacedHelpers } from 'vuex';
import NewPollForm from './components';
import newPollComponentsMap from './components';
const { mapGetters, mapActions } = createNamespacedHelpers('polls');
const { mapState, mapGetters, mapActions } = createNamespacedHelpers('polls');
@Component({
components: { NewPollForm },
computed: { ...mapGetters(['typesList']), ...mapRootState(['user']) },
props: {
typeId: {
type: String
}
},
computed: { ...mapState(['types']), ...mapGetters(['typesList']), ...mapRootState(['user']) },
methods: mapActions(['createPoll'])
})
export default class CreatePoll extends Vue {
type = {};
get typeIdNumber() {
return parseInt(this.typeId || 0, 10);
}
get typeExists() {
return this.typeId && this.types[this.typeId];
}
get newPollComponent() {
return this.typeExists ? newPollComponentsMap(this.typeIdNumber) : {};
}
created() {
if (this.typeId && !this.types[this.typeId]) {
this.$router.replace({ name: 'not-found' });
}
}
resetType() {
this.type = {};
typeChanged(ev) {
const typeId = ev.target.value;
this.$router.push({ name: 'new-poll', params: { typeId } });
}
submit(data) {
const pollData = { ...data, type: this.type.id };
const pollData = { ...data, type: this.typeIdNumber };
this.createPoll(pollData)
.then(key => this.$router.push({ name: 'fill-poll', params: { key } }));
}
Expand Down
21 changes: 21 additions & 0 deletions src/polls/create/components/NewBasicPollForm.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<template>
<form class="flex-1 flex flex-col" @submit.prevent="submit">
<div class="flex-1 container py-4">
<NewPollFormBase
:isLogged="isLogged"
:name.sync="name"
:author.sync="author"
:hasDescription.sync="hasDescription"
:description.sync="description"></NewPollFormBase>
</div>
<slot name="submit" :invalid="$v.$invalid"></slot>
</form>
</template>
<script>
import Component from 'vue-class-component';
import NewPollFormMixin from '../new-poll-form-mixin';
@Component()
export default class NewBasicPollForm extends NewPollFormMixin {}
</script>
Loading

0 comments on commit 576d136

Please sign in to comment.