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