summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/static_site_editor/pages/home.vue
blob: eef2bd88f0ea8ea040d4157217c71cb2f42d39e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
<script>
import SkeletonLoader from '../components/skeleton_loader.vue';
import EditArea from '../components/edit_area.vue';
import InvalidContentMessage from '../components/invalid_content_message.vue';
import SubmitChangesError from '../components/submit_changes_error.vue';
import appDataQuery from '../graphql/queries/app_data.query.graphql';
import sourceContentQuery from '../graphql/queries/source_content.query.graphql';
import submitContentChangesMutation from '../graphql/mutations/submit_content_changes.mutation.graphql';
import { deprecatedCreateFlash as createFlash } from '~/flash';
import Tracking from '~/tracking';
import { LOAD_CONTENT_ERROR, TRACKING_ACTION_INITIALIZE_EDITOR } from '../constants';
import { SUCCESS_ROUTE } from '../router/constants';

export default {
  components: {
    SkeletonLoader,
    EditArea,
    InvalidContentMessage,
    SubmitChangesError,
  },
  apollo: {
    appData: {
      query: appDataQuery,
    },
    sourceContent: {
      query: sourceContentQuery,
      update: ({
        project: {
          file: { title, content },
        },
      }) => {
        return { title, content };
      },
      variables() {
        return {
          project: this.appData.project,
          sourcePath: this.appData.sourcePath,
        };
      },
      skip() {
        return !this.appData.isSupportedContent;
      },
      error() {
        createFlash(LOAD_CONTENT_ERROR);
      },
    },
  },
  data() {
    return {
      content: null,
      submitChangesError: null,
      isSavingChanges: false,
    };
  },
  computed: {
    isLoadingContent() {
      return this.$apollo.queries.sourceContent.loading;
    },
    isContentLoaded() {
      return Boolean(this.sourceContent);
    },
  },
  mounted() {
    Tracking.event(document.body.dataset.page, TRACKING_ACTION_INITIALIZE_EDITOR);
  },
  methods: {
    onDismissError() {
      this.submitChangesError = null;
    },
    onSubmit({ content, images }) {
      this.content = content;
      this.submitChanges(images);
    },
    submitChanges(images) {
      this.isSavingChanges = true;

      this.$apollo
        .mutate({
          mutation: submitContentChangesMutation,
          variables: {
            input: {
              project: this.appData.project,
              username: this.appData.username,
              sourcePath: this.appData.sourcePath,
              content: this.content,
              images,
            },
          },
        })
        .then(() => {
          this.$router.push(SUCCESS_ROUTE);
        })
        .catch(e => {
          this.submitChangesError = e.message;
        })
        .finally(() => {
          this.isSavingChanges = false;
        });
    },
  },
};
</script>
<template>
  <div class="container d-flex gl-flex-direction-column pt-2 h-100">
    <template v-if="appData.isSupportedContent">
      <skeleton-loader v-if="isLoadingContent" class="w-75 gl-align-self-center gl-mt-5" />
      <submit-changes-error
        v-if="submitChangesError"
        :error="submitChangesError"
        @retry="submitChanges"
        @dismiss="onDismissError"
      />
      <edit-area
        v-if="isContentLoaded"
        :title="sourceContent.title"
        :content="sourceContent.content"
        :saving-changes="isSavingChanges"
        :return-url="appData.returnUrl"
        @submit="onSubmit"
      />
    </template>

    <invalid-content-message v-else class="w-75" />
  </div>
</template>