mirror of
https://github.com/alexmickelson/canvasManagement.git
synced 2026-03-25 23:28:33 -06:00
added click editing to calendar vue
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
@using Markdig
|
||||
|
||||
@inject CoursePlanner planner
|
||||
|
||||
@code
|
||||
{
|
||||
[Parameter]
|
||||
public string Description { get; set; } = default!;
|
||||
[Parameter]
|
||||
public bool UseTemplate { get; set; }
|
||||
[Parameter]
|
||||
public string? TemplateId { get; set; }
|
||||
[Parameter]
|
||||
public Dictionary<string, string> VariableValues { get; set; } = new Dictionary<string, string>();
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<string> DescriptionChanged { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<bool> UseTemplateChanged { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<string?> TemplateIdChanged { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<Dictionary<string, string>> VariableValuesChanged { get; set; }
|
||||
|
||||
private AssignmentTemplate? selectedTemplate =>
|
||||
planner
|
||||
.LocalCourse?
|
||||
.AssignmentTemplates
|
||||
.FirstOrDefault(t => t.Id == TemplateId);
|
||||
public string Preview => Markdown.ToHtml(Description);
|
||||
|
||||
}
|
||||
|
||||
|
||||
<div class="form-check form-switch">
|
||||
<input
|
||||
class="form-check-input"
|
||||
type="checkbox"
|
||||
role="switch"
|
||||
id="useTemplateForDescription"
|
||||
checked="@UseTemplate"
|
||||
@onchange="async (e) =>
|
||||
await UseTemplateChanged.InvokeAsync((bool)(e.Value ?? false))"
|
||||
>
|
||||
<label
|
||||
class="form-check-label"
|
||||
for="useTemplateForDescription"
|
||||
>
|
||||
use template for description
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@if(UseTemplate)
|
||||
{
|
||||
@if(planner.LocalCourse != null)
|
||||
{
|
||||
<div class="row justify-content-around">
|
||||
<div class="col-auto text-center">
|
||||
<form @onsubmit:preventDefault="true">
|
||||
<label for="templateSelect">Templates</label>
|
||||
<select
|
||||
id="templateSelect"
|
||||
class="form-select"
|
||||
value="@TemplateId"
|
||||
@onchange="async (e) =>
|
||||
await TemplateIdChanged.InvokeAsync(e.Value?.ToString())"
|
||||
>
|
||||
<option value=""></option>
|
||||
@foreach (var template in planner.LocalCourse.AssignmentTemplates)
|
||||
{
|
||||
<option value="@template.Id">@template.Name</option>
|
||||
}
|
||||
</select>
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
VARIABLES:
|
||||
@if(selectedTemplate != null)
|
||||
{
|
||||
var variables = AssignmentTemplate.GetVariables(selectedTemplate.Markdown);
|
||||
@foreach(var variable in variables)
|
||||
{
|
||||
<div class="my-1">
|
||||
<label
|
||||
class="form-label"
|
||||
>
|
||||
@variable
|
||||
</label>
|
||||
<input
|
||||
class="form-control"
|
||||
value="@VariableValues.GetValueOrDefault(variable, String.Empty)"
|
||||
@oninput="async (e) =>
|
||||
{
|
||||
var newValue = e.Value?.ToString() ?? String.Empty;
|
||||
var newDictionary = new Dictionary<string, string>(VariableValues);
|
||||
newDictionary[variable] = newValue;
|
||||
|
||||
await VariableValuesChanged.InvokeAsync(newDictionary);
|
||||
}
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<label
|
||||
for="description"
|
||||
class="form-label"
|
||||
>
|
||||
Description
|
||||
</label>
|
||||
</div>
|
||||
<div class="col">
|
||||
HTML Preview
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<textarea
|
||||
id="description"
|
||||
class="form-control"
|
||||
value="@Description"
|
||||
rows=12
|
||||
@oninput="async (e) =>
|
||||
await DescriptionChanged.InvokeAsync(e.Value?.ToString() ?? String.Empty)"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
@((MarkupString) Preview)
|
||||
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
@using Management.Web.Shared.Components
|
||||
|
||||
@inject CoursePlanner planner
|
||||
|
||||
@code {
|
||||
public LocalModule Module { get; set; } = default!;
|
||||
|
||||
[Parameter]
|
||||
[EditorRequired]
|
||||
public LocalAssignment Assignment
|
||||
{
|
||||
get;
|
||||
set;
|
||||
} = default!;
|
||||
|
||||
[Parameter]
|
||||
[EditorRequired]
|
||||
public bool Show { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public Action OnHide { get; set; } = () => { };
|
||||
public Modal AssignmentModal { get; set; } = default!;
|
||||
|
||||
private bool useTemplate { get; set; } = false;
|
||||
private string? templateId { get; set; }
|
||||
public Dictionary<string, string> templateVariables { get; set; } =
|
||||
new Dictionary<string, string>();
|
||||
private string description { get; set; } = String.Empty;
|
||||
private string name { get; set; } = String.Empty;
|
||||
private bool lockAtDueDate { get; set; }
|
||||
private IEnumerable<RubricItem> rubric { get; set; } = Enumerable.Empty<RubricItem>();
|
||||
private IEnumerable<string> submissionTypes { get; set; } = Enumerable.Empty<string>();
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
if(Show)
|
||||
{
|
||||
AssignmentModal.Show();
|
||||
}
|
||||
name = Assignment.name;
|
||||
description = Assignment.description;
|
||||
lockAtDueDate = Assignment.lock_at_due_date;
|
||||
rubric = Assignment.rubric;
|
||||
submissionTypes = Assignment.submission_types;
|
||||
templateId = Assignment.template_id;
|
||||
useTemplate = Assignment.use_template;
|
||||
templateVariables = Assignment.template_variables;
|
||||
}
|
||||
|
||||
private void submitHandler()
|
||||
{
|
||||
var totalRubricPoints = rubric
|
||||
.Where(r => !r.Label.Contains(RubricItem.extraCredit))
|
||||
.Select(s => s.Points)
|
||||
.Sum();
|
||||
|
||||
var newAssignment = Assignment with
|
||||
{
|
||||
name=name,
|
||||
description=description,
|
||||
lock_at_due_date=lockAtDueDate,
|
||||
rubric=rubric,
|
||||
points_possible=totalRubricPoints,
|
||||
submission_types=submissionTypes,
|
||||
use_template=useTemplate,
|
||||
template_id=templateId,
|
||||
template_variables=templateVariables,
|
||||
};
|
||||
|
||||
if(planner.LocalCourse != null)
|
||||
{
|
||||
planner.LocalCourse = planner.LocalCourse with
|
||||
{
|
||||
Modules=planner.LocalCourse.Modules.Select(m =>
|
||||
m.Name != Module.Name
|
||||
? m
|
||||
: Module with
|
||||
{
|
||||
Assignments=Module.Assignments.Select(a =>
|
||||
a.id == newAssignment.id
|
||||
? newAssignment
|
||||
: a
|
||||
)
|
||||
}
|
||||
)
|
||||
};
|
||||
}
|
||||
AssignmentModal.Hide();
|
||||
}
|
||||
private void updateRubric(IEnumerable<RubricItem> newRubric)
|
||||
{
|
||||
rubric = newRubric;
|
||||
StateHasChanged();
|
||||
}
|
||||
private void SetTypes(IEnumerable<string> newTypes)
|
||||
{
|
||||
submissionTypes = newTypes;
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
||||
<Modal @ref="AssignmentModal" OnHide="@(() => OnHide())">
|
||||
<Title>
|
||||
@Assignment.name
|
||||
</Title>
|
||||
<Body>
|
||||
<form @onsubmit:preventDefault="true" @onsubmit="submitHandler">
|
||||
<div class="m-1">
|
||||
<label
|
||||
class="form-label"
|
||||
>
|
||||
Name
|
||||
</label>
|
||||
<input
|
||||
class="form-control"
|
||||
@bind="name"
|
||||
/>
|
||||
</div>
|
||||
<div class="m-1">
|
||||
<AssignmentDescriptionEditor
|
||||
@bind-Description="description"
|
||||
@bind-UseTemplate="useTemplate"
|
||||
@bind-TemplateId="templateId"
|
||||
@bind-VariableValues="templateVariables"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="form-check m-1">
|
||||
<input
|
||||
class="form-check-input"
|
||||
id="lockAtDueDate"
|
||||
type="checkbox"
|
||||
/>
|
||||
<label
|
||||
class="form-check-label"
|
||||
for="lockAtDueDate"
|
||||
@bind="lockAtDueDate"
|
||||
>
|
||||
Lock At Due Date
|
||||
</label>
|
||||
</div>
|
||||
<RubricEditor Rubric="rubric" SetRubric="updateRubric" />
|
||||
<SubmissionTypeSelector
|
||||
Types="submissionTypes"
|
||||
SetTypes="SetTypes"
|
||||
/>
|
||||
</form>
|
||||
</Body>
|
||||
<Footer>
|
||||
<button class="btn btn-primary" @onclick="submitHandler">
|
||||
Save
|
||||
</button>
|
||||
</Footer>
|
||||
</Modal>
|
||||
@@ -0,0 +1,97 @@
|
||||
@using Management.Web.Shared.Components
|
||||
|
||||
@inject CoursePlanner planner
|
||||
|
||||
@code
|
||||
{
|
||||
[Parameter, EditorRequired]
|
||||
public IEnumerable<RubricItem> Rubric { get; set; } = default!;
|
||||
|
||||
[Parameter, EditorRequired]
|
||||
public Action<IEnumerable<RubricItem>> SetRubric { get; set; } = default!;
|
||||
|
||||
private void addItem()
|
||||
{
|
||||
SetRubric(
|
||||
Rubric.Append(new RubricItem
|
||||
{
|
||||
Id=Guid.NewGuid().ToString(),
|
||||
Label="",
|
||||
Points=0
|
||||
})
|
||||
);
|
||||
StateHasChanged();
|
||||
}
|
||||
private void removeItem()
|
||||
{
|
||||
SetRubric(
|
||||
Rubric.Take(Rubric.Count() - 1)
|
||||
);
|
||||
StateHasChanged();
|
||||
}
|
||||
private void editItem(RubricItem newItem)
|
||||
{
|
||||
var newRubric = Rubric.Select(i => i.Id == newItem.Id ? newItem : i);
|
||||
SetRubric(newRubric);
|
||||
StateHasChanged();
|
||||
}
|
||||
private void MoveUp(RubricItem item)
|
||||
{
|
||||
var rubricList = Rubric.ToList();
|
||||
var index = rubricList.IndexOf(item);
|
||||
|
||||
if(index > 0)
|
||||
{
|
||||
var previous = rubricList[index - 1];
|
||||
rubricList[index - 1] = item;
|
||||
rubricList[index] = previous;
|
||||
SetRubric(rubricList);
|
||||
}
|
||||
}
|
||||
private void MoveDown(RubricItem item)
|
||||
{
|
||||
var rubricList = Rubric.ToList();
|
||||
var index = rubricList.IndexOf(item);
|
||||
|
||||
if(index < rubricList.Count())
|
||||
{
|
||||
var next = rubricList[index + 1];
|
||||
rubricList[index + 1] = item;
|
||||
rubricList[index] = next;
|
||||
SetRubric(rubricList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<br>
|
||||
<h5>Rubric</h5>
|
||||
<ul class="list-group">
|
||||
@foreach (var rubricItem in Rubric)
|
||||
{
|
||||
<RubricEditorItem
|
||||
RubricItem="rubricItem"
|
||||
OnUpdate="editItem"
|
||||
MoveUp="() => MoveUp(rubricItem)"
|
||||
MoveDown="() => MoveDown(rubricItem)"
|
||||
/>
|
||||
}
|
||||
</ul>
|
||||
|
||||
<div class="text-end my-1">
|
||||
<button
|
||||
@onclick:preventDefault="true"
|
||||
@onclick="removeItem"
|
||||
type="button"
|
||||
class="btn btn-outline-danger"
|
||||
>
|
||||
- rubric item
|
||||
</button>
|
||||
<button
|
||||
@onclick:preventDefault="true"
|
||||
@onclick="addItem"
|
||||
type="button"
|
||||
class="btn btn-outline-primary"
|
||||
>
|
||||
+ rubric item
|
||||
</button>
|
||||
</div>
|
||||
@@ -0,0 +1,122 @@
|
||||
|
||||
@inject CoursePlanner planner
|
||||
|
||||
@code
|
||||
{
|
||||
[Parameter, EditorRequired]
|
||||
public RubricItem RubricItem { get; set; } = default!;
|
||||
|
||||
[Parameter, EditorRequired]
|
||||
public Action<RubricItem> OnUpdate { get; set; } = default!;
|
||||
[Parameter, EditorRequired]
|
||||
public Action MoveUp { get; set; } = default!;
|
||||
[Parameter, EditorRequired]
|
||||
public Action MoveDown { get; set; } = default!;
|
||||
private void editItem(string label, int points)
|
||||
{
|
||||
var newRubricItem = RubricItem with
|
||||
{
|
||||
Label = label,
|
||||
Points = points
|
||||
};
|
||||
OnUpdate(newRubricItem);
|
||||
}
|
||||
}
|
||||
|
||||
<li
|
||||
class="list-group-item"
|
||||
>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<label
|
||||
for="rubricLabel"
|
||||
class="form-label"
|
||||
>
|
||||
Label
|
||||
</label>
|
||||
<input
|
||||
class="form-control"
|
||||
id="rubricLabel"
|
||||
name="rubricLabel"
|
||||
@oninput="@(e => editItem(e.Value?.ToString() ?? "", RubricItem.Points))"
|
||||
value="@RubricItem.Label"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<label
|
||||
for="rubricPoints"
|
||||
class="form-label"
|
||||
>
|
||||
Points
|
||||
</label>
|
||||
<input
|
||||
class="form-control"
|
||||
id="rubricPoints"
|
||||
name="rubricPoints"
|
||||
@oninput="@(e => editItem(
|
||||
RubricItem.Label,
|
||||
int.Parse(e.Value?.ToString() != "" ? e.Value?.ToString() ?? "0" : "0"))
|
||||
)"
|
||||
value="@RubricItem.Points"
|
||||
type="number"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<label
|
||||
class="form-check-label"
|
||||
for="flexCheckDefault"
|
||||
>
|
||||
Extra Credit
|
||||
</label>
|
||||
<div class="form-check form-switch">
|
||||
<input
|
||||
class="form-check-input"
|
||||
type="checkbox"
|
||||
checked="@RubricItem.Label.Contains(RubricItem.extraCredit)"
|
||||
@oninput="@(e => {
|
||||
bool value = (bool) (e.Value ?? false);
|
||||
var newLabel = value
|
||||
? RubricItem.extraCredit + RubricItem.Label
|
||||
: RubricItem.Label.Replace(RubricItem.extraCredit, "");
|
||||
editItem(newLabel, RubricItem.Points);
|
||||
})"
|
||||
id="extraCredit"
|
||||
name="extraCredit"
|
||||
role="switch"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div >
|
||||
<svg
|
||||
width="2em"
|
||||
height="2em"
|
||||
viewBox="-0.5 0 25 25"
|
||||
fill="none"
|
||||
stroke="rgb(173, 181, 189)"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
role="button"
|
||||
@onclick="MoveUp"
|
||||
>
|
||||
<path d="M8 13.8599L10.87 10.8C11.0125 10.6416 11.1868 10.5149 11.3815 10.4282C11.5761 10.3415 11.7869 10.2966 12 10.2966C12.2131 10.2966 12.4239 10.3415 12.6185 10.4282C12.8132 10.5149 12.9875 10.6416 13.13 10.8L16 13.8599" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M3 7.41992L3 17.4199C3 19.6291 4.79086 21.4199 7 21.4199H17C19.2091 21.4199 21 19.6291 21 17.4199V7.41992C21 5.21078 19.2091 3.41992 17 3.41992H7C4.79086 3.41992 3 5.21078 3 7.41992Z" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<svg
|
||||
width="2em"
|
||||
height="2em"
|
||||
viewBox="-0.5 0 25 25"
|
||||
fill="none"
|
||||
stroke="rgb(173, 181, 189)"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
role="button"
|
||||
@onclick="MoveDown"
|
||||
>
|
||||
<path d="M16 10.99L13.1299 14.05C12.9858 14.2058 12.811 14.3298 12.6166 14.4148C12.4221 14.4998 12.2122 14.5437 12 14.5437C11.7878 14.5437 11.5779 14.4998 11.3834 14.4148C11.189 14.3298 11.0142 14.2058 10.87 14.05L8 10.99" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M21 17.4199V7.41992C21 5.21078 19.2091 3.41992 17 3.41992L7 3.41992C4.79086 3.41992 3 5.21078 3 7.41992V17.4199C3 19.6291 4.79086 21.4199 7 21.4199H17C19.2091 21.4199 21 19.6291 21 17.4199Z" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
@@ -0,0 +1,65 @@
|
||||
@using System.Reflection
|
||||
|
||||
@code
|
||||
{
|
||||
private IEnumerable<string> _types { get; set; } = Enumerable.Empty<string>();
|
||||
[Parameter, EditorRequired]
|
||||
public IEnumerable<string> Types {
|
||||
get => _types;
|
||||
set
|
||||
{
|
||||
_types = value;
|
||||
renderKey++;
|
||||
}
|
||||
}
|
||||
|
||||
[Parameter, EditorRequired]
|
||||
public Action<IEnumerable<string>> SetTypes { get; set; } = (_) => {};
|
||||
private string getLabel(string type)
|
||||
{
|
||||
return type.ToString().Replace("_", "") + "switch";
|
||||
}
|
||||
|
||||
private bool discussionIsSelected
|
||||
{
|
||||
get => Types.FirstOrDefault(
|
||||
t => t == SubmissionType.discussion_topic
|
||||
) != null;
|
||||
}
|
||||
private int renderKey {get; set; } = 1;
|
||||
}
|
||||
|
||||
<h5>Submission Types</h5>
|
||||
<div class="row" @key="Types">
|
||||
|
||||
@foreach (var submissionType in SubmissionType.AllTypes)
|
||||
{
|
||||
var isDiscussion = submissionType == SubmissionType.discussion_topic;
|
||||
var allowedToBeChecked = !discussionIsSelected || isDiscussion;
|
||||
<div class="col-4">
|
||||
<div class="form-check form-switch">
|
||||
<input
|
||||
class="form-check-input"
|
||||
type="checkbox"
|
||||
role="switch"
|
||||
id="@getLabel(submissionType)"
|
||||
checked="@(Types.Contains(submissionType) && allowedToBeChecked)"
|
||||
@onchange="(e) => {
|
||||
var isChecked = (bool)(e.Value ?? false);
|
||||
if(isChecked)
|
||||
SetTypes(Types.Append(submissionType));
|
||||
else
|
||||
SetTypes(Types.Where(t => t != submissionType));
|
||||
}"
|
||||
disabled="@(discussionIsSelected && !isDiscussion)"
|
||||
>
|
||||
<label
|
||||
class="form-check-label"
|
||||
for="@getLabel(submissionType)"
|
||||
>
|
||||
@submissionType
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
Reference in New Issue
Block a user