@blokkli/editor 2.0.0-alpha.14 → 2.0.0-alpha.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module.json +1 -1
- package/dist/module.mjs +867 -2
- package/dist/modules/drupal/graphql/base/fragment.paragraphsBlokkliEditState.graphql +4 -0
- package/dist/modules/drupal/graphql/features/publishNew.graphql +1 -4
- package/dist/modules/drupal/graphql/features/scheduler.graphql +31 -0
- package/dist/modules/drupal/index.mjs +17 -0
- package/dist/modules/drupal/runtime/adapter/index.js +31 -1
- package/dist/runtime/adapter/index.d.ts +36 -0
- package/dist/runtime/blokkliPlugins/MenuButton/index.vue.d.ts +2 -2
- package/dist/runtime/components/Edit/Features/EntityTitle/index.vue +33 -1
- package/dist/runtime/components/Edit/Features/Publish/Dialog/Item.vue +41 -14
- package/dist/runtime/components/Edit/Features/Publish/Dialog/Item.vue.d.ts +2 -0
- package/dist/runtime/components/Edit/Features/Publish/Dialog/PublishOption.vue +47 -0
- package/dist/runtime/components/Edit/Features/Publish/Dialog/PublishOption.vue.d.ts +19 -0
- package/dist/runtime/components/Edit/Features/Publish/Dialog/ScheduleDate.vue +183 -0
- package/dist/runtime/components/Edit/Features/Publish/Dialog/ScheduleDate.vue.d.ts +13 -0
- package/dist/runtime/components/Edit/Features/Publish/Dialog/Summary.vue +83 -0
- package/dist/runtime/components/Edit/Features/Publish/Dialog/Summary.vue.d.ts +9 -0
- package/dist/runtime/components/Edit/Features/Publish/Dialog/index.vue +381 -129
- package/dist/runtime/components/Edit/Features/Publish/Dialog/index.vue.d.ts +3 -14
- package/dist/runtime/components/Edit/Features/Publish/index.vue +34 -20
- package/dist/runtime/components/Edit/Form/Datepicker/index.vue +198 -0
- package/dist/runtime/components/Edit/Form/Datepicker/index.vue.d.ts +15 -0
- package/dist/runtime/components/Edit/Konami/Game/index.vue +8 -1
- package/dist/runtime/components/Edit/index.d.ts +2 -1
- package/dist/runtime/components/Edit/index.js +2 -0
- package/dist/runtime/css/output.css +1 -1
- package/dist/runtime/helpers/stateProvider.d.ts +2 -1
- package/dist/runtime/helpers/stateProvider.js +31 -0
- package/dist/runtime/helpers/uiProvider.d.ts +2 -0
- package/dist/runtime/helpers/uiProvider.js +23 -0
- package/dist/runtime/icons/calendar-clock.svg +1 -0
- package/dist/runtime/icons/eye-off.svg +1 -0
- package/dist/runtime/types/index.d.ts +9 -1
- package/package.json +1 -1
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="bk-publish-summary">
|
|
3
|
+
<!-- Current State -->
|
|
4
|
+
<div class="bk-publish-summary-state">
|
|
5
|
+
<div class="bk-publish-summary-state-icon" :class="currentStateClass">
|
|
6
|
+
<Icon :name="currentStateIcon" />
|
|
7
|
+
</div>
|
|
8
|
+
<div class="bk-publish-summary-state-label">
|
|
9
|
+
{{ currentStateLabel }}
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
<!-- Arrow -->
|
|
14
|
+
<div class="bk-publish-summary-arrow">
|
|
15
|
+
<Icon name="arrow-right" />
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
<!-- Action -->
|
|
19
|
+
<div class="bk-publish-summary-action">
|
|
20
|
+
<div class="bk-publish-summary-action-icon" :class="actionClass">
|
|
21
|
+
<Icon :name="actionIcon" />
|
|
22
|
+
</div>
|
|
23
|
+
<div class="bk-publish-summary-action-label">
|
|
24
|
+
{{ actionLabel }}
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
<!-- Arrow -->
|
|
29
|
+
<div class="bk-publish-summary-arrow">
|
|
30
|
+
<Icon name="arrow-right" />
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<!-- Result State -->
|
|
34
|
+
<div class="bk-publish-summary-state">
|
|
35
|
+
<div class="bk-publish-summary-state-icon" :class="resultStateClass">
|
|
36
|
+
<Icon :name="resultStateIcon" />
|
|
37
|
+
</div>
|
|
38
|
+
<div class="bk-publish-summary-state-label">
|
|
39
|
+
{{ resultStateLabel }}
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
</template>
|
|
44
|
+
|
|
45
|
+
<script setup>
|
|
46
|
+
import { computed } from "#imports";
|
|
47
|
+
import { Icon } from "#blokkli/components";
|
|
48
|
+
const props = defineProps({
|
|
49
|
+
isPublished: { type: Boolean, required: true },
|
|
50
|
+
mode: { type: String, required: true },
|
|
51
|
+
currentStateLabel: { type: String, required: true },
|
|
52
|
+
actionLabel: { type: String, required: true },
|
|
53
|
+
resultStateLabel: { type: String, required: true }
|
|
54
|
+
});
|
|
55
|
+
const currentStateIcon = computed(
|
|
56
|
+
() => props.isPublished ? "eye" : "eye-off"
|
|
57
|
+
);
|
|
58
|
+
const currentStateClass = computed(
|
|
59
|
+
() => props.isPublished ? "bk-is-published" : "bk-is-unpublished"
|
|
60
|
+
);
|
|
61
|
+
const resultStateIcon = computed(() => {
|
|
62
|
+
if (props.mode === "save") {
|
|
63
|
+
return "eye-off";
|
|
64
|
+
}
|
|
65
|
+
return "eye";
|
|
66
|
+
});
|
|
67
|
+
const resultStateClass = computed(() => {
|
|
68
|
+
if (props.mode === "save") {
|
|
69
|
+
return "bk-is-unpublished";
|
|
70
|
+
}
|
|
71
|
+
return "bk-is-published";
|
|
72
|
+
});
|
|
73
|
+
const actionIcon = computed(() => {
|
|
74
|
+
if (props.mode === "save") return "save";
|
|
75
|
+
if (props.mode === "scheduled") return "calendar-clock";
|
|
76
|
+
return "publish";
|
|
77
|
+
});
|
|
78
|
+
const actionClass = computed(() => {
|
|
79
|
+
if (props.mode === "save") return "bk-is-save";
|
|
80
|
+
if (props.mode === "scheduled") return "bk-is-scheduled";
|
|
81
|
+
return "bk-is-publish";
|
|
82
|
+
});
|
|
83
|
+
</script>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
isPublished: boolean;
|
|
3
|
+
mode: 'immediate' | 'scheduled' | 'save';
|
|
4
|
+
currentStateLabel: string;
|
|
5
|
+
actionLabel: string;
|
|
6
|
+
resultStateLabel: string;
|
|
7
|
+
};
|
|
8
|
+
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
9
|
+
export default _default;
|
|
@@ -1,117 +1,272 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<DialogModal
|
|
3
3
|
:title="$t('publishDialogTitle', 'Publish changes')"
|
|
4
|
-
:width="
|
|
4
|
+
:width="900"
|
|
5
5
|
:submit-label
|
|
6
6
|
:is-loading="isLoading"
|
|
7
|
-
:can-submit="
|
|
7
|
+
:can-submit="canSubmit"
|
|
8
8
|
class="bk-is-publish-dialog"
|
|
9
9
|
@submit="onSubmit"
|
|
10
10
|
@cancel="$emit('close')"
|
|
11
11
|
>
|
|
12
12
|
<div class="bk bk-form bk-dialog-publish-form">
|
|
13
|
-
<
|
|
14
|
-
<
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
13
|
+
<FormItem>
|
|
14
|
+
<div class="bk-form-label">
|
|
15
|
+
{{ $t("publishMode", "Publish mode")
|
|
16
|
+
}}<span class="bk-required-indicator">*</span>
|
|
17
|
+
</div>
|
|
18
|
+
<div class="bk-publish-options">
|
|
19
|
+
<PublishOption
|
|
20
|
+
v-for="option in publishModeOptions"
|
|
21
|
+
:id="option.id"
|
|
22
|
+
:key="option.id"
|
|
23
|
+
v-model="publishMode"
|
|
24
|
+
:icon="option.icon"
|
|
25
|
+
:color="option.color"
|
|
26
|
+
:label="option.label"
|
|
27
|
+
:description="option.description"
|
|
28
|
+
:disabled="option.disabled"
|
|
21
29
|
/>
|
|
22
|
-
</
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
</div>
|
|
31
|
+
</FormItem>
|
|
32
|
+
|
|
33
|
+
<FormItem v-if="publishMode === 'scheduled'">
|
|
34
|
+
<div>
|
|
35
|
+
<label class="bk-form-label">
|
|
36
|
+
{{ $t("publishScheduleDate", "Publication date") }}
|
|
37
|
+
</label>
|
|
38
|
+
<div class="bk-publish-schedule-date-wrapper">
|
|
39
|
+
<div v-if="isAlreadyScheduled" class="bk-publish-scheduled-display">
|
|
40
|
+
{{
|
|
41
|
+
ui.formatDate(scheduleDate, {
|
|
42
|
+
weekday: "long",
|
|
43
|
+
year: "numeric",
|
|
44
|
+
month: "2-digit",
|
|
45
|
+
day: "2-digit",
|
|
46
|
+
hour: "2-digit",
|
|
47
|
+
minute: "2-digit"
|
|
48
|
+
})
|
|
49
|
+
}}
|
|
50
|
+
</div>
|
|
51
|
+
<ScheduleDate
|
|
52
|
+
v-else
|
|
53
|
+
v-model="scheduleDate"
|
|
54
|
+
:disabled="isLoading"
|
|
55
|
+
:error="scheduleDateError"
|
|
56
|
+
/>
|
|
57
|
+
<button
|
|
58
|
+
v-if="isAlreadyScheduled"
|
|
59
|
+
type="button"
|
|
60
|
+
class="bk-button bk-is-danger"
|
|
61
|
+
@click="removeScheduledDate"
|
|
62
|
+
>
|
|
63
|
+
{{ $t("publishRemoveSchedule", "Remove schedule") }}
|
|
64
|
+
</button>
|
|
65
|
+
</div>
|
|
66
|
+
<div v-if="isAlreadyScheduled" class="bk-form-description">
|
|
67
|
+
{{
|
|
68
|
+
$t(
|
|
69
|
+
"publishAlreadyScheduledDescription",
|
|
70
|
+
"This page is already scheduled for publishing"
|
|
71
|
+
)
|
|
72
|
+
}}
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
</FormItem>
|
|
76
|
+
|
|
77
|
+
<FormItem v-if="publishOptions?.hasRevisionLogMessage">
|
|
78
|
+
<FormTextarea
|
|
79
|
+
id="revision-message"
|
|
80
|
+
v-model="revisionMessage"
|
|
81
|
+
:label="$t('publishRevisionLogMessage', 'Revision log message')"
|
|
82
|
+
:description="
|
|
83
|
+
$t(
|
|
84
|
+
'publishRevisionLogMessageDescription',
|
|
85
|
+
'Briefly describe the changes made'
|
|
86
|
+
)
|
|
87
|
+
"
|
|
88
|
+
:disabled="isLoading || isAlreadyScheduled"
|
|
89
|
+
rows="2"
|
|
90
|
+
/>
|
|
91
|
+
</FormItem>
|
|
31
92
|
|
|
32
|
-
<
|
|
33
|
-
<
|
|
34
|
-
|
|
35
|
-
|
|
93
|
+
<FormItem v-if="successItems.length && showTable">
|
|
94
|
+
<h2 class="bk-heading-2">
|
|
95
|
+
{{ $t("publishSuccessfullyPublished", "Successfully published") }}
|
|
96
|
+
</h2>
|
|
36
97
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
98
|
+
<table class="bk-table bk-publish-dialog-table">
|
|
99
|
+
<thead>
|
|
100
|
+
<tr>
|
|
101
|
+
<th>{{ $t("publishName", "Name") }}</th>
|
|
102
|
+
<th colspan="2">{{ $t("publishStatus", "Status") }}</th>
|
|
103
|
+
</tr>
|
|
104
|
+
</thead>
|
|
44
105
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
</
|
|
106
|
+
<tbody>
|
|
107
|
+
<Item
|
|
108
|
+
v-for="item in successItems"
|
|
109
|
+
:key="'success' + item.id"
|
|
110
|
+
v-bind="item"
|
|
111
|
+
v-model="states"
|
|
112
|
+
:is-current="item.id === currentId"
|
|
113
|
+
:should-publish
|
|
114
|
+
:is-mutating
|
|
115
|
+
:mutation-status="mutationStatusItems[item.id]"
|
|
116
|
+
:is-scheduled="enableScheduling"
|
|
117
|
+
:schedule-date
|
|
118
|
+
/>
|
|
119
|
+
</tbody>
|
|
120
|
+
</table>
|
|
59
121
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
122
|
+
<table class="bk-table bk-publish-dialog-table">
|
|
123
|
+
<thead>
|
|
124
|
+
<tr>
|
|
125
|
+
<th>{{ $t("publishName", "Name") }}</th>
|
|
126
|
+
<th colspan="2">{{ $t("publishStatus", "Status") }}</th>
|
|
127
|
+
</tr>
|
|
128
|
+
</thead>
|
|
67
129
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
130
|
+
<tbody>
|
|
131
|
+
<Item
|
|
132
|
+
v-for="item in toPublishItems"
|
|
133
|
+
:key="'to_publish_' + item.id"
|
|
134
|
+
v-bind="item"
|
|
135
|
+
v-model="states"
|
|
136
|
+
:is-current="item.id === currentId"
|
|
137
|
+
:should-publish
|
|
138
|
+
:is-mutating
|
|
139
|
+
:mutation-status="mutationStatusItems[item.id]"
|
|
140
|
+
:is-scheduled="enableScheduling"
|
|
141
|
+
:schedule-date
|
|
142
|
+
/>
|
|
143
|
+
</tbody>
|
|
144
|
+
</table>
|
|
145
|
+
</FormItem>
|
|
146
|
+
<FormItem class="bk-is-summary">
|
|
147
|
+
<h3 class="bk-form-label">
|
|
148
|
+
{{ $t("publishSummary", "Summary") }}
|
|
149
|
+
</h3>
|
|
150
|
+
<Summary
|
|
151
|
+
:is-published="isCurrentlyPublished"
|
|
152
|
+
:mode="publishMode"
|
|
153
|
+
:current-state-label="currentStateLabel"
|
|
154
|
+
:action-label="actionLabel"
|
|
155
|
+
:result-state-label="resultStateLabel"
|
|
156
|
+
/>
|
|
157
|
+
</FormItem>
|
|
83
158
|
</div>
|
|
84
159
|
</DialogModal>
|
|
85
160
|
</template>
|
|
86
161
|
|
|
87
162
|
<script setup>
|
|
88
|
-
import { ref, computed, useBlokkli, useAsyncData } from "#imports";
|
|
89
163
|
import {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
164
|
+
ref,
|
|
165
|
+
computed,
|
|
166
|
+
watch,
|
|
167
|
+
useBlokkli,
|
|
168
|
+
useAsyncData,
|
|
169
|
+
onMounted,
|
|
170
|
+
onUnmounted
|
|
171
|
+
} from "#imports";
|
|
172
|
+
import { DialogModal, FormTextarea, FormItem } from "#blokkli/components";
|
|
173
|
+
import { emitMessage } from "#blokkli/helpers/eventBus";
|
|
97
174
|
import Item from "./Item.vue";
|
|
98
|
-
|
|
175
|
+
import PublishOption, {} from "./PublishOption.vue";
|
|
176
|
+
import Summary from "./Summary.vue";
|
|
177
|
+
import ScheduleDate from "./ScheduleDate.vue";
|
|
178
|
+
const showTable = false;
|
|
179
|
+
const { adapter, $t, state, context, ui } = useBlokkli();
|
|
99
180
|
const isMutating = ref(false);
|
|
100
181
|
const mutationStatusItems = ref({});
|
|
101
182
|
const publishedIds = ref([]);
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
183
|
+
const states = ref([]);
|
|
184
|
+
const revisionMessage = ref("");
|
|
185
|
+
const currentTimestamp = ref(Date.now());
|
|
186
|
+
let timestampInterval = null;
|
|
187
|
+
onMounted(() => {
|
|
188
|
+
timestampInterval = setInterval(() => {
|
|
189
|
+
currentTimestamp.value = Date.now();
|
|
190
|
+
}, 3e4);
|
|
191
|
+
});
|
|
192
|
+
onUnmounted(() => {
|
|
193
|
+
if (timestampInterval) {
|
|
194
|
+
clearInterval(timestampInterval);
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
const publishMode = ref("immediate");
|
|
111
198
|
const emit = defineEmits(["close", "submit"]);
|
|
112
|
-
const {
|
|
199
|
+
const {
|
|
200
|
+
data: publishOptions,
|
|
201
|
+
status,
|
|
202
|
+
refresh
|
|
203
|
+
} = await useAsyncData(() => {
|
|
113
204
|
return adapter.getPublishOptions();
|
|
114
205
|
});
|
|
206
|
+
const canSchedule = computed(() => !!publishOptions.value?.canSchedule);
|
|
207
|
+
const publishOn = computed(
|
|
208
|
+
() => publishOptions.value?.publishOn ?? null
|
|
209
|
+
);
|
|
210
|
+
const isAlreadyScheduled = computed(() => !!publishOn.value);
|
|
211
|
+
const isCurrentlyPublished = computed(() => !!state.entity.value?.status);
|
|
212
|
+
const publishModeOptions = computed(() => {
|
|
213
|
+
const options = [
|
|
214
|
+
{
|
|
215
|
+
id: "save",
|
|
216
|
+
icon: "save",
|
|
217
|
+
color: "red",
|
|
218
|
+
label: $t("publishModeSaveTitle", "Save"),
|
|
219
|
+
description: $t(
|
|
220
|
+
"publishModeSaveDescription",
|
|
221
|
+
"Save changes without publishing"
|
|
222
|
+
),
|
|
223
|
+
disabled: isCurrentlyPublished.value || isAlreadyScheduled.value
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
id: "immediate",
|
|
227
|
+
icon: "publish",
|
|
228
|
+
color: "lime",
|
|
229
|
+
label: $t("publishModeImmediateTitle", "Publish"),
|
|
230
|
+
description: $t(
|
|
231
|
+
"publishModeImmediateDescription",
|
|
232
|
+
"Publish changes immediately"
|
|
233
|
+
),
|
|
234
|
+
disabled: isAlreadyScheduled.value
|
|
235
|
+
}
|
|
236
|
+
];
|
|
237
|
+
if (canSchedule.value) {
|
|
238
|
+
options.push({
|
|
239
|
+
id: "scheduled",
|
|
240
|
+
icon: "calendar-clock",
|
|
241
|
+
color: "yellow",
|
|
242
|
+
label: $t("publishModeScheduledTitle", "Schedule"),
|
|
243
|
+
description: $t(
|
|
244
|
+
"publishModeScheduledDescription",
|
|
245
|
+
"Schedule changes for publishing"
|
|
246
|
+
),
|
|
247
|
+
disabled: false
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
return options;
|
|
251
|
+
});
|
|
252
|
+
const scheduleDate = ref(publishOn.value || "");
|
|
253
|
+
console.log("SET REIVISON LOG MESSAGE");
|
|
254
|
+
if (publishOptions.value?.revisionLogMessage) {
|
|
255
|
+
revisionMessage.value = publishOptions.value.revisionLogMessage;
|
|
256
|
+
}
|
|
257
|
+
if (publishOn.value) {
|
|
258
|
+
publishMode.value = "scheduled";
|
|
259
|
+
}
|
|
260
|
+
watch(publishMode, (newMode) => {
|
|
261
|
+
if (newMode === "scheduled" && !scheduleDate.value) {
|
|
262
|
+
const tomorrow = /* @__PURE__ */ new Date();
|
|
263
|
+
tomorrow.setDate(tomorrow.getDate() + 1);
|
|
264
|
+
tomorrow.setHours(12, 0, 0, 0);
|
|
265
|
+
scheduleDate.value = tomorrow.toISOString();
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
const enableScheduling = computed(() => publishMode.value === "scheduled");
|
|
269
|
+
const shouldPublish = computed(() => publishMode.value !== "save");
|
|
115
270
|
const { data: editStates } = await useAsyncData(
|
|
116
271
|
() => {
|
|
117
272
|
if (adapter.getEditStates) {
|
|
@@ -167,39 +322,127 @@ const selectedToPublishItems = computed(
|
|
|
167
322
|
)
|
|
168
323
|
);
|
|
169
324
|
const isLoading = computed(() => status.value === "pending" || isMutating.value);
|
|
170
|
-
const
|
|
171
|
-
if (
|
|
172
|
-
|
|
173
|
-
|
|
325
|
+
const scheduleDateError = computed(() => {
|
|
326
|
+
if (publishMode.value !== "scheduled" || !scheduleDate.value) {
|
|
327
|
+
return "";
|
|
328
|
+
}
|
|
329
|
+
const selectedDateTime = new Date(scheduleDate.value);
|
|
330
|
+
const minDateTime = new Date(currentTimestamp.value + 2 * 60 * 1e3);
|
|
331
|
+
if (selectedDateTime < minDateTime) {
|
|
332
|
+
return $t(
|
|
333
|
+
"publishScheduleDateTooSoon",
|
|
334
|
+
"The scheduled date must be at least 2 minutes in the future"
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
return "";
|
|
338
|
+
});
|
|
339
|
+
const canSubmit = computed(() => {
|
|
340
|
+
if (!selectedToPublishItems.value.length) {
|
|
341
|
+
return false;
|
|
342
|
+
}
|
|
343
|
+
if (publishMode.value === "scheduled" && !scheduleDate.value) {
|
|
344
|
+
return false;
|
|
174
345
|
}
|
|
175
|
-
|
|
346
|
+
if (publishMode.value === "scheduled" && isAlreadyScheduled.value) {
|
|
347
|
+
return false;
|
|
348
|
+
}
|
|
349
|
+
if (scheduleDateError.value) {
|
|
350
|
+
return false;
|
|
351
|
+
}
|
|
352
|
+
return true;
|
|
176
353
|
});
|
|
177
|
-
const
|
|
354
|
+
const submitLabel = computed(() => {
|
|
178
355
|
const count = selectedToPublishItems.value.length;
|
|
179
|
-
if (
|
|
180
|
-
if (
|
|
181
|
-
return "
|
|
356
|
+
if (publishMode.value === "scheduled") {
|
|
357
|
+
if (count === 0) {
|
|
358
|
+
return $t("publishSchedulePublication", "Schedule publication");
|
|
182
359
|
}
|
|
183
|
-
return "
|
|
360
|
+
return count === 1 ? $t("publishSchedulePublication", "Schedule publication") : $t(
|
|
361
|
+
"publishSchedulePublications",
|
|
362
|
+
"Schedule @count publications"
|
|
363
|
+
).replace("@count", count.toString());
|
|
184
364
|
}
|
|
185
|
-
if (
|
|
186
|
-
|
|
365
|
+
if (publishMode.value === "save") {
|
|
366
|
+
if (count === 0) {
|
|
367
|
+
return $t("publishSaveContent", "Save content");
|
|
368
|
+
}
|
|
369
|
+
return count === 1 ? $t("publishSaveContent", "Save content") : $t("publishSaveContents", "Save @count contents").replace(
|
|
370
|
+
"@count",
|
|
371
|
+
count.toString()
|
|
372
|
+
);
|
|
373
|
+
}
|
|
374
|
+
if (count === 0) {
|
|
375
|
+
return $t("publishPublishContent", "Publish content");
|
|
187
376
|
}
|
|
188
|
-
return
|
|
377
|
+
return count === 1 ? $t("publishPublishContent", "Publish content") : $t("publishPublishContents", "Publish @count contents").replace(
|
|
378
|
+
"@count",
|
|
379
|
+
count.toString()
|
|
380
|
+
);
|
|
189
381
|
});
|
|
190
|
-
const
|
|
191
|
-
|
|
382
|
+
const currentStateLabel = computed(
|
|
383
|
+
() => isCurrentlyPublished.value ? $t("publishCurrentlyPublished", "Page is published") : $t("publishCurrentlyUnpublished", "Page is unpublished")
|
|
384
|
+
);
|
|
385
|
+
const actionLabel = computed(() => {
|
|
386
|
+
if (publishMode.value === "save") {
|
|
387
|
+
return $t("publishModeSaveTitle", "Save");
|
|
388
|
+
}
|
|
389
|
+
if (publishMode.value === "scheduled") {
|
|
390
|
+
return $t("publishModeScheduledTitle", "Schedule");
|
|
391
|
+
}
|
|
392
|
+
return $t("publishModeImmediateTitle", "Publish");
|
|
192
393
|
});
|
|
193
|
-
const
|
|
194
|
-
if (
|
|
195
|
-
return
|
|
394
|
+
const resultStateLabel = computed(() => {
|
|
395
|
+
if (publishMode.value === "save") {
|
|
396
|
+
return $t(
|
|
397
|
+
"publishResultSaveChanges",
|
|
398
|
+
"Changes are saved, page remains unpublished"
|
|
399
|
+
);
|
|
196
400
|
}
|
|
197
|
-
|
|
401
|
+
if (publishMode.value === "scheduled" && scheduleDate.value) {
|
|
402
|
+
const formattedDate = ui.formatDate(scheduleDate.value);
|
|
403
|
+
return $t(
|
|
404
|
+
"publishResultScheduledChanges",
|
|
405
|
+
"Changes will be published on @date"
|
|
406
|
+
).replace("@date", formattedDate);
|
|
407
|
+
}
|
|
408
|
+
if (isCurrentlyPublished.value) {
|
|
409
|
+
return $t(
|
|
410
|
+
"publishResultPublishChangesRemainPublished",
|
|
411
|
+
"Changes are published, page remains published"
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
return $t(
|
|
415
|
+
"publishResultPublishChangesNowPublished",
|
|
416
|
+
"Changes are published, page is now published"
|
|
417
|
+
);
|
|
198
418
|
});
|
|
419
|
+
async function removeScheduledDate() {
|
|
420
|
+
if (!adapter.unscheduleEditState) {
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
isMutating.value = true;
|
|
424
|
+
const previousScheduleDate = scheduleDate.value;
|
|
425
|
+
const success = await state.mutateWithLoadingState(
|
|
426
|
+
() => adapter.unscheduleEditState({
|
|
427
|
+
hostEntityType: context.value.entityType,
|
|
428
|
+
hostEntityUuid: context.value.entityUuid
|
|
429
|
+
})
|
|
430
|
+
);
|
|
431
|
+
if (success) {
|
|
432
|
+
await refresh();
|
|
433
|
+
scheduleDate.value = previousScheduleDate;
|
|
434
|
+
}
|
|
435
|
+
isMutating.value = false;
|
|
436
|
+
}
|
|
199
437
|
async function onSubmit() {
|
|
438
|
+
currentTimestamp.value = Date.now();
|
|
439
|
+
if (scheduleDateError.value) {
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
200
442
|
isMutating.value = true;
|
|
201
443
|
const items = stateItems.value;
|
|
202
|
-
|
|
444
|
+
const hasAnyError = false;
|
|
445
|
+
let mutationResult = false;
|
|
203
446
|
for (const item of items) {
|
|
204
447
|
const isSelected = states.value.includes(item.id) || item.hostEntityType === context.value.entityType && item.hostEntityUuid === context.value.entityUuid;
|
|
205
448
|
if (!isSelected) {
|
|
@@ -209,30 +452,29 @@ async function onSubmit() {
|
|
|
209
452
|
continue;
|
|
210
453
|
}
|
|
211
454
|
try {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
closeAfterPublish: true,
|
|
216
|
-
revisionLogMessage: revisionMessage.value,
|
|
217
|
-
publishIfUnpublished: shouldPublish.value
|
|
218
|
-
});
|
|
219
|
-
let violations = [];
|
|
220
|
-
if (!result.success && result.state) {
|
|
221
|
-
const mapped = adapter.mapState(result.state);
|
|
222
|
-
if (mapped.mutatedState?.violations) {
|
|
223
|
-
violations = mapped.mutatedState.violations;
|
|
455
|
+
if (publishMode.value === "scheduled") {
|
|
456
|
+
if (!adapter.scheduleEditState) {
|
|
457
|
+
throw new Error("scheduleEditState method not available");
|
|
224
458
|
}
|
|
459
|
+
mutationResult = await state.mutateWithLoadingState(
|
|
460
|
+
() => adapter.scheduleEditState({
|
|
461
|
+
hostEntityType: item.hostEntityType,
|
|
462
|
+
hostEntityUuid: item.hostEntityUuid,
|
|
463
|
+
revisionLogMessage: revisionMessage.value,
|
|
464
|
+
date: scheduleDate.value
|
|
465
|
+
})
|
|
466
|
+
);
|
|
467
|
+
} else {
|
|
468
|
+
mutationResult = await state.mutateWithLoadingState(
|
|
469
|
+
() => adapter.publish({
|
|
470
|
+
hostEntityType: item.hostEntityType,
|
|
471
|
+
hostEntityUuid: item.hostEntityUuid,
|
|
472
|
+
closeAfterPublish: true,
|
|
473
|
+
revisionLogMessage: revisionMessage.value,
|
|
474
|
+
publishIfUnpublished: shouldPublish.value
|
|
475
|
+
})
|
|
476
|
+
);
|
|
225
477
|
}
|
|
226
|
-
mutationStatusItems.value[item.id] = {
|
|
227
|
-
id: item.id,
|
|
228
|
-
success: result.success,
|
|
229
|
-
errors: result.errors,
|
|
230
|
-
violations
|
|
231
|
-
};
|
|
232
|
-
if (result.success) {
|
|
233
|
-
publishedIds.value.push(item.id);
|
|
234
|
-
}
|
|
235
|
-
hasAnyError ||= !result.success;
|
|
236
478
|
} catch {
|
|
237
479
|
mutationStatusItems.value[item.id] = {
|
|
238
480
|
id: item.id,
|
|
@@ -244,9 +486,19 @@ async function onSubmit() {
|
|
|
244
486
|
}
|
|
245
487
|
}
|
|
246
488
|
isMutating.value = false;
|
|
247
|
-
if (hasAnyError) {
|
|
489
|
+
if (hasAnyError || !mutationResult) {
|
|
248
490
|
return;
|
|
249
491
|
}
|
|
250
|
-
|
|
492
|
+
if (publishMode.value === "scheduled") {
|
|
493
|
+
const formattedDate = ui.formatDate(scheduleDate.value);
|
|
494
|
+
const message = $t(
|
|
495
|
+
"publishScheduleSuccess",
|
|
496
|
+
"Publication scheduled for @date"
|
|
497
|
+
).replace("@date", formattedDate);
|
|
498
|
+
emitMessage(message, "success");
|
|
499
|
+
emit("close");
|
|
500
|
+
} else {
|
|
501
|
+
emit("submit");
|
|
502
|
+
}
|
|
251
503
|
}
|
|
252
504
|
</script>
|