Skip to content
This repository has been archived by the owner on Jun 26, 2024. It is now read-only.

Commit

Permalink
feat(proposals): take a proposal back to drafts for modifications
Browse files Browse the repository at this point in the history
  • Loading branch information
vhf committed Dec 16, 2019
1 parent af832ce commit 73bbfb6
Show file tree
Hide file tree
Showing 10 changed files with 197 additions and 12 deletions.
2 changes: 1 addition & 1 deletion apollo/queries/userDrafts.gql
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
query UserDrafts ($authorId: Int!) {
proposals: allThreads (condition: {authorId: $authorId, threadType: PROPOSAL, isDraft: true, status: OPEN}) {
proposals: allThreads (condition: {authorId: $authorId, threadType: PROPOSAL, isDraft: true}) {
drafts: nodes {
id,
headline,
Expand Down
5 changes: 5 additions & 0 deletions assets/themes/zazuko/layouts/_layout-proposal.scss
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,11 @@
}
}

.proposal-edit {
@extend .proposal-submit;
margin-top: calc(1.5rem - 2.5em);
}

.proposal-author-img {
width: 40px; height: 40px;

Expand Down
7 changes: 7 additions & 0 deletions components/layout/ActivityLog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@
{{ item.thread.headline }}
</nuxt-link>
</span>
<span v-else-if="item.actionType === 'PROPOSAL_EDIT'">
edited the proposal
<nuxt-link :to="{ name: 'proposal-id', params: { id: item.thread.id } }">
{{ item.thread.headline }}
</nuxt-link>
</span>
<span v-else-if="item.actionType === 'PROPOSAL_ACCEPT'">
accepted the proposal
<nuxt-link :to="{ name: 'proposal-id', params: { id: item.thread.id } }">
Expand Down Expand Up @@ -104,6 +110,7 @@ import Close from 'vue-material-design-icons/Close.vue'
const actionTypes = [
'PROPOSAL_SUBMIT',
'PROPOSAL_EDIT',
'PROPOSAL_ACCEPT',
'PROPOSAL_REJECT',
'CONVERSATION_CREATE',
Expand Down
50 changes: 43 additions & 7 deletions pages/proposal/_id.vue
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,18 @@
</property-form>
<div v-else />

<div
v-show="isProposalAuthor && !isDraft"
class="columns proposal-edit">
<p class="column">
<button
class="button submit-proposal"
@click="editProposal">
Edit Proposal
</button>
</p>
</div>

<h1
id="conversation"
class="title is-2 conversation-title">
Expand All @@ -119,21 +131,23 @@
:discussion="discussion"
@refreshDiscussion="refreshDiscussion" />
</div>
<div class="discussion">
<div
v-show="$store.state.auth.loggedIn"
class="discussion">
<discussion-reply
:id="id"
@answerAdded="refreshDiscussion" />
</div>
</div>

</div>
</section>
<div
v-else>

<div v-else>
<loader :show-if="true">
<p class="subtitle">Loading Proposal</p>
</loader>
</div>

</div>
</div>
</template>
Expand All @@ -150,7 +164,7 @@ import Vote from '@/components/proposal/Vote'
import Loader from '@/components/layout/Loader'
import discussionById from '@/apollo/queries/discussionById'
import { LOAD } from '@/store/action-types'
import { EDIT, LOAD } from '@/store/action-types'
import { toastClose } from '@/libs/utils'
import { emptyDiscussion } from '@/libs/fixtures'
Expand Down Expand Up @@ -194,14 +208,22 @@ export default {
return this.$store.state[this.path]
}
return this.$deepModel(this.path)
},
isProposalAuthor () {
return this.discussion.authorId === this.$store.state.auth.personId
},
isDraft () {
return this.obj.isDraft
}
},
methods: {
...classActions({
loadClass: LOAD
loadClass: LOAD,
editClass: EDIT
}),
...propertyActions({
loadProperty: LOAD
loadProperty: LOAD,
editProperty: EDIT
}),
authorsAvatar (name = '') {
return `${name}'s avatar'`
Expand All @@ -214,6 +236,20 @@ export default {
}
})
},
async editProposal () {
if (this.type === 'Class') {
await this.editClass()
}
else {
await this.editProperty()
}
await this.$store.dispatch('drafts/LOAD')
this.$router.push({
name: `proposal-${this.type.toLowerCase()}`,
query: { id: this.id }
})
},
init () {
this.type = this.$proposalType(this.discussion.proposalObject)
let loader
Expand Down
11 changes: 11 additions & 0 deletions setup/sql/0021-new-proposal-status.no-transaction.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
-- creating a proposals now works like this:
-- * create a draft, status = initial_draft
-- submit it, status = open, etc, the rest stays the same as before:
-- reject -> rejected
-- resolve -> resolved
-- hide -> hidden

-- this allows us to trigger on proposal edits, ie.
-- we log a 'submit' when status = 'initial_draft'
-- we log an 'edit' when status = 'open'
alter type editor_schema.status add value 'initial_draft' after 'rejected';
2 changes: 2 additions & 0 deletions setup/sql/0022-proposal-edit-log-type.no-transaction.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- for the log
alter type editor_schema.action_type add value 'proposal_edit' after 'proposal_submit';
58 changes: 58 additions & 0 deletions setup/sql/0023-proposal-edit.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
-- new proposals should have the new status 'initial_draft' by default
alter table only editor_schema.thread alter column status set default 'initial_draft';

-- function used to take an open proposal back to a draft
create or replace function editor_schema.edit_proposal(
thread_id int
) returns editor_schema.thread as $$
declare thread editor_schema.thread;
begin
update editor_schema.thread
set
status = 'open'::editor_schema.status,
is_draft = true
where id = thread_id and author_id = current_setting('jwt.claims.person_id')::integer
returning * into thread;
return thread;
end;
$$ language plpgsql strict security definer;
comment on function editor_schema.edit_proposal(int) is E'Edit a proposal, restricted to proposal author.';
grant execute on function editor_schema.edit_proposal(int) to $POSTGRESQL_ROLE_PERSON;

-- change submit log proposal trigger
drop trigger proposal_submit_logger on editor_schema.thread;
create trigger proposal_submit_logger
after update on editor_schema.thread
for each row
when (
NEW.thread_type = 'proposal'::editor_schema.thread_type and
NEW.status = 'open'::editor_schema.status and
OLD.status = 'initial_draft'::editor_schema.status and
OLD.external_id is null and
OLD.is_draft = true and
NEW.is_draft = false
)
execute procedure editor_private_schema.tg_log__proposal_submit();
-- new trigger to log proposal edits
create function editor_private_schema.tg_log__proposal_edit()
returns trigger as $$
begin
insert into editor_schema.log
(author_id, thread_id, action_type, event_date)
values
(NEW.author_id, NEW.id, 'proposal_edit', NEW.updated_at);
return NEW;
end;
$$ language plpgsql;
create trigger proposal_edit_logger
after update on editor_schema.thread
for each row
when (
NEW.thread_type = 'proposal'::editor_schema.thread_type and
NEW.status = 'open'::editor_schema.status and
OLD.status = 'open'::editor_schema.status and
OLD.external_id is null and
OLD.is_draft = true and
NEW.is_draft = false
)
execute procedure editor_private_schema.tg_log__proposal_edit();
2 changes: 2 additions & 0 deletions store/action-types.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export const NEW = 'NEW'
export const SAVE = 'SAVE'
export const SUBMIT = 'SUBMIT'
export const EDIT = 'EDIT'
export const APPROVE = 'APPROVE'
export const LOAD = 'LOAD'
export const LOAD_CONFIG = 'LOAD_CONFIG'
export const DESERIALIZE = 'DESERIALIZE'
Expand Down
36 changes: 34 additions & 2 deletions store/class.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import rdf from 'rdf-ext'

import proposalById from '@/apollo/queries/proposalById'

import { SAVE, SUBMIT, NEW, LOAD } from '@/store/action-types'
import { APPROVE, LOAD, EDIT, NEW, SAVE, SUBMIT } from '@/store/action-types'
import { SET_ID, ERROR, SUCCESS } from '@/store/mutation-types'

export const state = () => ({
Expand Down Expand Up @@ -46,6 +46,9 @@ export const mutations = VueDeepSet.extendMutation({
},
[LOAD] (state, clss) {
state.clss = clss
},
[EDIT] (state) {
state.clss.isDraft = true
}
})

Expand Down Expand Up @@ -161,7 +164,36 @@ export const actions = {
}
},

async APPROVE ({ dispatch, commit, state, rootState }, { threadId, token }) {
async [EDIT] ({ commit, dispatch, state }) {
try {
const threadId = state.clss.threadId
commit(EDIT)
await dispatch(SAVE)

const mutation = gql`
mutation ($threadId: Int!) {
editProposal (input: {
threadId: $threadId
}) {
thread {
id
}
}
}
`
const variables = { threadId }
await this.app.apolloProvider.defaultClient.mutate({
mutation,
variables
})
await dispatch(LOAD, threadId)
}
catch (err) {
console.error(err)
}
},

async [APPROVE] ({ dispatch, commit, state, rootState }, { threadId, token }) {
await dispatch(LOAD, threadId)
try {
const classProposalData = state.clss.generateProposal({
Expand Down
36 changes: 34 additions & 2 deletions store/prop.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import rdf from 'rdf-ext'

import proposalById from '@/apollo/queries/proposalById'

import { SAVE, SUBMIT, NEW, LOAD } from '@/store/action-types'
import { APPROVE, LOAD, EDIT, NEW, SAVE, SUBMIT } from '@/store/action-types'
import { SET_ID, ERROR, SUCCESS } from '@/store/mutation-types'

export const state = () => ({
Expand Down Expand Up @@ -46,6 +46,9 @@ export const mutations = VueDeepSet.extendMutation({
},
[LOAD] (state, prop) {
state.prop = prop
},
[EDIT] (state) {
state.prop.isDraft = true
}
})

Expand Down Expand Up @@ -153,7 +156,36 @@ export const actions = {
}
},

async APPROVE ({ dispatch, commit, state, rootState }, { threadId, token }) {
async [EDIT] ({ commit, dispatch, state }) {
try {
const threadId = state.prop.threadId
commit(EDIT)
await dispatch(SAVE)

const mutation = gql`
mutation ($threadId: Int!) {
editProposal (input: {
threadId: $threadId
}) {
thread {
id
}
}
}
`
const variables = { threadId }
await this.app.apolloProvider.defaultClient.mutate({
mutation,
variables
})
await dispatch(LOAD, threadId)
}
catch (err) {
console.error(err)
}
},

async [APPROVE] ({ dispatch, commit, state, rootState }, { threadId, token }) {
await dispatch(LOAD, threadId)
try {
const propertyProposalData = state.prop.generateProposal({
Expand Down

0 comments on commit 73bbfb6

Please sign in to comment.