Move buttons to separate component (#380)
Co-authored-by: kolaente <k@knt.li> Reviewed-on: https://kolaente.dev/vikunja/frontend/pulls/380 Co-authored-by: konrad <konrad@kola-entertainments.de> Co-committed-by: konrad <konrad@kola-entertainments.de>
This commit is contained in:
@ -3,13 +3,13 @@
|
||||
<h2>Hi {{ userInfo.name !== '' ? userInfo.name : userInfo.username }}!</h2>
|
||||
<template v-if="!hasTasks">
|
||||
<p>Click on a list or namespace on the left to get started.</p>
|
||||
<router-link
|
||||
<x-button
|
||||
:to="{name: 'migrate.start'}"
|
||||
class="button is-primary has-no-shadow"
|
||||
:shadow="false"
|
||||
v-if="migratorsEnabled"
|
||||
>
|
||||
Import your data into Vikunja
|
||||
</router-link>
|
||||
</x-button>
|
||||
</template>
|
||||
<ShowTasks :show-all="true"/>
|
||||
</div>
|
||||
|
@ -2,64 +2,60 @@
|
||||
<div class="modal-mask keyboard-shortcuts-modal">
|
||||
<div @click.self="$router.back()" class="modal-container">
|
||||
<div class="modal-content">
|
||||
<div class="card has-background-white has-no-shadow">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">Create A Saved Filter</p>
|
||||
</header>
|
||||
<div class="card-content content">
|
||||
<p>
|
||||
A saved filter is a virtual list which is computed from a set of filters each time it is
|
||||
accessed. Once created, it will appear in a special namespace.
|
||||
</p>
|
||||
<div class="field">
|
||||
<label class="label" for="title">Title</label>
|
||||
<div class="control">
|
||||
<input
|
||||
v-model="savedFilter.title"
|
||||
:class="{ 'disabled': savedFilterService.loading}"
|
||||
:disabled="savedFilterService.loading"
|
||||
class="input"
|
||||
id="Title"
|
||||
placeholder="The saved filter title goes here..."
|
||||
type="text"
|
||||
v-focus
|
||||
/>
|
||||
</div>
|
||||
<card class="has-background-white has-no-shadow" title="Create A Saved Filter">
|
||||
<p>
|
||||
A saved filter is a virtual list which is computed from a set of filters each time it is
|
||||
accessed. Once created, it will appear in a special namespace.
|
||||
</p>
|
||||
<div class="field">
|
||||
<label class="label" for="title">Title</label>
|
||||
<div class="control">
|
||||
<input
|
||||
v-model="savedFilter.title"
|
||||
:class="{ 'disabled': savedFilterService.loading}"
|
||||
:disabled="savedFilterService.loading"
|
||||
class="input"
|
||||
id="Title"
|
||||
placeholder="The saved filter title goes here..."
|
||||
type="text"
|
||||
v-focus
|
||||
/>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="description">Description</label>
|
||||
<div class="control">
|
||||
<editor
|
||||
v-model="savedFilter.description"
|
||||
:class="{ 'disabled': savedFilterService.loading}"
|
||||
:disabled="savedFilterService.loading"
|
||||
:preview-is-default="false"
|
||||
id="description"
|
||||
placeholder="The description goes here..."
|
||||
v-if="editorActive"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="filters">Filters</label>
|
||||
<div class="control">
|
||||
<filters
|
||||
:class="{ 'disabled': savedFilterService.loading}"
|
||||
:disabled="savedFilterService.loading"
|
||||
class="has-no-shadow has-no-border"
|
||||
v-model="filters"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
:class="{ 'disabled': savedFilterService.loading}"
|
||||
:disabled="savedFilterService.loading"
|
||||
@click="create()"
|
||||
class="button is-primary is-fullwidth">
|
||||
Create new saved filter
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="description">Description</label>
|
||||
<div class="control">
|
||||
<editor
|
||||
v-model="savedFilter.description"
|
||||
:class="{ 'disabled': savedFilterService.loading}"
|
||||
:disabled="savedFilterService.loading"
|
||||
:preview-is-default="false"
|
||||
id="description"
|
||||
placeholder="The description goes here..."
|
||||
v-if="editorActive"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="filters">Filters</label>
|
||||
<div class="control">
|
||||
<filters
|
||||
:class="{ 'disabled': savedFilterService.loading}"
|
||||
:disabled="savedFilterService.loading"
|
||||
class="has-no-shadow has-no-border"
|
||||
v-model="filters"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<x-button
|
||||
:loading="savedFilterService.loading"
|
||||
:disabled="savedFilterService.loading"
|
||||
@click="create()"
|
||||
class="is-fullwidth"
|
||||
>
|
||||
Create new saved filter
|
||||
</x-button>
|
||||
</card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,78 +1,67 @@
|
||||
<template>
|
||||
<div :class="{ 'is-loading': filterService.loading}" class="loader-container edit-list is-max-width-desktop">
|
||||
<div class="card">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">
|
||||
Edit Saved Filter
|
||||
</p>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<div class="content">
|
||||
<form @submit.prevent="save()">
|
||||
<div class="field">
|
||||
<label class="label" for="listtext">Filter Name</label>
|
||||
<div class="control">
|
||||
<input
|
||||
:class="{ 'disabled': filterService.loading}"
|
||||
:disabled="filterService.loading"
|
||||
@keyup.enter="save"
|
||||
class="input"
|
||||
id="listtext"
|
||||
placeholder="The list title goes here..."
|
||||
type="text"
|
||||
v-focus
|
||||
v-model="filter.title"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="listdescription">Description</label>
|
||||
<div class="control">
|
||||
<editor
|
||||
:class="{ 'disabled': filterService.loading}"
|
||||
:disabled="filterService.loading"
|
||||
:preview-is-default="false"
|
||||
id="listdescription"
|
||||
placeholder="The lists description goes here..."
|
||||
v-model="filter.description"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="filters">Filters</label>
|
||||
<div class="control">
|
||||
<filters
|
||||
:class="{ 'disabled': filterService.loading}"
|
||||
:disabled="filterService.loading"
|
||||
class="has-no-shadow has-no-border"
|
||||
v-model="filters"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="field has-addons mt-4">
|
||||
<div class="control is-fullwidth">
|
||||
<button
|
||||
@click="save()"
|
||||
:class="{ 'is-loading': filterService.loading}"
|
||||
class="button is-primary is-fullwidth">
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
<div class="control">
|
||||
<button
|
||||
@click="showDeleteModal = true"
|
||||
:class="{ 'is-loading': filterService.loading}"
|
||||
class="button is-danger">
|
||||
<span class="icon">
|
||||
<icon icon="trash-alt"/>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<card title="Edit Saved Filter">
|
||||
<form @submit.prevent="save()">
|
||||
<div class="field">
|
||||
<label class="label" for="listtext">Filter Name</label>
|
||||
<div class="control">
|
||||
<input
|
||||
:class="{ 'disabled': filterService.loading}"
|
||||
:disabled="filterService.loading"
|
||||
@keyup.enter="save"
|
||||
class="input"
|
||||
id="listtext"
|
||||
placeholder="The list title goes here..."
|
||||
type="text"
|
||||
v-focus
|
||||
v-model="filter.title"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="listdescription">Description</label>
|
||||
<div class="control">
|
||||
<editor
|
||||
:class="{ 'disabled': filterService.loading}"
|
||||
:disabled="filterService.loading"
|
||||
:preview-is-default="false"
|
||||
id="listdescription"
|
||||
placeholder="The lists description goes here..."
|
||||
v-model="filter.description"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="filters">Filters</label>
|
||||
<div class="control">
|
||||
<filters
|
||||
:class="{ 'disabled': filterService.loading}"
|
||||
:disabled="filterService.loading"
|
||||
class="has-no-shadow has-no-border"
|
||||
v-model="filters"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="field has-addons mt-4">
|
||||
<div class="control is-fullwidth">
|
||||
<x-button
|
||||
@click="save()"
|
||||
:loading="filterService.loading"
|
||||
class="is-fullwidth">
|
||||
Save
|
||||
</x-button>
|
||||
</div>
|
||||
<div class="control">
|
||||
<x-button
|
||||
@click="showDeleteModal = true"
|
||||
:loading="filterService.loading"
|
||||
class="is-danger"
|
||||
icon="trash-alt"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</card>
|
||||
|
||||
<modal
|
||||
@close="showDeleteModal = false"
|
||||
|
@ -1,17 +1,23 @@
|
||||
<template>
|
||||
<div :class="{ 'is-loading': labelService.loading}" class="loader-container content">
|
||||
<router-link :to="{name:'labels.create'}" class="button is-primary button-right">
|
||||
<span class="icon is-small">
|
||||
<icon icon="plus"/>
|
||||
</span>
|
||||
<div :class="{ 'is-loading': labelService.loading}" class="loader-container">
|
||||
<x-button
|
||||
:to="{name:'labels.create'}"
|
||||
class="is-pulled-right"
|
||||
icon="plus"
|
||||
>
|
||||
New label
|
||||
</router-link>
|
||||
<h1>Manage labels</h1>
|
||||
<p>
|
||||
Click on a label to edit it.
|
||||
You can edit all labels you created, you can use all labels which are associated with a task to whose list
|
||||
you have access.
|
||||
</p>
|
||||
</x-button>
|
||||
|
||||
<div class="content">
|
||||
<h1>Manage labels</h1>
|
||||
<p>
|
||||
Click on a label to edit it.
|
||||
You can edit all labels you created, you can use all labels which are associated with a task to whose
|
||||
list
|
||||
you have access.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="columns">
|
||||
<div class="labels-list column">
|
||||
<span
|
||||
@ -35,66 +41,55 @@
|
||||
</span>
|
||||
</div>
|
||||
<div class="column is-4" v-if="isLabelEdit">
|
||||
<div class="card">
|
||||
<header class="card-header">
|
||||
<span class="card-header-title">
|
||||
Edit Label
|
||||
</span>
|
||||
<a @click="isLabelEdit = false" class="card-header-icon">
|
||||
<span class="icon">
|
||||
<icon icon="times"/>
|
||||
</span>
|
||||
</a>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<form @submit.prevent="editLabelSubmit()">
|
||||
<div class="field">
|
||||
<label class="label">Title</label>
|
||||
<div class="control">
|
||||
<input
|
||||
class="input"
|
||||
placeholder="Label title"
|
||||
type="text"
|
||||
v-model="labelEditLabel.title"/>
|
||||
</div>
|
||||
<card title="Edit Label" :has-close="true" @close="() => isLabelEdit = false">
|
||||
<form @submit.prevent="editLabelSubmit()">
|
||||
<div class="field">
|
||||
<label class="label">Title</label>
|
||||
<div class="control">
|
||||
<input
|
||||
class="input"
|
||||
placeholder="Label title"
|
||||
type="text"
|
||||
v-model="labelEditLabel.title"/>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">Description</label>
|
||||
<div class="control">
|
||||
<editor
|
||||
:preview-is-default="false"
|
||||
placeholder="Label description"
|
||||
v-if="editorActive"
|
||||
v-model="labelEditLabel.description"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">Description</label>
|
||||
<div class="control">
|
||||
<editor
|
||||
:preview-is-default="false"
|
||||
placeholder="Label description"
|
||||
v-if="editorActive"
|
||||
v-model="labelEditLabel.description"
|
||||
/>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">Color</label>
|
||||
<div class="control">
|
||||
<color-picker v-model="labelEditLabel.hexColor"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">Color</label>
|
||||
<div class="control">
|
||||
<color-picker v-model="labelEditLabel.hexColor"/>
|
||||
</div>
|
||||
<div class="field has-addons">
|
||||
<div class="control is-expanded">
|
||||
<button :class="{ 'is-loading': labelService.loading}" class="button is-fullwidth is-primary"
|
||||
type="submit">
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
<div class="control">
|
||||
<a
|
||||
@click="() => {deleteLabel(labelEditLabel);isLabelEdit = false}"
|
||||
class="button has-icon is-danger">
|
||||
<span class="icon">
|
||||
<icon icon="trash-alt"/>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field has-addons">
|
||||
<div class="control is-expanded">
|
||||
<x-button
|
||||
:loading="labelService.loading"
|
||||
class="is-fullwidth"
|
||||
@click="editLabelSubmit()"
|
||||
>
|
||||
Save
|
||||
</x-button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control">
|
||||
<x-button
|
||||
@click="() => {deleteLabel(labelEditLabel);isLabelEdit = false}"
|
||||
icon="trash-alt"
|
||||
class="is-danger"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -15,12 +15,13 @@
|
||||
v-model="label.title"/>
|
||||
</p>
|
||||
<p class="control">
|
||||
<button class="button is-primary has-no-shadow" type="submit">
|
||||
<span class="icon is-small">
|
||||
<icon icon="plus"/>
|
||||
</span>
|
||||
<x-button
|
||||
:shadow="false"
|
||||
icon="plus"
|
||||
@click="newlabel"
|
||||
>
|
||||
Add
|
||||
</button>
|
||||
</x-button>
|
||||
</p>
|
||||
</div>
|
||||
<p class="help is-danger" v-if="showError && label.title === ''">
|
||||
|
@ -4,132 +4,112 @@
|
||||
This list is archived.
|
||||
It is not possible to create new or edit tasks or it.
|
||||
</div>
|
||||
<div class="card">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">
|
||||
Edit List
|
||||
</p>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<div class="content">
|
||||
<form @submit.prevent="submit()">
|
||||
<div class="field">
|
||||
<label class="label" for="listtext">List Name</label>
|
||||
<div class="control">
|
||||
<input
|
||||
:class="{ 'disabled': listService.loading}"
|
||||
:disabled="listService.loading"
|
||||
@keyup.enter="submit"
|
||||
class="input"
|
||||
id="listtext"
|
||||
placeholder="The list title goes here..."
|
||||
type="text"
|
||||
v-focus
|
||||
v-model="list.title"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label
|
||||
class="label"
|
||||
for="listtext"
|
||||
v-tooltip="'The list identifier can be used to uniquely identify a task across lists. You can set it to empty to disable it.'">
|
||||
List Identifier
|
||||
</label>
|
||||
<div class="control">
|
||||
<input
|
||||
:class="{ 'disabled': listService.loading}"
|
||||
:disabled="listService.loading"
|
||||
@keyup.enter="submit"
|
||||
class="input"
|
||||
id="listtext"
|
||||
placeholder="The list identifier goes here..."
|
||||
type="text"
|
||||
v-focus
|
||||
v-model="list.identifier"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="listdescription">Description</label>
|
||||
<div class="control">
|
||||
<editor
|
||||
:class="{ 'disabled': listService.loading}"
|
||||
:disabled="listService.loading"
|
||||
:preview-is-default="false"
|
||||
id="listdescription"
|
||||
placeholder="The lists description goes here..."
|
||||
v-model="list.description"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="isArchivedCheck">Is Archived</label>
|
||||
<div class="control">
|
||||
<fancycheckbox
|
||||
v-model="list.isArchived"
|
||||
v-tooltip="'If a list is archived, you cannot create new tasks or edit the list or existing tasks.'">
|
||||
This list is archived
|
||||
</fancycheckbox>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">Color</label>
|
||||
<div class="control">
|
||||
<color-picker v-model="list.hexColor"/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="field has-addons mt-4">
|
||||
<div class="control is-fullwidth">
|
||||
<button
|
||||
@click="submit()"
|
||||
:class="{ 'is-loading': listService.loading}"
|
||||
class="button is-primary is-fullwidth">
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
<div class="control">
|
||||
<button
|
||||
@click="showDeleteModal = true"
|
||||
:class="{ 'is-loading': listService.loading}"
|
||||
class="button is-danger">
|
||||
<span class="icon">
|
||||
<icon icon="trash-alt"/>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<card title="Edit List">
|
||||
<form @submit.prevent="submit()">
|
||||
<div class="field">
|
||||
<label class="label" for="listtext">List Name</label>
|
||||
<div class="control">
|
||||
<input
|
||||
:class="{ 'disabled': listService.loading}"
|
||||
:disabled="listService.loading"
|
||||
@keyup.enter="submit"
|
||||
class="input"
|
||||
id="listtext"
|
||||
placeholder="The list title goes here..."
|
||||
type="text"
|
||||
v-focus
|
||||
v-model="list.title"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card has-overflow">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">
|
||||
Duplicate this list
|
||||
</p>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<div class="content">
|
||||
<p>Select a namespace which should hold the duplicated list:</p>
|
||||
|
||||
<div class="field has-addons">
|
||||
<div class="control is-expanded">
|
||||
<namespace-search @selected="selectNamespace"/>
|
||||
</div>
|
||||
<div class="control">
|
||||
<button
|
||||
:class="{'is-loading': listDuplicateService.loading}"
|
||||
@click="duplicateList"
|
||||
class="button is-primary"
|
||||
type="submit">
|
||||
Duplicate
|
||||
</button>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label
|
||||
class="label"
|
||||
for="listtext"
|
||||
v-tooltip="'The list identifier can be used to uniquely identify a task across lists. You can set it to empty to disable it.'">
|
||||
List Identifier
|
||||
</label>
|
||||
<div class="control">
|
||||
<input
|
||||
:class="{ 'disabled': listService.loading}"
|
||||
:disabled="listService.loading"
|
||||
@keyup.enter="submit"
|
||||
class="input"
|
||||
id="listtext"
|
||||
placeholder="The list identifier goes here..."
|
||||
type="text"
|
||||
v-focus
|
||||
v-model="list.identifier"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="listdescription">Description</label>
|
||||
<div class="control">
|
||||
<editor
|
||||
:class="{ 'disabled': listService.loading}"
|
||||
:disabled="listService.loading"
|
||||
:preview-is-default="false"
|
||||
id="listdescription"
|
||||
placeholder="The lists description goes here..."
|
||||
v-model="list.description"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="isArchivedCheck">Is Archived</label>
|
||||
<div class="control">
|
||||
<fancycheckbox
|
||||
v-model="list.isArchived"
|
||||
v-tooltip="'If a list is archived, you cannot create new tasks or edit the list or existing tasks.'">
|
||||
This list is archived
|
||||
</fancycheckbox>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">Color</label>
|
||||
<div class="control">
|
||||
<color-picker v-model="list.hexColor"/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="field has-addons mt-4">
|
||||
<div class="control is-fullwidth">
|
||||
<x-button
|
||||
@click="submit()"
|
||||
:loading="listService.loading"
|
||||
class="is-fullwidth">
|
||||
Save
|
||||
</x-button>
|
||||
</div>
|
||||
<div class="control">
|
||||
<x-button
|
||||
@click="showDeleteModal = true"
|
||||
:locading="listService.loading"
|
||||
icon="trash-alt"
|
||||
class="is-danger"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</card>
|
||||
|
||||
<!-- Duplicate list -->
|
||||
<card class="has-overflow" title="Duplicate this list">
|
||||
<p>Select a namespace which should hold the duplicated list:</p>
|
||||
|
||||
<div class="field has-addons">
|
||||
<div class="control is-expanded">
|
||||
<namespace-search @selected="selectNamespace"/>
|
||||
</div>
|
||||
<div class="control">
|
||||
<x-button
|
||||
:loading="listDuplicateService.loading"
|
||||
@click="duplicateList"
|
||||
>
|
||||
Duplicate
|
||||
</x-button>
|
||||
</div>
|
||||
</div>
|
||||
</card>
|
||||
|
||||
<background :list-id="$route.params.id"/>
|
||||
|
||||
|
@ -18,12 +18,14 @@
|
||||
v-model="list.title"/>
|
||||
</p>
|
||||
<p class="control">
|
||||
<button :disabled="list.title === ''" @click="newList()" class="button is-primary has-no-shadow">
|
||||
<span class="icon is-small">
|
||||
<icon icon="plus"/>
|
||||
</span>
|
||||
<x-button
|
||||
:disabled="list.title === ''"
|
||||
@click="newList()"
|
||||
icon="plus"
|
||||
:shadow="false"
|
||||
>
|
||||
Add
|
||||
</button>
|
||||
</x-button>
|
||||
</p>
|
||||
</div>
|
||||
<p class="help is-danger" v-if="showError && list.title === ''">
|
||||
|
@ -2,12 +2,13 @@
|
||||
<div class="kanban-view">
|
||||
<div class="filter-container" v-if="list.isSavedFilter && !list.isSavedFilter()">
|
||||
<div class="items">
|
||||
<button @click.prevent.stop="showFilters = !showFilters" class="button">
|
||||
<span class="icon is-small">
|
||||
<icon icon="filter"/>
|
||||
</span>
|
||||
<x-button
|
||||
@click.prevent.stop="showFilters = !showFilters"
|
||||
icon="filter"
|
||||
type="secondary"
|
||||
>
|
||||
Filters
|
||||
</button>
|
||||
</x-button>
|
||||
</div>
|
||||
<filter-popup
|
||||
@change="() => {filtersChanged = true; loadBuckets()}"
|
||||
@ -59,11 +60,10 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="control">
|
||||
<a class="button is-primary has-no-shadow">
|
||||
<span class="icon">
|
||||
<icon :icon="['far', 'save']"/>
|
||||
</span>
|
||||
</a>
|
||||
<x-button
|
||||
:icon="['far', 'save']"
|
||||
:shadow="false"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<template v-else>
|
||||
@ -191,20 +191,21 @@
|
||||
Please specify a title.
|
||||
</p>
|
||||
</div>
|
||||
<a
|
||||
<x-button
|
||||
@click="toggleShowNewTaskInput(bucket.id)"
|
||||
class="button has-no-shadow is-transparent is-fullwidth has-text-centered"
|
||||
v-if="!showNewTaskInput[bucket.id]">
|
||||
<span class="icon is-small">
|
||||
<icon icon="plus"/>
|
||||
</span>
|
||||
<span v-if="bucket.tasks.length === 0">
|
||||
Add a task
|
||||
</span>
|
||||
<span v-else>
|
||||
Add another task
|
||||
</span>
|
||||
</a>
|
||||
class="is-transparent is-fullwidth has-text-centered"
|
||||
:shadow="false"
|
||||
v-if="!showNewTaskInput[bucket.id]"
|
||||
icon="plus"
|
||||
type="secondary"
|
||||
>
|
||||
<template v-if="bucket.tasks.length === 0">
|
||||
Add a task
|
||||
</template>
|
||||
<template v-else>
|
||||
Add another task
|
||||
</template>
|
||||
</x-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -222,16 +223,16 @@
|
||||
v-if="showNewBucketInput"
|
||||
v-model="newBucketTitle"
|
||||
/>
|
||||
<a
|
||||
<x-button
|
||||
@click="() => showNewBucketInput = true"
|
||||
class="button has-no-shadow is-transparent is-fullwidth has-text-centered" v-if="!showNewBucketInput">
|
||||
<span class="icon is-small">
|
||||
<icon icon="plus"/>
|
||||
</span>
|
||||
<span>
|
||||
Create a new bucket
|
||||
</span>
|
||||
</a>
|
||||
:shadow="false"
|
||||
class="is-transparent is-fullwidth has-text-centered"
|
||||
v-if="!showNewBucketInput"
|
||||
type="secondary"
|
||||
icon="plus"
|
||||
>
|
||||
Create a new bucket
|
||||
</x-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -269,7 +270,7 @@ import {applyDrag} from '@/helpers/applyDrag'
|
||||
import {mapState} from 'vuex'
|
||||
import {saveListView} from '@/helpers/saveListView'
|
||||
import Rights from '../../../models/rights.json'
|
||||
import { LOADING, LOADING_MODULE } from '../../../store/mutation-types'
|
||||
import {LOADING, LOADING_MODULE} from '../../../store/mutation-types'
|
||||
import FilterPopup from '@/components/list/partials/filter-popup'
|
||||
|
||||
export default {
|
||||
|
@ -1,5 +1,7 @@
|
||||
<template>
|
||||
<div :class="{ 'is-loading': taskCollectionService.loading}" class="loader-container is-max-width-desktop list-view">
|
||||
<div
|
||||
:class="{ 'is-loading': taskCollectionService.loading}"
|
||||
class="loader-container is-max-width-desktop list-view">
|
||||
<div class="filter-container" v-if="list.isSavedFilter && !list.isSavedFilter()">
|
||||
<div class="items">
|
||||
<div class="search">
|
||||
@ -18,26 +20,29 @@
|
||||
</span>
|
||||
</div>
|
||||
<div class="control">
|
||||
<button
|
||||
:class="{'is-loading': taskCollectionService.loading}"
|
||||
<x-button
|
||||
:loading="taskCollectionService.loading"
|
||||
@click="searchTasks"
|
||||
class="button has-no-shadow is-primary">
|
||||
:shadow="false"
|
||||
>
|
||||
Search
|
||||
</button>
|
||||
</x-button>
|
||||
</div>
|
||||
</div>
|
||||
<button @click="showTaskSearch = !showTaskSearch" class="button" v-if="!showTaskSearch">
|
||||
<span class="icon">
|
||||
<icon icon="search"/>
|
||||
</span>
|
||||
</button>
|
||||
<x-button
|
||||
@click="showTaskSearch = !showTaskSearch"
|
||||
icon="search"
|
||||
type="secondary"
|
||||
v-if="!showTaskSearch"
|
||||
/>
|
||||
</div>
|
||||
<button @click.prevent.stop="showTaskFilter = !showTaskFilter" class="button">
|
||||
<span class="icon is-small">
|
||||
<icon icon="filter"/>
|
||||
</span>
|
||||
<x-button
|
||||
@click.prevent.stop="showTaskFilter = !showTaskFilter"
|
||||
type="secondary"
|
||||
icon="filter"
|
||||
>
|
||||
Filters
|
||||
</button>
|
||||
</x-button>
|
||||
</div>
|
||||
<filter-popup
|
||||
@change="loadTasks(1)"
|
||||
@ -62,12 +67,13 @@
|
||||
</span>
|
||||
</p>
|
||||
<p class="control">
|
||||
<button :disabled="newTaskText.length === 0" @click="addTask()" class="button is-primary">
|
||||
<span class="icon is-small">
|
||||
<icon icon="plus"/>
|
||||
</span>
|
||||
<x-button
|
||||
:disabled="newTaskText.length === 0"
|
||||
@click="addTask()"
|
||||
icon="plus"
|
||||
>
|
||||
Add
|
||||
</button>
|
||||
</x-button>
|
||||
</p>
|
||||
</div>
|
||||
<p class="help is-danger" v-if="showError && newTaskText === ''">
|
||||
@ -97,23 +103,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-4" v-if="isTaskEdit">
|
||||
<div class="card taskedit">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">
|
||||
Edit Task
|
||||
</p>
|
||||
<a @click="isTaskEdit = false" class="card-header-icon">
|
||||
<span class="icon">
|
||||
<icon icon="angle-right"/>
|
||||
</span>
|
||||
</a>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<div class="content">
|
||||
<edit-task :task="taskEditTask"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<card class="taskedit" title="Edit Task" :has-close="true" @close="() => isTaskEdit = false">
|
||||
<edit-task :task="taskEditTask"/>
|
||||
</card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -2,39 +2,37 @@
|
||||
<div :class="{'is-loading': taskCollectionService.loading}" class="table-view loader-container">
|
||||
<div class="filter-container">
|
||||
<div class="items">
|
||||
<button @click.prevent.stop="() => {showActiveColumnsFilter = !showActiveColumnsFilter; showTaskFilter = false}"
|
||||
class="button">
|
||||
<span class="icon is-small">
|
||||
<icon icon="th"/>
|
||||
</span>
|
||||
<x-button
|
||||
@click.prevent.stop="() => {showActiveColumnsFilter = !showActiveColumnsFilter; showTaskFilter = false}"
|
||||
icon="th"
|
||||
type="secondary"
|
||||
>
|
||||
Columns
|
||||
</button>
|
||||
<button @click.prevent.stop="() => {showTaskFilter = !showTaskFilter; showActiveColumnsFilter = false}"
|
||||
class="button">
|
||||
<span class="icon is-small">
|
||||
<icon icon="filter"/>
|
||||
</span>
|
||||
</x-button>
|
||||
<x-button
|
||||
@click.prevent.stop="() => {showTaskFilter = !showTaskFilter; showActiveColumnsFilter = false}"
|
||||
icon="filter"
|
||||
type="secondary"
|
||||
>
|
||||
Filters
|
||||
</button>
|
||||
</x-button>
|
||||
</div>
|
||||
<transition name="fade">
|
||||
<div class="card" v-if="showActiveColumnsFilter">
|
||||
<div class="card-content">
|
||||
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.id">#</fancycheckbox>
|
||||
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.done">Done</fancycheckbox>
|
||||
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.title">Title</fancycheckbox>
|
||||
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.priority">Priority</fancycheckbox>
|
||||
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.labels">Labels</fancycheckbox>
|
||||
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.assignees">Assignees</fancycheckbox>
|
||||
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.dueDate">Due Date</fancycheckbox>
|
||||
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.startDate">Start Date</fancycheckbox>
|
||||
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.endDate">End Date</fancycheckbox>
|
||||
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.percentDone">% Done</fancycheckbox>
|
||||
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.created">Created</fancycheckbox>
|
||||
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.updated">Updated</fancycheckbox>
|
||||
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.createdBy">Created By</fancycheckbox>
|
||||
</div>
|
||||
</div>
|
||||
<card v-if="showActiveColumnsFilter">
|
||||
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.id">#</fancycheckbox>
|
||||
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.done">Done</fancycheckbox>
|
||||
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.title">Title</fancycheckbox>
|
||||
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.priority">Priority</fancycheckbox>
|
||||
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.labels">Labels</fancycheckbox>
|
||||
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.assignees">Assignees</fancycheckbox>
|
||||
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.dueDate">Due Date</fancycheckbox>
|
||||
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.startDate">Start Date</fancycheckbox>
|
||||
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.endDate">End Date</fancycheckbox>
|
||||
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.percentDone">% Done</fancycheckbox>
|
||||
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.created">Created</fancycheckbox>
|
||||
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.updated">Updated</fancycheckbox>
|
||||
<fancycheckbox @change="saveTaskColumns" v-model="activeColumns.createdBy">Created By</fancycheckbox>
|
||||
</card>
|
||||
</transition>
|
||||
<filter-popup
|
||||
@change="loadTasks(1)"
|
||||
@ -174,7 +172,8 @@
|
||||
:aria-label="'Goto page ' + p.number"
|
||||
:class="{'is-current': p.number === currentPage}"
|
||||
:to="getRouteForPagination(p.number, 'table')"
|
||||
class="pagination-link">{{ p.number }}
|
||||
class="pagination-link">
|
||||
{{ p.number }}
|
||||
</router-link>
|
||||
</li>
|
||||
</template>
|
||||
|
@ -4,84 +4,74 @@
|
||||
This namespace is archived.
|
||||
It is not possible to create new lists or edit it.
|
||||
</div>
|
||||
<div class="card">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">
|
||||
Edit Namespace
|
||||
</p>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<div class="content">
|
||||
<form @submit.prevent="submit()">
|
||||
<div class="field">
|
||||
<label class="label" for="namespacetext">Namespace Name</label>
|
||||
<div class="control">
|
||||
<input
|
||||
:class="{ 'disabled': namespaceService.loading}"
|
||||
:disabled="namespaceService.loading"
|
||||
class="input"
|
||||
id="namespacetext"
|
||||
placeholder="The namespace text is here..."
|
||||
type="text"
|
||||
v-focus
|
||||
v-model="namespace.title"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="namespacedescription">Description</label>
|
||||
<div class="control">
|
||||
<editor
|
||||
:class="{ 'disabled': namespaceService.loading}"
|
||||
:disabled="namespaceService.loading"
|
||||
:preview-is-default="false"
|
||||
id="namespacedescription"
|
||||
placeholder="The namespaces description goes here..."
|
||||
v-if="editorActive"
|
||||
v-model="namespace.description"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="isArchivedCheck">Is Archived</label>
|
||||
<div class="control">
|
||||
<fancycheckbox
|
||||
v-model="namespace.isArchived"
|
||||
v-tooltip="'If a namespace is archived, you cannot create new lists or edit it.'">
|
||||
This namespace is archived
|
||||
</fancycheckbox>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">Color</label>
|
||||
<div class="control">
|
||||
<color-picker v-model="namespace.hexColor"/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="field has-addons mt-4">
|
||||
<div class="control is-fullwidth">
|
||||
<button
|
||||
@click="submit()"
|
||||
:class="{ 'is-loading': namespaceService.loading}"
|
||||
class="button is-primary is-fullwidth">
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
<div class="control">
|
||||
<button
|
||||
@click="showDeleteModal = true"
|
||||
:class="{ 'is-loading': namespaceService.loading}"
|
||||
class="button is-danger">
|
||||
<span class="icon">
|
||||
<icon icon="trash-alt"/>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<card title="Edit Namespace">
|
||||
<form @submit.prevent="submit()">
|
||||
<div class="field">
|
||||
<label class="label" for="namespacetext">Namespace Name</label>
|
||||
<div class="control">
|
||||
<input
|
||||
:class="{ 'disabled': namespaceService.loading}"
|
||||
:disabled="namespaceService.loading"
|
||||
class="input"
|
||||
id="namespacetext"
|
||||
placeholder="The namespace text is here..."
|
||||
type="text"
|
||||
v-focus
|
||||
v-model="namespace.title"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="namespacedescription">Description</label>
|
||||
<div class="control">
|
||||
<editor
|
||||
:class="{ 'disabled': namespaceService.loading}"
|
||||
:disabled="namespaceService.loading"
|
||||
:preview-is-default="false"
|
||||
id="namespacedescription"
|
||||
placeholder="The namespaces description goes here..."
|
||||
v-if="editorActive"
|
||||
v-model="namespace.description"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="isArchivedCheck">Is Archived</label>
|
||||
<div class="control">
|
||||
<fancycheckbox
|
||||
v-model="namespace.isArchived"
|
||||
v-tooltip="'If a namespace is archived, you cannot create new lists or edit it.'">
|
||||
This namespace is archived
|
||||
</fancycheckbox>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">Color</label>
|
||||
<div class="control">
|
||||
<color-picker v-model="namespace.hexColor"/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="field has-addons mt-4">
|
||||
<div class="control is-fullwidth">
|
||||
<x-button
|
||||
@click="submit()"
|
||||
:loading="namespaceService.loading"
|
||||
class="is-fullwidth"
|
||||
>
|
||||
Save
|
||||
</x-button>
|
||||
</div>
|
||||
<div class="control">
|
||||
<x-button
|
||||
@click="showDeleteModal = true"
|
||||
:loading="namespaceService.loading"
|
||||
class="is-danger"
|
||||
icon="trash-alt"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</card>
|
||||
|
||||
<component
|
||||
:id="namespace.id"
|
||||
|
@ -1,32 +1,26 @@
|
||||
<template>
|
||||
<div class="content namespaces-list loader-container" :class="{'is-loading': loading}">
|
||||
<router-link :to="{name: 'namespace.create'}" class="button is-primary new-namespace">
|
||||
<span class="icon is-small">
|
||||
<icon icon="plus"/>
|
||||
</span>
|
||||
<x-button :to="{name: 'namespace.create'}" class="new-namespace" icon="plus">
|
||||
Create namespace
|
||||
</router-link>
|
||||
<router-link :to="{name: 'filters.create'}" class="button is-primary new-namespace">
|
||||
<span class="icon is-small">
|
||||
<icon icon="filter"/>
|
||||
</span>
|
||||
</x-button>
|
||||
<x-button :to="{name: 'filters.create'}" class="new-namespace" icon="filter">
|
||||
Create saved filter
|
||||
</router-link>
|
||||
</x-button>
|
||||
|
||||
<fancycheckbox class="show-archived-check" v-model="showArchived">
|
||||
Show Archived
|
||||
</fancycheckbox>
|
||||
|
||||
<div :key="`n${n.id}`" class="namespace" v-for="n in namespaces">
|
||||
<router-link
|
||||
<x-button
|
||||
:to="{name: 'list.create', params: {id: n.id}}"
|
||||
class="button is-pulled-right"
|
||||
v-if="n.id > 0">
|
||||
<span class="icon is-small">
|
||||
<icon icon="plus"/>
|
||||
</span>
|
||||
class="is-pulled-right"
|
||||
type="secondary"
|
||||
v-if="n.id > 0"
|
||||
icon="plus"
|
||||
>
|
||||
Create list
|
||||
</router-link>
|
||||
</x-button>
|
||||
|
||||
<h1>
|
||||
<span>{{ n.title }}</span>
|
||||
|
@ -18,12 +18,14 @@
|
||||
v-model="namespace.title"/>
|
||||
</p>
|
||||
<p class="control">
|
||||
<button :disabled="namespace.title === ''" @click="newNamespace()" class="button is-primary has-no-shadow">
|
||||
<span class="icon is-small">
|
||||
<icon icon="plus"/>
|
||||
</span>
|
||||
<x-button
|
||||
:disabled="namespace.title === ''"
|
||||
@click="newNamespace()"
|
||||
:shadow="false"
|
||||
icon="plus"
|
||||
>
|
||||
Add
|
||||
</button>
|
||||
</x-button>
|
||||
</p>
|
||||
</div>
|
||||
<p class="help is-danger" v-if="showError && namespace.title === ''">
|
||||
|
@ -30,9 +30,9 @@
|
||||
/>
|
||||
</h3>
|
||||
<div v-if="!showAll">
|
||||
<a @click="showTodaysTasks()" class="button has-no-shadow mr-2">Today</a>
|
||||
<a @click="setDatesToNextWeek()" class="button has-no-shadow mr-2">Next Week</a>
|
||||
<a @click="setDatesToNextMonth()" class="button has-no-shadow">Next Month</a>
|
||||
<x-button type="secondary" @click="showTodaysTasks()" :shadow="false" class="mr-2">Today</x-button>
|
||||
<x-button type="secondary" @click="setDatesToNextWeek()" :shadow="false" class="mr-2">Next Week</x-button>
|
||||
<x-button type="secondary" @click="setDatesToNextMonth()" :shadow="false">Next Month</x-button>
|
||||
</div>
|
||||
<template v-if="!taskService.loading && (!hasUndoneTasks || !tasks || tasks.length === 0)">
|
||||
<h3 class="nothing">Nothing to do - Have a nice day!</h3>
|
||||
|
@ -56,8 +56,11 @@
|
||||
choose-date-label="Click here to set a due date"
|
||||
:disabled="taskService.loading || !canWrite"
|
||||
ref="dueDate"
|
||||
/>
|
||||
<a @click="() => {task.dueDate = null;saveTask()}" v-if="task.dueDate && canWrite" class="remove">
|
||||
/>
|
||||
<a
|
||||
@click="() => {task.dueDate = null;saveTask()}"
|
||||
v-if="task.dueDate && canWrite"
|
||||
class="remove">
|
||||
<span class="icon is-small">
|
||||
<icon icon="times"></icon>
|
||||
</span>
|
||||
@ -94,7 +97,11 @@
|
||||
:disabled="taskService.loading || !canWrite"
|
||||
ref="startDate"
|
||||
/>
|
||||
<a @click="() => {task.startDate = null;saveTask()}" v-if="task.startDate && canWrite" class="remove">
|
||||
<a
|
||||
@click="() => {task.startDate = null;saveTask()}"
|
||||
v-if="task.startDate && canWrite"
|
||||
class="remove"
|
||||
>
|
||||
<span class="icon is-small">
|
||||
<icon icon="times"></icon>
|
||||
</span>
|
||||
@ -117,7 +124,10 @@
|
||||
:disabled="taskService.loading || !canWrite"
|
||||
ref="endDate"
|
||||
/>
|
||||
<a @click="() => {task.endDate = null;saveTask()}" v-if="task.endDate && canWrite" class="remove">
|
||||
<a
|
||||
@click="() => {task.endDate = null;saveTask()}"
|
||||
v-if="task.endDate && canWrite"
|
||||
class="remove">
|
||||
<span class="icon is-small">
|
||||
<icon icon="times"></icon>
|
||||
</span>
|
||||
@ -235,94 +245,124 @@
|
||||
<comments :can-write="canWrite" :task-id="taskId"/>
|
||||
</div>
|
||||
<div class="column is-one-third action-buttons" v-if="canWrite">
|
||||
<a
|
||||
:class="{'is-success': !task.done, 'has-no-shadow': !task.done}"
|
||||
<x-button
|
||||
:class="{'is-success': !task.done}"
|
||||
:shadow="task.done"
|
||||
@click="toggleTaskDone()"
|
||||
class="button is-outlined has-no-border">
|
||||
<span class="icon is-small"><icon icon="check-double"/></span>
|
||||
<template v-if="task.done">
|
||||
Mark as undone
|
||||
</template>
|
||||
<template v-else>
|
||||
Done!
|
||||
</template>
|
||||
</a>
|
||||
<a
|
||||
class="is-outlined has-no-border"
|
||||
icon="check-double"
|
||||
type="secondary"
|
||||
>
|
||||
{{ task.done ? 'Mark as undone' : 'Done!' }}
|
||||
</x-button>
|
||||
<x-button
|
||||
@click="setFieldActive('assignees')"
|
||||
@shortkey="setFieldActive('assignees')"
|
||||
class="button"
|
||||
type="secondary"
|
||||
v-shortkey="['a']">
|
||||
<span class="icon is-small"><icon icon="users"/></span>
|
||||
Assign this task to a user
|
||||
</a>
|
||||
<a
|
||||
</x-button>
|
||||
<x-button
|
||||
@click="setFieldActive('labels')"
|
||||
@shortkey="setFieldActive('labels')"
|
||||
class="button"
|
||||
v-shortkey="['l']">
|
||||
<span class="icon is-small"><icon icon="tags"/></span>
|
||||
type="secondary"
|
||||
v-shortkey="['l']"
|
||||
icon="tags"
|
||||
>
|
||||
Add labels
|
||||
</a>
|
||||
<a @click="setFieldActive('priority')" class="button">
|
||||
<span class="icon is-small"><icon :icon="['far', 'star']"/></span>
|
||||
</x-button>
|
||||
<x-button
|
||||
@click="setFieldActive('priority')"
|
||||
type="secondary"
|
||||
:icon="['far', 'star']"
|
||||
>
|
||||
Set Priority
|
||||
</a>
|
||||
<a
|
||||
</x-button>
|
||||
<x-button
|
||||
@click="setFieldActive('dueDate')"
|
||||
@shortkey="setFieldActive('dueDate')"
|
||||
class="button"
|
||||
v-shortkey="['d']">
|
||||
<span class="icon is-small"><icon icon="calendar"/></span>
|
||||
type="secondary"
|
||||
v-shortkey="['d']"
|
||||
icon="calendar"
|
||||
>
|
||||
Set Due Date
|
||||
</a>
|
||||
<a @click="setFieldActive('startDate')" class="button">
|
||||
<span class="icon is-small"><icon icon="calendar-week"/></span>
|
||||
</x-button>
|
||||
<x-button
|
||||
@click="setFieldActive('startDate')"
|
||||
type="secondary"
|
||||
icon="calendar-week"
|
||||
>
|
||||
Set a Start Date
|
||||
</a>
|
||||
<a @click="setFieldActive('endDate')" class="button">
|
||||
<span class="icon is-small"><icon icon="calendar-week"/></span>
|
||||
</x-button>
|
||||
<x-button
|
||||
@click="setFieldActive('endDate')"
|
||||
type="secondary"
|
||||
icon="calendar-week"
|
||||
>
|
||||
Set an End Date
|
||||
</a>
|
||||
<a @click="setFieldActive('reminders')" class="button">
|
||||
<span class="icon is-small"><icon icon="history"/></span>
|
||||
</x-button>
|
||||
<x-button
|
||||
@click="setFieldActive('reminders')"
|
||||
type="secondary"
|
||||
icon="history"
|
||||
>
|
||||
Set Reminders
|
||||
</a>
|
||||
<a @click="setFieldActive('repeatAfter')" class="button">
|
||||
<span class="icon is-small"><icon :icon="['far', 'clock']"/></span>
|
||||
</x-button>
|
||||
<x-button
|
||||
@click="setFieldActive('repeatAfter')"
|
||||
type="secondary"
|
||||
:icon="['far', 'clock']"
|
||||
>
|
||||
Set a repeating interval
|
||||
</a>
|
||||
<a @click="setFieldActive('percentDone')" class="button">
|
||||
<span class="icon is-small"><icon icon="percent"/></span>
|
||||
</x-button>
|
||||
<x-button
|
||||
@click="setFieldActive('percentDone')"
|
||||
type="secondary"
|
||||
icon="percent"
|
||||
>
|
||||
Set Percent Done
|
||||
</a>
|
||||
<a
|
||||
</x-button>
|
||||
<x-button
|
||||
@click="setFieldActive('attachments')"
|
||||
@shortkey="setFieldActive('attachments')"
|
||||
class="button"
|
||||
v-shortkey="['f']">
|
||||
<span class="icon is-small"><icon icon="paperclip"/></span>
|
||||
type="secondary"
|
||||
v-shortkey="['f']"
|
||||
icon="paperclip"
|
||||
>
|
||||
Add attachments
|
||||
</a>
|
||||
<a
|
||||
</x-button>
|
||||
<x-button
|
||||
@click="setFieldActive('relatedTasks')"
|
||||
@shortkey="setFieldActive('relatedTasks')"
|
||||
class="button"
|
||||
v-shortkey="['r']">
|
||||
<span class="icon is-small"><icon icon="tasks"/></span>
|
||||
type="secondary"
|
||||
v-shortkey="['r']"
|
||||
icon="tasks"
|
||||
>
|
||||
Add task relations
|
||||
</a>
|
||||
<a @click="setFieldActive('moveList')" class="button">
|
||||
<span class="icon is-small"><icon icon="list"/></span>
|
||||
</x-button>
|
||||
<x-button
|
||||
@click="setFieldActive('moveList')"
|
||||
type="secondary"
|
||||
icon="list"
|
||||
>
|
||||
Move task
|
||||
</a>
|
||||
<a @click="setFieldActive('color')" class="button">
|
||||
<span class="icon is-small"><icon icon="fill-drip"/></span>
|
||||
</x-button>
|
||||
<x-button
|
||||
@click="setFieldActive('color')"
|
||||
type="secondary"
|
||||
icon="fill-drip"
|
||||
>
|
||||
Set task color
|
||||
</a>
|
||||
<a @click="showDeleteModal = true" class="button is-danger is-outlined has-no-shadow has-no-border">
|
||||
<span class="icon is-small"><icon icon="trash-alt"/></span>
|
||||
</x-button>
|
||||
<x-button
|
||||
@click="showDeleteModal = true"
|
||||
icon="trash-alt"
|
||||
:shadow="false"
|
||||
class="is-danger is-outlined has-no-border"
|
||||
>
|
||||
Delete task
|
||||
</a>
|
||||
</x-button>
|
||||
|
||||
<!-- Created / Updated [by] -->
|
||||
<p class="created">
|
||||
@ -335,7 +375,7 @@
|
||||
</template>
|
||||
<template v-if="task.done">
|
||||
<br/>
|
||||
Done <span v-tooltip="doneFormatted">{{ doneSince }}</span>
|
||||
Done <span v-tooltip="doneFormatted">{{ doneSince }}</span>
|
||||
</template>
|
||||
</p>
|
||||
</div>
|
||||
@ -568,13 +608,17 @@ export default {
|
||||
this.activeFields[fieldName] = true
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs[fieldName]) {
|
||||
this.$refs[fieldName].$el.focus();
|
||||
this.$refs[fieldName].$el.focus()
|
||||
|
||||
// scroll the field to the center of the screen if not in viewport already
|
||||
const boundingRect = this.$refs[fieldName].$el.getBoundingClientRect();
|
||||
const boundingRect = this.$refs[fieldName].$el.getBoundingClientRect()
|
||||
|
||||
if (boundingRect.top > (window.scrollY + window.innerHeight) || boundingRect.top < window.scrollY)
|
||||
this.$refs[fieldName].$el.scrollIntoView({behavior: "smooth", block: "center", inline: "nearest"});
|
||||
this.$refs[fieldName].$el.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'center',
|
||||
inline: 'nearest'
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
@ -1,77 +1,75 @@
|
||||
<template>
|
||||
<div class="loader-container is-max-width-desktop" :class="{ 'is-loading': teamService.loading}">
|
||||
<div class="card is-fullwidth" v-if="userIsAdmin">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">
|
||||
Edit Team
|
||||
</p>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<div class="content">
|
||||
<form @submit.prevent="save()">
|
||||
<div class="field">
|
||||
<label class="label" for="teamtext">Team Name</label>
|
||||
<div class="control">
|
||||
<input
|
||||
:class="{ 'disabled': teamMemberService.loading}"
|
||||
:disabled="teamMemberService.loading"
|
||||
class="input"
|
||||
id="teamtext"
|
||||
placeholder="The team text is here..."
|
||||
type="text"
|
||||
v-focus
|
||||
v-model="team.name"/>
|
||||
</div>
|
||||
</div>
|
||||
<p class="help is-danger" v-if="showError && team.name === ''">
|
||||
Please specify a name.
|
||||
</p>
|
||||
<div class="field">
|
||||
<label class="label" for="teamdescription">Description</label>
|
||||
<div class="control">
|
||||
<editor
|
||||
:class="{ 'disabled': teamService.loading}"
|
||||
:disabled="teamService.loading"
|
||||
:preview-is-default="false"
|
||||
id="teamdescription"
|
||||
placeholder="The teams description goes here..."
|
||||
v-model="team.description"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="field has-addons mt-4">
|
||||
<div class="control is-fullwidth">
|
||||
<button
|
||||
@click="save()"
|
||||
:class="{ 'is-loading': teamService.loading}"
|
||||
class="button is-primary is-fullwidth">
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
<div class="control">
|
||||
<button
|
||||
@click="showDeleteModal = true"
|
||||
:class="{ 'is-loading': teamService.loading}"
|
||||
class="button is-danger">
|
||||
<span class="icon">
|
||||
<icon icon="trash-alt"/>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="loader-container is-max-width-desktop"
|
||||
:class="{ 'is-loading': teamService.loading }"
|
||||
>
|
||||
<card class="is-fullwidth" v-if="userIsAdmin" title="Edit Team">
|
||||
<form @submit.prevent="save()">
|
||||
<div class="field">
|
||||
<label class="label" for="teamtext"
|
||||
>Team Name</label
|
||||
>
|
||||
<div class="control">
|
||||
<input
|
||||
:class="{
|
||||
disabled: teamMemberService.loading,
|
||||
}"
|
||||
:disabled="teamMemberService.loading"
|
||||
class="input"
|
||||
id="teamtext"
|
||||
placeholder="The team text is here..."
|
||||
type="text"
|
||||
v-focus
|
||||
v-model="team.name"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card is-fullwidth has-overflow">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">
|
||||
Team Members
|
||||
<p
|
||||
class="help is-danger"
|
||||
v-if="showError && team.name === ''"
|
||||
>
|
||||
Please specify a name.
|
||||
</p>
|
||||
</header>
|
||||
<div class="card-content" v-if="userIsAdmin">
|
||||
<div class="field">
|
||||
<label class="label" for="teamdescription"
|
||||
>Description</label
|
||||
>
|
||||
<div class="control">
|
||||
<editor
|
||||
:class="{ disabled: teamService.loading }"
|
||||
:disabled="teamService.loading"
|
||||
:preview-is-default="false"
|
||||
id="teamdescription"
|
||||
placeholder="The teams description goes here..."
|
||||
v-model="team.description"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="field has-addons mt-4">
|
||||
<div class="control is-fullwidth">
|
||||
<x-button
|
||||
@click="save()"
|
||||
:loading="teamService.loading"
|
||||
class="is-fullwidth"
|
||||
>
|
||||
Save
|
||||
</x-button>
|
||||
</div>
|
||||
<div class="control">
|
||||
<x-button
|
||||
@click="showDeleteModal = true"
|
||||
:loading="teamService.loading"
|
||||
class="is-danger"
|
||||
icon="trash-alt"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</card>
|
||||
|
||||
<card class="is-fullwidth has-overflow" title="Team Members">
|
||||
<div class="p-4" v-if="userIsAdmin">
|
||||
<div class="field has-addons">
|
||||
<div class="control is-expanded">
|
||||
<multiselect
|
||||
@ -84,12 +82,9 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="control">
|
||||
<button class="button is-primary" @click="addUser">
|
||||
<span class="icon is-small">
|
||||
<icon icon="plus"/>
|
||||
</span>
|
||||
<x-button @click="addUser" icon="plus">
|
||||
Add To Team
|
||||
</button>
|
||||
</x-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -104,57 +99,68 @@
|
||||
</td>
|
||||
<td class="type">
|
||||
<template v-if="m.admin">
|
||||
<span class="icon is-small">
|
||||
<icon icon="lock"/>
|
||||
</span>
|
||||
<span class="icon is-small">
|
||||
<icon icon="lock"/>
|
||||
</span>
|
||||
Admin
|
||||
</template>
|
||||
<template v-else>
|
||||
<span class="icon is-small">
|
||||
<icon icon="user"/>
|
||||
</span>
|
||||
<span class="icon is-small">
|
||||
<icon icon="user"/>
|
||||
</span>
|
||||
Member
|
||||
</template>
|
||||
</td>
|
||||
<td class="actions" v-if="userIsAdmin">
|
||||
<button :class="{'is-loading': teamMemberService.loading}" @click="() => toggleUserType(m)"
|
||||
class="button buttonright is-primary"
|
||||
v-if="m.id !== userInfo.id">
|
||||
<x-button
|
||||
:loading="teamMemberService.loading"
|
||||
@click="() => toggleUserType(m)"
|
||||
class="mr-2"
|
||||
v-if="m.id !== userInfo.id"
|
||||
>
|
||||
Make {{ m.admin ? 'Member' : 'Admin' }}
|
||||
</button>
|
||||
<button :class="{'is-loading': teamMemberService.loading}"
|
||||
</x-button>
|
||||
<x-button
|
||||
:loading="teamMemberService.loading"
|
||||
@click="() => {member = m; showUserDeleteModal = true}"
|
||||
class="button is-danger"
|
||||
v-if="m.id !== userInfo.id">
|
||||
<span class="icon">
|
||||
<icon icon="trash-alt"/>
|
||||
</span>
|
||||
</button>
|
||||
class="is-danger"
|
||||
v-if="m.id !== userInfo.id"
|
||||
icon="trash-alt"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</card>
|
||||
|
||||
<!-- Team delete modal -->
|
||||
<modal
|
||||
@close="showDeleteModal = false"
|
||||
@submit="deleteTeam()"
|
||||
v-if="showDeleteModal">
|
||||
v-if="showDeleteModal"
|
||||
>
|
||||
<span slot="header">Delete the team</span>
|
||||
<p slot="text">Are you sure you want to delete this team and all of its members?<br/>
|
||||
All team members will loose access to lists and namespaces shared with this team.<br/>
|
||||
<b>This CANNOT BE UNDONE!</b></p>
|
||||
<p slot="text">
|
||||
Are you sure you want to delete this team and all of its
|
||||
members?<br/>
|
||||
All team members will loose access to lists and namespaces
|
||||
shared with this team.<br/>
|
||||
<b>This CANNOT BE UNDONE!</b>
|
||||
</p>
|
||||
</modal>
|
||||
<!-- User delete modal -->
|
||||
<modal
|
||||
@close="showUserDeleteModal = false"
|
||||
@submit="deleteUser()"
|
||||
v-if="showUserDeleteModal">
|
||||
v-if="showUserDeleteModal"
|
||||
>
|
||||
<span slot="header">Remove a user from the team</span>
|
||||
<p slot="text">Are you sure you want to remove this user from the team?<br/>
|
||||
They will loose access to all lists and namespaces this team has access to.<br/>
|
||||
<b>This CANNOT BE UNDONE!</b></p>
|
||||
<p slot="text">
|
||||
Are you sure you want to remove this user from the team?<br/>
|
||||
They will loose access to all lists and namespaces this team has
|
||||
access to.<br/>
|
||||
<b>This CANNOT BE UNDONE!</b>
|
||||
</p>
|
||||
</modal>
|
||||
</div>
|
||||
</template>
|
||||
@ -199,7 +205,9 @@ export default {
|
||||
components: {
|
||||
Multiselect,
|
||||
editor: () => ({
|
||||
component: import(/* webpackChunkName: "editor" */ '../../components/input/editor'),
|
||||
component: import(
|
||||
/* webpackChunkName: "editor" */ '../../components/input/editor'
|
||||
),
|
||||
loading: LoadingComponent,
|
||||
error: ErrorComponent,
|
||||
timeout: 60000,
|
||||
@ -213,25 +221,30 @@ export default {
|
||||
},
|
||||
watch: {
|
||||
// call again the method if the route changes
|
||||
'$route': 'loadTeam',
|
||||
$route: 'loadTeam',
|
||||
},
|
||||
computed: {
|
||||
userIsAdmin() {
|
||||
return this.team && this.team.maxRight && this.team.maxRight > Rights.READ
|
||||
return (
|
||||
this.team &&
|
||||
this.team.maxRight &&
|
||||
this.team.maxRight > Rights.READ
|
||||
)
|
||||
},
|
||||
...mapState({
|
||||
userInfo: state => state.auth.info,
|
||||
userInfo: (state) => state.auth.info,
|
||||
}),
|
||||
},
|
||||
methods: {
|
||||
loadTeam() {
|
||||
this.team = new TeamModel({id: this.teamId})
|
||||
this.teamService.get(this.team)
|
||||
.then(response => {
|
||||
this.teamService
|
||||
.get(this.team)
|
||||
.then((response) => {
|
||||
this.$set(this, 'team', response)
|
||||
this.setTitle(`Edit Team ${this.team.name}`)
|
||||
})
|
||||
.catch(e => {
|
||||
.catch((e) => {
|
||||
this.error(e, this)
|
||||
})
|
||||
},
|
||||
@ -242,32 +255,47 @@ export default {
|
||||
}
|
||||
this.showError = false
|
||||
|
||||
this.teamService.update(this.team)
|
||||
.then(response => {
|
||||
this.teamService
|
||||
.update(this.team)
|
||||
.then((response) => {
|
||||
this.team = response
|
||||
this.success({message: 'The team was successfully updated.'}, this)
|
||||
this.success(
|
||||
{message: 'The team was successfully updated.'},
|
||||
this
|
||||
)
|
||||
})
|
||||
.catch(e => {
|
||||
.catch((e) => {
|
||||
this.error(e, this)
|
||||
})
|
||||
},
|
||||
deleteTeam() {
|
||||
this.teamService.delete(this.team)
|
||||
this.teamService
|
||||
.delete(this.team)
|
||||
.then(() => {
|
||||
this.success({message: 'The team was successfully deleted.'}, this)
|
||||
this.success(
|
||||
{message: 'The team was successfully deleted.'},
|
||||
this
|
||||
)
|
||||
router.push({name: 'teams.index'})
|
||||
})
|
||||
.catch(e => {
|
||||
.catch((e) => {
|
||||
this.error(e, this)
|
||||
})
|
||||
},
|
||||
deleteUser() {
|
||||
this.teamMemberService.delete(this.member)
|
||||
this.teamMemberService
|
||||
.delete(this.member)
|
||||
.then(() => {
|
||||
this.success({message: 'The user was successfully deleted from the team.'}, this)
|
||||
this.success(
|
||||
{
|
||||
message:
|
||||
'The user was successfully deleted from the team.',
|
||||
},
|
||||
this
|
||||
)
|
||||
this.loadTeam()
|
||||
})
|
||||
.catch(e => {
|
||||
.catch((e) => {
|
||||
this.error(e, this)
|
||||
})
|
||||
.finally(() => {
|
||||
@ -279,29 +307,42 @@ export default {
|
||||
teamId: this.teamId,
|
||||
username: this.newMember.username,
|
||||
})
|
||||
this.teamMemberService.create(newMember)
|
||||
this.teamMemberService
|
||||
.create(newMember)
|
||||
.then(() => {
|
||||
this.loadTeam()
|
||||
this.success({message: 'The team member was successfully added.'}, this)
|
||||
this.success(
|
||||
{message: 'The team member was successfully added.'},
|
||||
this
|
||||
)
|
||||
})
|
||||
.catch(e => {
|
||||
.catch((e) => {
|
||||
this.error(e, this)
|
||||
})
|
||||
},
|
||||
toggleUserType(member) {
|
||||
member.admin = !member.admin
|
||||
member.teamId = this.teamId
|
||||
this.teamMemberService.update(member)
|
||||
.then(r => {
|
||||
this.teamMemberService
|
||||
.update(member)
|
||||
.then((r) => {
|
||||
for (const tm in this.team.members) {
|
||||
if (this.team.members[tm].id === member.id) {
|
||||
this.$set(this.team.members[tm], 'admin', r.admin)
|
||||
break
|
||||
}
|
||||
}
|
||||
this.success({message: 'The team member was successfully made ' + (member.admin ? 'admin' : 'member') + '.'}, this)
|
||||
this.success(
|
||||
{
|
||||
message:
|
||||
'The team member was successfully made ' +
|
||||
(member.admin ? 'admin' : 'member') +
|
||||
'.',
|
||||
},
|
||||
this
|
||||
)
|
||||
})
|
||||
.catch(e => {
|
||||
.catch((e) => {
|
||||
this.error(e, this)
|
||||
})
|
||||
},
|
||||
@ -311,11 +352,12 @@ export default {
|
||||
return
|
||||
}
|
||||
|
||||
this.userService.getAll({}, {s: query})
|
||||
.then(response => {
|
||||
this.userService
|
||||
.getAll({}, {s: query})
|
||||
.then((response) => {
|
||||
this.$set(this, 'foundUsers', response)
|
||||
})
|
||||
.catch(e => {
|
||||
.catch((e) => {
|
||||
this.error(e, this)
|
||||
})
|
||||
},
|
||||
|
@ -1,11 +1,12 @@
|
||||
<template>
|
||||
<div class="content loader-container is-max-width-desktop" v-bind:class="{ 'is-loading': teamService.loading}">
|
||||
<router-link :to="{name:'teams.create'}" class="button is-primary button-right">
|
||||
<span class="icon is-small">
|
||||
<icon icon="plus"/>
|
||||
</span>
|
||||
<x-button
|
||||
:to="{name:'teams.create'}"
|
||||
class="is-pulled-right"
|
||||
icon="plus"
|
||||
>
|
||||
New Team
|
||||
</router-link>
|
||||
</x-button>
|
||||
|
||||
<h1>Teams</h1>
|
||||
<ul class="teams box" v-if="teams.length > 0">
|
||||
|
@ -16,12 +16,9 @@
|
||||
v-model="team.name"/>
|
||||
</p>
|
||||
<p class="control">
|
||||
<button class="button is-primary has-no-shadow" type="submit">
|
||||
<span class="icon is-small">
|
||||
<icon icon="plus"/>
|
||||
</span>
|
||||
<x-button :shadow="false" @click="newTeam" icon="plus">
|
||||
Add
|
||||
</button>
|
||||
</x-button>
|
||||
</p>
|
||||
</div>
|
||||
<p class="help is-danger" v-if="showError && team.name === ''">
|
||||
|
@ -54,12 +54,19 @@
|
||||
|
||||
<div class="field is-grouped login-buttons">
|
||||
<div class="control is-expanded">
|
||||
<button class="button is-primary" type="submit" v-bind:class="{ 'is-loading': loading}">
|
||||
<x-button
|
||||
@click="submit"
|
||||
:loading="loading"
|
||||
>
|
||||
Login
|
||||
</button>
|
||||
<router-link :to="{ name: 'user.register' }" class="button" v-if="registrationEnabled">
|
||||
</x-button>
|
||||
<x-button
|
||||
:to="{ name: 'user.register' }"
|
||||
v-if="registrationEnabled"
|
||||
type="secondary"
|
||||
>
|
||||
Register
|
||||
</router-link>
|
||||
</x-button>
|
||||
</div>
|
||||
<div class="control">
|
||||
<router-link :to="{ name: 'user.password-reset.request' }" class="reset-password-link">
|
||||
@ -73,9 +80,15 @@
|
||||
</form>
|
||||
|
||||
<div v-if="openidConnect.enabled && openidConnect.providers && openidConnect.providers.length > 0" class="mt-4">
|
||||
<a @click="redirectToProvider(p)" v-for="(p, k) in openidConnect.providers" :key="k" class="button is-fullwidth">
|
||||
<x-button
|
||||
@click="redirectToProvider(p)"
|
||||
v-for="(p, k) in openidConnect.providers"
|
||||
:key="k"
|
||||
type="secondary"
|
||||
class="is-fullwidth"
|
||||
>
|
||||
Log in with {{ p.name }}
|
||||
</a>
|
||||
</x-button>
|
||||
</div>
|
||||
|
||||
<legal/>
|
||||
|
@ -35,9 +35,12 @@
|
||||
|
||||
<div class="field is-grouped">
|
||||
<div class="control">
|
||||
<button :class="{ 'is-loading': this.passwordResetService.loading}" class="button is-primary"
|
||||
type="submit">Reset your password
|
||||
</button>
|
||||
<x-button
|
||||
:loading="this.passwordResetService.loading"
|
||||
@click="submit"
|
||||
>
|
||||
Reset your password
|
||||
</x-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="notification is-info" v-if="this.passwordResetService.loading">
|
||||
@ -51,7 +54,9 @@
|
||||
<div class="notification is-success">
|
||||
{{ successMessage }}
|
||||
</div>
|
||||
<router-link :to="{ name: 'user.login' }" class="button is-primary">Login</router-link>
|
||||
<x-button :to="{ name: 'user.login' }">
|
||||
Login
|
||||
</x-button>
|
||||
</div>
|
||||
<legal/>
|
||||
</div>
|
||||
|
@ -62,10 +62,15 @@
|
||||
|
||||
<div class="field is-grouped">
|
||||
<div class="control">
|
||||
<button class="button is-primary" type="submit" :class="{ 'is-loading': loading}" id="register-submit">
|
||||
<x-button
|
||||
:loading="loading"
|
||||
id="register-submit"
|
||||
@click="submit"
|
||||
class="mr-2"
|
||||
>
|
||||
Register
|
||||
</button>
|
||||
<router-link :to="{ name: 'user.login' }" class="button">Login</router-link>
|
||||
</x-button>
|
||||
<x-button :to="{ name: 'user.login' }" type="secondary">Login</x-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="notification is-info" v-if="loading">
|
||||
@ -136,9 +141,3 @@ export default {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.button {
|
||||
margin: 0 0.4em 0 0;
|
||||
}
|
||||
</style>
|
||||
|
@ -20,11 +20,13 @@
|
||||
|
||||
<div class="field is-grouped">
|
||||
<div class="control">
|
||||
<button class="button is-primary" type="submit"
|
||||
v-bind:class="{ 'is-loading': passwordResetService.loading}">Send me a password reset
|
||||
link
|
||||
</button>
|
||||
<router-link :to="{ name: 'user.login' }" class="button">Login</router-link>
|
||||
<x-button
|
||||
@click="submit"
|
||||
:loading="passwordResetService.loading"
|
||||
>
|
||||
Send me a password reset link
|
||||
</x-button>
|
||||
<x-button :to="{ name: 'user.login' }" type="secondary">Login</x-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="notification is-danger" v-if="errorMsg">
|
||||
@ -35,7 +37,7 @@
|
||||
<div class="notification is-success">
|
||||
Check your inbox! You should have a mail with instructions on how to reset your password.
|
||||
</div>
|
||||
<router-link :to="{ name: 'user.login' }" class="button is-primary">Login</router-link>
|
||||
<x-button :to="{ name: 'user.login' }">Login</x-button>
|
||||
</div>
|
||||
<legal/>
|
||||
</div>
|
||||
|
@ -3,265 +3,216 @@
|
||||
:class="{ 'is-loading': passwordUpdateService.loading || emailUpdateService.loading || totpService.loading }"
|
||||
class="loader-container is-max-width-desktop">
|
||||
<!-- Password update -->
|
||||
<div class="card">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">
|
||||
Update Your Password
|
||||
</p>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<div class="content">
|
||||
<form @submit.prevent="updatePassword()">
|
||||
<div class="field">
|
||||
<label class="label" for="newPassword">New Password</label>
|
||||
<div class="control">
|
||||
<input
|
||||
@keyup.enter="updatePassword"
|
||||
class="input"
|
||||
id="newPassword"
|
||||
placeholder="The new password..."
|
||||
type="password"
|
||||
v-model="passwordUpdate.newPassword"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="newPasswordConfirm">New Password Confirmation</label>
|
||||
<div class="control">
|
||||
<input
|
||||
@keyup.enter="updatePassword"
|
||||
class="input"
|
||||
id="newPasswordConfirm"
|
||||
placeholder="Confirm your new password..."
|
||||
type="password"
|
||||
v-model="passwordConfirm"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="currentPassword">Current Password</label>
|
||||
<div class="control">
|
||||
<input
|
||||
@keyup.enter="updatePassword"
|
||||
class="input"
|
||||
id="currentPassword"
|
||||
placeholder="Your current password"
|
||||
type="password"
|
||||
v-model="passwordUpdate.oldPassword"/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="bigbuttons">
|
||||
<button :class="{ 'is-loading': passwordUpdateService.loading}" @click="updatePassword()"
|
||||
class="button is-primary is-fullwidth">
|
||||
Save
|
||||
</button>
|
||||
<card title="Update Your Password">
|
||||
<form @submit.prevent="updatePassword()">
|
||||
<div class="field">
|
||||
<label class="label" for="newPassword">New Password</label>
|
||||
<div class="control">
|
||||
<input
|
||||
@keyup.enter="updatePassword"
|
||||
class="input"
|
||||
id="newPassword"
|
||||
placeholder="The new password..."
|
||||
type="password"
|
||||
v-model="passwordUpdate.newPassword"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="newPasswordConfirm">New Password Confirmation</label>
|
||||
<div class="control">
|
||||
<input
|
||||
@keyup.enter="updatePassword"
|
||||
class="input"
|
||||
id="newPasswordConfirm"
|
||||
placeholder="Confirm your new password..."
|
||||
type="password"
|
||||
v-model="passwordConfirm"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="currentPassword">Current Password</label>
|
||||
<div class="control">
|
||||
<input
|
||||
@keyup.enter="updatePassword"
|
||||
class="input"
|
||||
id="currentPassword"
|
||||
placeholder="Your current password"
|
||||
type="password"
|
||||
v-model="passwordUpdate.oldPassword"/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<x-button
|
||||
:loading="passwordUpdateService.loading"
|
||||
@click="updatePassword()"
|
||||
class="is-fullwidth mt-4">
|
||||
Save
|
||||
</x-button>
|
||||
</card>
|
||||
|
||||
<!-- Update E-Mail -->
|
||||
<div class="card">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">
|
||||
Update Your E-Mail Address
|
||||
</p>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<div class="content">
|
||||
<form @submit.prevent="updateEmail()">
|
||||
<div class="field">
|
||||
<label class="label" for="newEmail">New Email Address</label>
|
||||
<div class="control">
|
||||
<input
|
||||
@keyup.enter="updateEmail"
|
||||
class="input"
|
||||
id="newEmail"
|
||||
placeholder="The new email address..."
|
||||
type="email"
|
||||
v-model="emailUpdate.newEmail"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="currentPassword">Current Password</label>
|
||||
<div class="control">
|
||||
<input
|
||||
@keyup.enter="updateEmail"
|
||||
class="input"
|
||||
id="currentPassword"
|
||||
placeholder="Your current password"
|
||||
type="password"
|
||||
v-model="emailUpdate.password"/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="bigbuttons">
|
||||
<button :class="{ 'is-loading': emailUpdateService.loading}" @click="updateEmail()"
|
||||
class="button is-primary is-fullwidth">
|
||||
Save
|
||||
</button>
|
||||
<card title="Update Your E-Mail Address">
|
||||
<form @submit.prevent="updateEmail()">
|
||||
<div class="field">
|
||||
<label class="label" for="newEmail">New Email Address</label>
|
||||
<div class="control">
|
||||
<input
|
||||
@keyup.enter="updateEmail"
|
||||
class="input"
|
||||
id="newEmail"
|
||||
placeholder="The new email address..."
|
||||
type="email"
|
||||
v-model="emailUpdate.newEmail"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="currentPassword">Current Password</label>
|
||||
<div class="control">
|
||||
<input
|
||||
@keyup.enter="updateEmail"
|
||||
class="input"
|
||||
id="currentPassword"
|
||||
placeholder="Your current password"
|
||||
type="password"
|
||||
v-model="emailUpdate.password"/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<x-button
|
||||
:loading="emailUpdateService.loading"
|
||||
@click="updateEmail()"
|
||||
class="is-fullwidth mt-4">
|
||||
Save
|
||||
</x-button>
|
||||
</card>
|
||||
|
||||
<!-- General -->
|
||||
<div class="card update-name">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">
|
||||
General Settings
|
||||
</p>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<div class="content">
|
||||
<div class="field">
|
||||
<label class="label" for="newName">Name</label>
|
||||
<div class="control">
|
||||
<input
|
||||
@keyup.enter="updateSettings"
|
||||
class="input"
|
||||
id="newName"
|
||||
placeholder="The new name"
|
||||
type="text"
|
||||
v-model="settings.name"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" v-model="settings.emailRemindersEnabled"/>
|
||||
Send me Reminders for tasks via Email
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="bigbuttons">
|
||||
<button :class="{ 'is-loading': userSettingsService.loading}" @click="updateSettings()"
|
||||
class="button is-primary is-fullwidth">
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
<card title="General Settings" class="general-settings">
|
||||
<div class="field">
|
||||
<label class="label" for="newName">Name</label>
|
||||
<div class="control">
|
||||
<input
|
||||
@keyup.enter="updateSettings"
|
||||
class="input"
|
||||
id="newName"
|
||||
placeholder="The new name"
|
||||
type="text"
|
||||
v-model="settings.name"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" v-model="settings.emailRemindersEnabled"/>
|
||||
Send me Reminders for tasks via Email
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<x-button
|
||||
:loading="userSettingsService.loading"
|
||||
@click="updateSettings()"
|
||||
class="is-fullwidth mt-4"
|
||||
>
|
||||
Save
|
||||
</x-button>
|
||||
</card>
|
||||
|
||||
<!-- Avatar -->
|
||||
<avatar-settings/>
|
||||
|
||||
<!-- TOTP -->
|
||||
<div class="card" v-if="totpEnabled">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">
|
||||
Two Factor Authentication
|
||||
<card title="Two Factor Authentication" v-if="totpEnabled">
|
||||
<x-button
|
||||
:loading="totpService.loading"
|
||||
@click="totpEnroll()"
|
||||
v-if="!totpEnrolled && totp.secret === ''">
|
||||
Enroll
|
||||
</x-button>
|
||||
<template v-else-if="totp.secret !== '' && !totp.enabled">
|
||||
<p>
|
||||
To finish your setup, use this secret in your totp app (Google Authenticator or similar):
|
||||
<strong>{{ totp.secret }}</strong><br/>
|
||||
After that, enter a code from your app below.
|
||||
</p>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<a
|
||||
:class="{ 'is-loading': totpService.loading }"
|
||||
@click="totpEnroll()"
|
||||
class="button is-primary"
|
||||
v-if="!totpEnrolled && totp.secret === ''">
|
||||
Enroll
|
||||
</a>
|
||||
<div class="content" v-else-if="totp.secret !== '' && !totp.enabled">
|
||||
<p>
|
||||
To finish your setup, use this secret in your totp app (Google Authenticator or similar):
|
||||
<strong>{{ totp.secret }}</strong><br/>
|
||||
After that, enter a code from your app below.
|
||||
</p>
|
||||
<p>
|
||||
Alternatively you can scan this QR code:<br/>
|
||||
<img :src="totpQR" alt=""/>
|
||||
</p>
|
||||
<p>
|
||||
Alternatively you can scan this QR code:<br/>
|
||||
<img :src="totpQR" alt=""/>
|
||||
</p>
|
||||
<div class="field">
|
||||
<label class="label" for="totpConfirmPasscode">Passcode</label>
|
||||
<div class="control">
|
||||
<input
|
||||
@keyup.enter="totpConfirm()"
|
||||
class="input"
|
||||
id="totpConfirmPasscode"
|
||||
placeholder="A code generated by your totp application"
|
||||
type="text"
|
||||
v-model="totpConfirmPasscode"/>
|
||||
</div>
|
||||
</div>
|
||||
<x-button @click="totpConfirm()">Confirm</x-button>
|
||||
</template>
|
||||
<template v-else-if="totp.secret !== '' && totp.enabled">
|
||||
<p>
|
||||
You've sucessfully set up two factor authentication!
|
||||
</p>
|
||||
<p v-if="!totpDisableForm">
|
||||
<x-button @click="totpDisableForm = true" class="is-danger">Disable</x-button>
|
||||
</p>
|
||||
<div v-if="totpDisableForm">
|
||||
<div class="field">
|
||||
<label class="label" for="totpConfirmPasscode">Passcode</label>
|
||||
<label class="label" for="currentPassword">Please Enter Your Password</label>
|
||||
<div class="control">
|
||||
<input
|
||||
@keyup.enter="totpConfirm()"
|
||||
@keyup.enter="totpDisable"
|
||||
class="input"
|
||||
id="totpConfirmPasscode"
|
||||
placeholder="A code generated by your totp application"
|
||||
type="text"
|
||||
v-model="totpConfirmPasscode"/>
|
||||
id="currentPassword"
|
||||
placeholder="Your current password"
|
||||
type="password"
|
||||
v-focus
|
||||
v-model="totpDisablePassword"/>
|
||||
</div>
|
||||
</div>
|
||||
<a @click="totpConfirm()" class="button is-primary">Confirm</a>
|
||||
<x-button @click="totpDisable()" class="is-danger">Disable two factor authentication</x-button>
|
||||
</div>
|
||||
<div class="content" v-else-if="totp.secret !== '' && totp.enabled">
|
||||
<p>
|
||||
You've sucessfully set up two factor authentication!
|
||||
</p>
|
||||
<p v-if="!totpDisableForm">
|
||||
<a @click="totpDisableForm = true" class="button is-danger">Disable</a>
|
||||
</p>
|
||||
<div v-if="totpDisableForm">
|
||||
<div class="field">
|
||||
<label class="label" for="currentPassword">Please Enter Your Password</label>
|
||||
<div class="control">
|
||||
<input
|
||||
@keyup.enter="totpDisable"
|
||||
class="input"
|
||||
id="currentPassword"
|
||||
placeholder="Your current password"
|
||||
type="password"
|
||||
v-focus
|
||||
v-model="totpDisablePassword"/>
|
||||
</div>
|
||||
</div>
|
||||
<a @click="totpDisable()" class="button is-danger">Disable two factor authentication</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</card>
|
||||
|
||||
<!-- Migration -->
|
||||
<div class="card" v-if="migratorsEnabled">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">
|
||||
Migrate from other services to Vikunja
|
||||
</p>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<router-link
|
||||
:to="{name: 'migrate.start'}"
|
||||
class="button is-primary"
|
||||
v-if="migratorsEnabled"
|
||||
>
|
||||
Import your data into Vikunja
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
<card title="Migrate from other services to Vikunja" v-if="migratorsEnabled">
|
||||
<x-button
|
||||
:to="{name: 'migrate.start'}"
|
||||
>
|
||||
Import your data into Vikunja
|
||||
</x-button>
|
||||
</card>
|
||||
|
||||
<!-- Caldav -->
|
||||
<div class="card" v-if="caldavEnabled">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">
|
||||
Caldav
|
||||
</p>
|
||||
</header>
|
||||
<div class="card-content content">
|
||||
<p>
|
||||
You can connect Vikunja to caldav clients to view and manage all tasks from different clients.
|
||||
Enter this url into your client:
|
||||
</p>
|
||||
<div class="field has-addons no-input-mobile">
|
||||
<div class="control is-expanded">
|
||||
<input type="text" v-model="caldavUrl" class="input" readonly/>
|
||||
</div>
|
||||
<div class="control">
|
||||
<a @click="copy(caldavUrl)" class="button is-primary has-no-shadow" v-tooltip="'Copy to clipboard'">
|
||||
<span class="icon">
|
||||
<icon icon="paste"/>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<card v-if="caldavEnabled" title="Caldav">
|
||||
<p>
|
||||
You can connect Vikunja to caldav clients to view and manage all tasks from different clients.
|
||||
Enter this url into your client:
|
||||
</p>
|
||||
<div class="field has-addons no-input-mobile">
|
||||
<div class="control is-expanded">
|
||||
<input type="text" v-model="caldavUrl" class="input" readonly/>
|
||||
</div>
|
||||
<div class="control">
|
||||
<x-button
|
||||
@click="copy(caldavUrl)"
|
||||
:shadow="false"
|
||||
v-tooltip="'Copy to clipboard'"
|
||||
icon="paste"
|
||||
/>
|
||||
</div>
|
||||
<p>
|
||||
<a href="https://vikunja.io/docs/caldav/" target="_blank">
|
||||
More information about caldav in Vikunja
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
<a href="https://vikunja.io/docs/caldav/" target="_blank">
|
||||
More information about caldav in Vikunja
|
||||
</a>
|
||||
</p>
|
||||
</card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
Reference in New Issue
Block a user