commit
ab48f173b3
|
@ -1,9 +1,11 @@
|
|||
name: 'deploy'
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- feature/sse-connect
|
||||
- dev
|
||||
- feature/email-templates
|
||||
|
||||
jobs:
|
||||
test:
|
||||
|
@ -26,24 +28,40 @@ jobs:
|
|||
update_mailgun_template:
|
||||
runs-on: ubuntu-latest
|
||||
name: Update templates on Mailgun
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/feature/email-templates'
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: update authorizer_password_reset
|
||||
uses: jlepocher/mailgun-create-template-version-action@v1.3
|
||||
with:
|
||||
mailgun-host: 'api.eu.mailgun.net'
|
||||
mailgun-api-key: ${{ secrets.MAILGUN_API_KEY }}
|
||||
mailgun-domain-name: 'discours.io'
|
||||
mailgun-template-name: 'authorizer_password_reset'
|
||||
html-file-path: './templates/authorizer_password_reset.html'
|
||||
|
||||
- name: update authorizer_password_reset
|
||||
uses: jlepocher/mailgun-create-template-version-action@v1.3
|
||||
- name: "Email confirmation template"
|
||||
uses: gyto/mailgun-template-action@v2
|
||||
with:
|
||||
mailgun-host: 'api.eu.mailgun.net'
|
||||
html-file: "./templates/authorizer_email_confirmation.html"
|
||||
mailgun-api-key: ${{ secrets.MAILGUN_API_KEY }}
|
||||
mailgun-domain-name: 'discours.io'
|
||||
mailgun-template-name: 'authorizer_email_confirm'
|
||||
html-file-path: './templates/authorizer_email_confirm.html'
|
||||
mailgun-domain: "discours.io"
|
||||
mailgun-template: "authorizer_email_confirmation"
|
||||
|
||||
- name: "Password reset template"
|
||||
uses: gyto/mailgun-template-action@v2
|
||||
with:
|
||||
html-file: "./templates/authorizer_password_reset.html"
|
||||
mailgun-api-key: ${{ secrets.MAILGUN_API_KEY }}
|
||||
mailgun-domain: "discours.io"
|
||||
mailgun-template: "authorizer_password_reset"
|
||||
|
||||
- name: "First publication notification"
|
||||
uses: gyto/mailgun-template-action@v2
|
||||
with:
|
||||
html-file: "./templates/first_publication_notification.html"
|
||||
mailgun-api-key: ${{ secrets.MAILGUN_API_KEY }}
|
||||
mailgun-domain: "discours.io"
|
||||
mailgun-template: "first_publication_notification"
|
||||
|
||||
- name: "New comment notification template"
|
||||
uses: gyto/mailgun-template-action@v2
|
||||
with:
|
||||
html-file: "./templates/new_comment_notification.html"
|
||||
mailgun-api-key: ${{ secrets.MAILGUN_API_KEY }}
|
||||
mailgun-domain: "discours.io"
|
||||
mailgun-template: "new_comment_notification"
|
||||
|
|
|
@ -8,7 +8,6 @@ import { useMediaQuery } from '../../../context/mediaQuery'
|
|||
import { useSession } from '../../../context/session'
|
||||
import { Author, FollowingEntity } from '../../../graphql/schema/core.gen'
|
||||
import { router, useRouter } from '../../../stores/router'
|
||||
import { resetSortedArticles } from '../../../stores/zine/articles'
|
||||
import { isCyrillic } from '../../../utils/cyrillic'
|
||||
import { translit } from '../../../utils/ru2en'
|
||||
import { Button } from '../../_shared/Button'
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import type { AuthModalSearchParams } from './types'
|
||||
|
||||
import { ApiResponse, ForgotPasswordResponse } from '@authorizerdev/authorizer-js'
|
||||
import { clsx } from 'clsx'
|
||||
import { createSignal, JSX, Show } from 'solid-js'
|
||||
|
||||
|
@ -67,6 +66,7 @@ export const ForgotPasswordForm = () => {
|
|||
if (errors && errors.some((error) => error.message.includes('bad user credentials'))) {
|
||||
setIsUserNotFound(true)
|
||||
}
|
||||
if (data.message) setMessage(data.message)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
} finally {
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import type { AuthModalSearchParams } from './types'
|
||||
|
||||
import { clsx } from 'clsx'
|
||||
import { createEffect, createSignal, Show } from 'solid-js'
|
||||
import { createSignal, Show } from 'solid-js'
|
||||
|
||||
import { useLocalize } from '../../../context/localize'
|
||||
import { useSession } from '../../../context/session'
|
||||
import { useSnackbar } from '../../../context/snackbar'
|
||||
import { ApiError } from '../../../graphql/error'
|
||||
import { useRouter } from '../../../stores/router'
|
||||
import { hideModal } from '../../../stores/ui'
|
||||
import { validateEmail } from '../../../utils/validateEmail'
|
||||
|
|
|
@ -55,6 +55,7 @@ export const SearchModal = () => {
|
|||
>(
|
||||
async () => {
|
||||
setIsLoading(true)
|
||||
saveScrollPosition()
|
||||
const { hasMore, newShouts } = await loadShoutsSearch({
|
||||
limit: FEED_PAGE_SIZE,
|
||||
text: inputValue(),
|
||||
|
|
|
@ -128,7 +128,7 @@ export const AuthorView = (props: Props) => {
|
|||
const data = await apiClient.getReactionsBy({
|
||||
by: { comment: false, created_by: commenter.id },
|
||||
})
|
||||
console.debug(`[components.Author] fetched ${data.length} comments`)
|
||||
console.debug(`[components.Author] fetched comments`, data)
|
||||
setCommented(data)
|
||||
}
|
||||
|
||||
|
|
|
@ -22,8 +22,8 @@ export const DraftsView = () => {
|
|||
}
|
||||
}
|
||||
|
||||
createEffect(async () => {
|
||||
if (isSessionLoaded()) await loadDrafts()
|
||||
createEffect(() => {
|
||||
if (isSessionLoaded()) loadDrafts()
|
||||
})
|
||||
|
||||
const {
|
||||
|
@ -32,7 +32,9 @@ export const DraftsView = () => {
|
|||
|
||||
const handleDraftDelete = async (shout: Shout) => {
|
||||
const result = deleteShout(shout.id)
|
||||
if (result) await loadDrafts()
|
||||
if (result) {
|
||||
setDrafts((ddd) => ddd.filter((d) => d.id !== shout.id))
|
||||
}
|
||||
}
|
||||
|
||||
const handleDraftPublish = (shout: Shout) => {
|
||||
|
|
|
@ -21,6 +21,7 @@ import { Editor, Panel } from '../Editor'
|
|||
import { AudioUploader } from '../Editor/AudioUploader'
|
||||
import { AutoSaveNotice } from '../Editor/AutoSaveNotice'
|
||||
import { VideoUploader } from '../Editor/VideoUploader'
|
||||
import { Modal } from '../Nav/Modal'
|
||||
import { TableOfContents } from '../TableOfContents'
|
||||
|
||||
import { PublishSettings } from './PublishSettings'
|
||||
|
@ -413,7 +414,10 @@ export const EditView = (props: Props) => {
|
|||
<PublishSettings shoutId={props.shout.id} form={form} />
|
||||
</Show>
|
||||
<Panel shoutId={props.shout.id} />
|
||||
|
||||
<Modal variant="medium" name="inviteCoauthors">
|
||||
<InviteMembers variant={'coauthors'} title={t('Invite experts')} />
|
||||
</Modal>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ import { AuthorBadge } from '../../Author/AuthorBadge'
|
|||
import { AuthorLink } from '../../Author/AuthorLink'
|
||||
import { ArticleCard } from '../../Feed/ArticleCard'
|
||||
import { Sidebar } from '../../Feed/Sidebar'
|
||||
import { Modal } from '../../Nav/Modal'
|
||||
|
||||
import styles from './Feed.module.scss'
|
||||
import stylesBeside from '../../Feed/Beside.module.scss'
|
||||
|
@ -439,7 +440,10 @@ export const FeedView = (props: Props) => {
|
|||
shareUrl={getShareUrl({ pathname: `/${shareData().slug}` })}
|
||||
/>
|
||||
</Show>
|
||||
<InviteMembers title={t('Invite experts')} variant={'coauthors'} />
|
||||
|
||||
<Modal variant="medium" name="inviteCoauthors">
|
||||
<InviteMembers variant={'coauthors'} title={t('Invite experts')} />
|
||||
</Modal>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { getPagePath } from '@nanostores/router'
|
||||
import { batch, createEffect, createMemo, createSignal, For, onMount, Show } from 'solid-js'
|
||||
import { batch, createMemo, createSignal, For, onMount, Show } from 'solid-js'
|
||||
|
||||
import { useFollowing } from '../../context/following'
|
||||
import { useLocalize } from '../../context/localize'
|
||||
import { apiClient } from '../../graphql/client/core'
|
||||
import { Shout, Topic } from '../../graphql/schema/core.gen'
|
||||
|
|
|
@ -19,6 +19,7 @@ import DialogHeader from '../../Inbox/DialogHeader'
|
|||
import { Message } from '../../Inbox/Message'
|
||||
import MessagesFallback from '../../Inbox/MessagesFallback'
|
||||
import Search from '../../Inbox/Search'
|
||||
import { Modal } from '../../Nav/Modal'
|
||||
|
||||
import styles from './Inbox.module.scss'
|
||||
|
||||
|
@ -181,7 +182,9 @@ export const InboxView = (props: Props) => {
|
|||
|
||||
return (
|
||||
<div class={clsx('container', styles.Inbox)}>
|
||||
<Modal variant="medium" name="inviteMembers">
|
||||
<InviteMembers title={t('Create Chat')} variant={'recipients'} />
|
||||
</Modal>
|
||||
{/*<CreateModalContent users={recipients()} />*/}
|
||||
<div class={clsx('row', styles.row)}>
|
||||
<div class={clsx(styles.chatList, 'col-md-8')}>
|
||||
|
|
|
@ -8,7 +8,6 @@ import { Author } from '../../../graphql/schema/core.gen'
|
|||
import { hideModal } from '../../../stores/ui'
|
||||
import { useAuthorsStore } from '../../../stores/zine/authors'
|
||||
import { AuthorBadge } from '../../Author/AuthorBadge'
|
||||
import { Modal } from '../../Nav/Modal'
|
||||
import { Button } from '../Button'
|
||||
import { DropdownSelect } from '../DropdownSelect'
|
||||
import { Loading } from '../Loading'
|
||||
|
|
|
@ -8,6 +8,7 @@ import { createStore, SetStoreFunction } from 'solid-js/store'
|
|||
import { apiClient } from '../graphql/client/core'
|
||||
import { Topic, TopicInput } from '../graphql/schema/core.gen'
|
||||
import { router, useRouter } from '../stores/router'
|
||||
import { addArticles } from '../stores/zine/articles'
|
||||
import { slugify } from '../utils/slugify'
|
||||
|
||||
import { useLocalize } from './localize'
|
||||
|
@ -122,20 +123,11 @@ export const EditorProvider = (props: { children: JSX.Element }) => {
|
|||
|
||||
const updateShout = async (formToUpdate: ShoutForm, { publish }: { publish: boolean }) => {
|
||||
return await apiClient.updateArticle({
|
||||
shoutId: formToUpdate.shoutId,
|
||||
shoutInput: {
|
||||
body: formToUpdate.body,
|
||||
shout_id: formToUpdate.shoutId,
|
||||
shout_input: {
|
||||
...formToUpdate,
|
||||
topics: formToUpdate.selectedTopics.map((topic) => topic2topicInput(topic)), // NOTE: first is main
|
||||
// authors?: InputMaybe<Array<InputMaybe<Scalars['String']>>>
|
||||
// community?: InputMaybe<Scalars['Int']>
|
||||
// mainTopic: topic2topicInput(formToUpdate.mainTopic),
|
||||
slug: formToUpdate.slug,
|
||||
subtitle: formToUpdate.subtitle,
|
||||
title: formToUpdate.title,
|
||||
lead: formToUpdate.lead,
|
||||
description: formToUpdate.description,
|
||||
cover: formToUpdate.coverImageUrl,
|
||||
media: formToUpdate.media,
|
||||
},
|
||||
publish,
|
||||
})
|
||||
|
@ -204,13 +196,13 @@ export const EditorProvider = (props: { children: JSX.Element }) => {
|
|||
}
|
||||
}
|
||||
|
||||
const publishShoutById = async (shoutId: number) => {
|
||||
const publishShoutById = async (shout_id: number) => {
|
||||
try {
|
||||
await apiClient.updateArticle({
|
||||
shoutId,
|
||||
const newShout = await apiClient.updateArticle({
|
||||
shout_id,
|
||||
publish: true,
|
||||
})
|
||||
|
||||
addArticles([newShout])
|
||||
openPage(router, 'feed')
|
||||
} catch (error) {
|
||||
console.error('[publishShoutById]', error)
|
||||
|
@ -218,10 +210,10 @@ export const EditorProvider = (props: { children: JSX.Element }) => {
|
|||
}
|
||||
}
|
||||
|
||||
const deleteShout = async (shoutId: number) => {
|
||||
const deleteShout = async (shout_id: number) => {
|
||||
try {
|
||||
await apiClient.deleteShout({
|
||||
shoutId,
|
||||
shout_id,
|
||||
})
|
||||
return true
|
||||
} catch {
|
||||
|
|
|
@ -13,6 +13,7 @@ import type {
|
|||
QueryLoad_Shouts_SearchArgs,
|
||||
QueryLoad_Shouts_Random_TopArgs,
|
||||
Community,
|
||||
MutationDelete_ShoutArgs,
|
||||
} from '../schema/core.gen'
|
||||
|
||||
import { createGraphQLClient } from '../createGraphQLClient'
|
||||
|
@ -149,22 +150,22 @@ export const apiClient = {
|
|||
return response.data.create_shout.shout
|
||||
},
|
||||
updateArticle: async ({
|
||||
shoutId,
|
||||
shoutInput,
|
||||
shout_id,
|
||||
shout_input,
|
||||
publish,
|
||||
}: {
|
||||
shoutId: number
|
||||
shoutInput?: ShoutInput
|
||||
shout_id: number
|
||||
shout_input?: ShoutInput
|
||||
publish: boolean
|
||||
}): Promise<Shout> => {
|
||||
const response = await apiClient.private
|
||||
.mutation(updateArticle, { shoutId, shoutInput, publish })
|
||||
.mutation(updateArticle, { shout_id, shout_input, publish })
|
||||
.toPromise()
|
||||
console.debug('[graphql.client.core] updateArticle:', response.data)
|
||||
return response.data.update_shout.shout
|
||||
},
|
||||
deleteShout: async ({ shoutId }: { shoutId: number }): Promise<void> => {
|
||||
const response = await apiClient.private.mutation(deleteShout, { shout_id: shoutId }).toPromise()
|
||||
deleteShout: async (params: MutationDelete_ShoutArgs): Promise<void> => {
|
||||
const response = await apiClient.private.mutation(deleteShout, params).toPromise()
|
||||
console.debug('[graphql.client.core] deleteShout:', response)
|
||||
},
|
||||
getDrafts: async (): Promise<Shout[]> => {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { gql } from '@urql/core'
|
||||
|
||||
export default gql`
|
||||
mutation DeleteShoutMutation($shoutId: Int!) {
|
||||
delete_shout(shout_id: $shoutId) {
|
||||
mutation DeleteShoutMutation($shout_id: Int!) {
|
||||
delete_shout(shout_id: $shout_id) {
|
||||
error
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { gql } from '@urql/core'
|
||||
|
||||
export default gql`
|
||||
mutation UpdateShoutMutation($shoutId: Int!, $shoutInput: ShoutInput, $publish: Boolean) {
|
||||
update_shout(shout_id: $shoutId, shout_input: $shoutInput, publish: $publish) {
|
||||
mutation UpdateShoutMutation($shout_id: Int!, $shout_input: ShoutInput, $publish: Boolean) {
|
||||
update_shout(shout_id: $shout_id, shout_input: $shout_input, publish: $publish) {
|
||||
error
|
||||
shout {
|
||||
id
|
||||
|
@ -12,7 +12,10 @@ export default gql`
|
|||
lead
|
||||
description
|
||||
body
|
||||
visibility
|
||||
created_at
|
||||
updated_at
|
||||
published_at
|
||||
featured_at
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ export default gql`
|
|||
id
|
||||
kind
|
||||
body
|
||||
range
|
||||
reply_to
|
||||
shout {
|
||||
id
|
||||
|
|
|
@ -64,12 +64,14 @@ const topCommentedArticles = createLazyMemo(() => {
|
|||
})
|
||||
|
||||
// eslint-disable-next-line sonarjs/cognitive-complexity
|
||||
const addArticles = (...args: Shout[][]) => {
|
||||
export const addArticles = (...args: Shout[][]) => {
|
||||
const allArticles = args.flatMap((articles) => articles || [])
|
||||
|
||||
const newArticleEntities = allArticles.reduce(
|
||||
(acc, article) => {
|
||||
if (!acc[article.slug]) {
|
||||
acc[article.slug] = article
|
||||
}
|
||||
return acc
|
||||
},
|
||||
{} as { [articleSLug: string]: Shout },
|
||||
|
|
Loading…
Reference in New Issue
Block a user