mirror of
https://github.com/mediacms-io/mediacms.git
synced 2026-05-05 20:23:26 -04:00
sharing
This commit is contained in:
@@ -667,3 +667,4 @@ if USE_LTI:
|
|||||||
CSRF_COOKIE_SECURE = True
|
CSRF_COOKIE_SECURE = True
|
||||||
# SESSION_ENGINE = "django.contrib.sessions.backends.cached_db"
|
# SESSION_ENGINE = "django.contrib.sessions.backends.cached_db"
|
||||||
# Consider using cached_db for reliability if sessions are lost between many LTI launches
|
# Consider using cached_db for reliability if sessions are lost between many LTI launches
|
||||||
|
RELATED_MEDIA_STRATEGY = "no_related"
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
VERSION = "8.99912"
|
VERSION = "8.99914"
|
||||||
|
|||||||
+3
-6
@@ -138,8 +138,9 @@ class MediaPublishForm(forms.ModelForm):
|
|||||||
|
|
||||||
self.was_shared = self.instance.is_shared if self.instance.pk else False
|
self.was_shared = self.instance.is_shared if self.instance.pk else False
|
||||||
is_embed_mode = self._check_embed_mode()
|
is_embed_mode = self._check_embed_mode()
|
||||||
if not is_embed_mode:
|
|
||||||
self.fields.pop('shared')
|
self.fields["shared"].initial = self.was_shared
|
||||||
|
self.initial["shared"] = self.was_shared
|
||||||
|
|
||||||
if not is_mediacms_editor(user):
|
if not is_mediacms_editor(user):
|
||||||
for field in ["featured", "reported_times", "is_reviewed"]:
|
for field in ["featured", "reported_times", "is_reviewed"]:
|
||||||
@@ -153,10 +154,6 @@ class MediaPublishForm(forms.ModelForm):
|
|||||||
valid_states.append(self.instance.state)
|
valid_states.append(self.instance.state)
|
||||||
self.fields["state"].choices = [(state, dict(MEDIA_STATES).get(state, state)) for state in valid_states]
|
self.fields["state"].choices = [(state, dict(MEDIA_STATES).get(state, state)) for state in valid_states]
|
||||||
|
|
||||||
if is_embed_mode:
|
|
||||||
self.fields["shared"].initial = self.was_shared
|
|
||||||
self.initial["shared"] = self.was_shared
|
|
||||||
|
|
||||||
if getattr(settings, 'USE_RBAC', False) and 'category' in self.fields:
|
if getattr(settings, 'USE_RBAC', False) and 'category' in self.fields:
|
||||||
if is_mediacms_editor(user):
|
if is_mediacms_editor(user):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -238,6 +238,8 @@ def show_related_media(media, request=None, limit=100):
|
|||||||
return show_related_media_calculated(media, request, limit)
|
return show_related_media_calculated(media, request, limit)
|
||||||
elif settings.RELATED_MEDIA_STRATEGY == "author":
|
elif settings.RELATED_MEDIA_STRATEGY == "author":
|
||||||
return show_related_media_author(media, request, limit)
|
return show_related_media_author(media, request, limit)
|
||||||
|
elif settings.RELATED_MEDIA_STRATEGY == "no_related":
|
||||||
|
return []
|
||||||
|
|
||||||
return show_related_media_content(media, request, limit)
|
return show_related_media_content(media, request, limit)
|
||||||
|
|
||||||
|
|||||||
@@ -509,16 +509,9 @@ class MediaBulkUserActions(APIView):
|
|||||||
|
|
||||||
m.save(update_fields=["state", "listable"])
|
m.save(update_fields=["state", "listable"])
|
||||||
|
|
||||||
shared = request.data.get('shared', None)
|
remove_sharing = request.data.get('remove_sharing', False)
|
||||||
|
|
||||||
if shared is True:
|
if remove_sharing:
|
||||||
for m in media:
|
|
||||||
MediaPermission.objects.get_or_create(
|
|
||||||
media=m,
|
|
||||||
user=request.user,
|
|
||||||
defaults={'owner_user': request.user, 'permission': 'owner'},
|
|
||||||
)
|
|
||||||
elif shared is False or (shared is None and state == 'private'):
|
|
||||||
MediaPermission.objects.filter(media__in=media).delete()
|
MediaPermission.objects.filter(media__in=media).delete()
|
||||||
for m in media:
|
for m in media:
|
||||||
rbac_cats = m.category.filter(is_rbac_category=True)
|
rbac_cats = m.category.filter(is_rbac_category=True)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect, useRef } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import './BulkActionPublishStateModal.scss';
|
import './BulkActionPublishStateModal.scss';
|
||||||
import { translateString } from '../utils/helpers/';
|
import { translateString } from '../utils/helpers/';
|
||||||
|
|
||||||
@@ -29,31 +29,29 @@ export const BulkActionPublishStateModal: React.FC<BulkActionPublishStateModalPr
|
|||||||
sessionStorage.getItem('lms_embed_mode') === 'true' ||
|
sessionStorage.getItem('lms_embed_mode') === 'true' ||
|
||||||
new URLSearchParams(window.location.search).get('mode') === 'lms_embed_mode';
|
new URLSearchParams(window.location.search).get('mode') === 'lms_embed_mode';
|
||||||
const availableStates = isLmsEmbedMode ? PUBLISH_STATES.filter((s) => s.value !== 'public') : PUBLISH_STATES;
|
const availableStates = isLmsEmbedMode ? PUBLISH_STATES.filter((s) => s.value !== 'public') : PUBLISH_STATES;
|
||||||
const defaultState = availableStates[0].value;
|
|
||||||
|
|
||||||
const [selectedState, setSelectedState] = useState(defaultState);
|
const [selectedState, setSelectedState] = useState('');
|
||||||
const [shared, setShared] = useState<boolean | null>(null);
|
const [removeSharing, setRemoveSharing] = useState(false);
|
||||||
|
const [acknowledged, setAcknowledged] = useState(false);
|
||||||
const [isProcessing, setIsProcessing] = useState(false);
|
const [isProcessing, setIsProcessing] = useState(false);
|
||||||
const sharedRef = useRef<HTMLInputElement>(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isOpen) {
|
if (!isOpen) {
|
||||||
setSelectedState(defaultState);
|
setSelectedState('');
|
||||||
setShared(null);
|
setRemoveSharing(false);
|
||||||
|
setAcknowledged(false);
|
||||||
}
|
}
|
||||||
}, [isOpen]);
|
}, [isOpen]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (sharedRef.current) {
|
|
||||||
sharedRef.current.indeterminate = shared === null;
|
|
||||||
}
|
|
||||||
}, [shared]);
|
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
if (!selectedState) {
|
if (!selectedState) {
|
||||||
onError(translateString('Please select a publish state'));
|
onError(translateString('Please select a publish state'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (removeSharing && !acknowledged) {
|
||||||
|
onError(translateString('Please acknowledge the sharing removal'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setIsProcessing(true);
|
setIsProcessing(true);
|
||||||
|
|
||||||
@@ -63,8 +61,8 @@ export const BulkActionPublishStateModal: React.FC<BulkActionPublishStateModalPr
|
|||||||
media_ids: selectedMediaIds,
|
media_ids: selectedMediaIds,
|
||||||
state: selectedState,
|
state: selectedState,
|
||||||
};
|
};
|
||||||
if (shared !== null) {
|
if (removeSharing) {
|
||||||
body.shared = shared;
|
body.remove_sharing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await fetch('/api/v1/media/user/bulk_actions', {
|
const response = await fetch('/api/v1/media/user/bulk_actions', {
|
||||||
@@ -93,13 +91,6 @@ export const BulkActionPublishStateModal: React.FC<BulkActionPublishStateModalPr
|
|||||||
|
|
||||||
if (!isOpen) return null;
|
if (!isOpen) return null;
|
||||||
|
|
||||||
const sharedNote =
|
|
||||||
shared === null
|
|
||||||
? translateString('Sharing status will not be changed.')
|
|
||||||
: shared
|
|
||||||
? translateString('Selected media will be marked as shared.')
|
|
||||||
: translateString('Sharing will be removed from all selected media.');
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="publish-state-modal-overlay">
|
<div className="publish-state-modal-overlay">
|
||||||
<div className="publish-state-modal">
|
<div className="publish-state-modal">
|
||||||
@@ -119,6 +110,9 @@ export const BulkActionPublishStateModal: React.FC<BulkActionPublishStateModalPr
|
|||||||
onChange={(e) => setSelectedState(e.target.value)}
|
onChange={(e) => setSelectedState(e.target.value)}
|
||||||
disabled={isProcessing}
|
disabled={isProcessing}
|
||||||
>
|
>
|
||||||
|
<option value="" disabled>
|
||||||
|
{translateString('— select —')}
|
||||||
|
</option>
|
||||||
{availableStates.map((state) => (
|
{availableStates.map((state) => (
|
||||||
<option key={state.value} value={state.value}>
|
<option key={state.value} value={state.value}>
|
||||||
{state.label}
|
{state.label}
|
||||||
@@ -127,23 +121,34 @@ export const BulkActionPublishStateModal: React.FC<BulkActionPublishStateModalPr
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{isLmsEmbedMode && (
|
<div className="shared-selector">
|
||||||
<div className="shared-selector">
|
|
||||||
<label className="shared-selector-label">
|
<label className="shared-selector-label">
|
||||||
<input
|
<input
|
||||||
ref={sharedRef}
|
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
checked={shared === true}
|
checked={removeSharing}
|
||||||
onChange={(e) => setShared(e.target.checked)}
|
onChange={(e) => {
|
||||||
|
setRemoveSharing(e.target.checked);
|
||||||
|
if (!e.target.checked) setAcknowledged(false);
|
||||||
|
}}
|
||||||
disabled={isProcessing}
|
disabled={isProcessing}
|
||||||
/>
|
/>
|
||||||
{translateString('Shared')}
|
{translateString('Remove Sharing')}
|
||||||
</label>
|
</label>
|
||||||
<p className={`shared-selector-note${shared === false ? ' shared-selector-note--warn' : ''}`}>
|
<p className="shared-selector-note shared-selector-note--warn">
|
||||||
{sharedNote}
|
{translateString('Sharing will be removed from all selected media.')}
|
||||||
</p>
|
</p>
|
||||||
|
{removeSharing && (
|
||||||
|
<label className="shared-selector-label shared-selector-acknowledge">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={acknowledged}
|
||||||
|
onChange={(e) => setAcknowledged(e.target.checked)}
|
||||||
|
disabled={isProcessing}
|
||||||
|
/>
|
||||||
|
{translateString('I understand that this will remove all existing sharing for this media.')}
|
||||||
|
</label>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="publish-state-modal-footer">
|
<div className="publish-state-modal-footer">
|
||||||
@@ -153,7 +158,7 @@ export const BulkActionPublishStateModal: React.FC<BulkActionPublishStateModalPr
|
|||||||
<button
|
<button
|
||||||
className="publish-state-btn publish-state-btn-submit"
|
className="publish-state-btn publish-state-btn-submit"
|
||||||
onClick={handleSubmit}
|
onClick={handleSubmit}
|
||||||
disabled={isProcessing}
|
disabled={isProcessing || (removeSharing && !acknowledged)}
|
||||||
>
|
>
|
||||||
{isProcessing ? translateString('Processing...') : translateString('Submit')}
|
{isProcessing ? translateString('Processing...') : translateString('Submit')}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user