feat(AddFastPriceChange)

subProduct
Amir Hossein Khademi 2024-08-06 12:38:57 +03:30
parent 956b0421b2
commit d457803c30
15 changed files with 416 additions and 99 deletions

View File

@ -1,8 +1,9 @@
@inject IJSRuntime JsRuntime @inject IJSRuntime JsRuntime
@implements IAsyncDisposable @implements IAsyncDisposable
<head> <head>
<link rel="stylesheet" href="css/content-styles.css" /> <link rel="stylesheet" href="assets/vendor/ckeditor5-content.css" />
</head> </head>
<style> <style>
.ck-content * { .ck-content * {
@ -15,65 +16,9 @@
</style> </style>
<div class="editor"></div> <div class="editor"></div>
<script type="text/javascript">
@code
function destroyEditor() { {
// document.querySelector('.editor').ckeditorInstance.destroy();
window.editor = null;
}
function lunchEditor(data) {
if (!document.querySelector('.editor')) return
if (window.editor) return
ClassicEditor.create(document.querySelector('.editor'), {
htmlSupport: {
allow: [
{
name: 'iframe',
attributes: true,
classes: true,
styles: true
}
]
}
})
.then(editor => {
window.editor = editor;
window.editor.setData(data);
editor.editing.view.document.on('blur', () => {
GLOBAL.DotNetReference.invokeMethodAsync('MyMethod', window.editor.getData());
});
})
.catch(handleSampleError);
}
var GLOBAL = {};
GLOBAL.DotNetReference = null;
GLOBAL.SetDotnetReference = function (pDotNetReference) {
GLOBAL.DotNetReference = pDotNetReference;
};
function handleSampleError(error) {
const issueUrl = 'https://github.com/ckeditor/ckeditor5/issues';
const message = [
'Oops, something went wrong!',
`Please, report the following error on ${issueUrl} with the build id "pws0dnpd0jqj-zi42lsl7aqxa" and the error stack trace:`
].join('\n');
console.error(message);
console.error(error);
}
function setData(data) {
if (!!window.editor.date && window.editor.data != data) {
window.editor.setData(data);
}
}
</script>
@code {
@ -100,7 +45,7 @@
{ {
try try
{ {
await JsRuntime.InvokeVoidAsync("window.setData", Text); await JsRuntime.InvokeVoidAsync("setData", Text);
isTextSeted = true; isTextSeted = true;
} }
catch (Exception e) catch (Exception e)
@ -114,20 +59,23 @@
protected override async Task OnAfterRenderAsync(bool firstRender) protected override async Task OnAfterRenderAsync(bool firstRender)
{ {
var lDotNetReference = DotNetObjectReference.Create(this); if (firstRender)
await JsRuntime.InvokeVoidAsync("GLOBAL.SetDotnetReference", lDotNetReference); {
await JsRuntime.InvokeVoidAsync("window.lunchEditor", Text); var lDotNetReference = DotNetObjectReference.Create(this);
await base.OnAfterRenderAsync(firstRender); await JsRuntime.InvokeVoidAsync("GLOBAL.SetDotnetReference", lDotNetReference);
await JsRuntime.InvokeVoidAsync("initializeCKEditor", Text);
await base.OnAfterRenderAsync(firstRender);
}
} }
public void Dispose() public void Dispose()
{ {
JsRuntime.InvokeVoidAsync("window.destroyEditor", Text); JsRuntime.InvokeVoidAsync("destroyEditor", Text);
} }
public async ValueTask DisposeAsync() public async ValueTask DisposeAsync()
{ {
await JsRuntime.InvokeVoidAsync("window.destroyEditor", Text); await JsRuntime.InvokeVoidAsync("destroyEditor", Text);
} }
} }

View File

@ -34,6 +34,12 @@
</EmbeddedResource> </EmbeddedResource>
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="wwwroot\assets\vendor\ckeditor5.css.map" />
<None Include="wwwroot\assets\vendor\ckeditor5.js" />
<None Include="wwwroot\assets\vendor\ckeditor5.js.map" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Append.Blazor.Printing" Version="6.3.0" /> <PackageReference Include="Append.Blazor.Printing" Version="6.3.0" />
<PackageReference Include="Blazored.LocalStorage" Version="4.4.0" /> <PackageReference Include="Blazored.LocalStorage" Version="4.4.0" />

View File

@ -134,7 +134,6 @@
</TemplateColumn> </TemplateColumn>
<PropertyColumn Title="نام محصول" Property="arg => arg.PersianName" /> <PropertyColumn Title="نام محصول" Property="arg => arg.PersianName" />
<PropertyColumn Title="دسته بندی" Property="arg => arg.CategoryName" /> <PropertyColumn Title="دسته بندی" Property="arg => arg.CategoryName" />
<PropertyColumn Title="برند" Property="arg => arg.BrandName" />
<TemplateColumn T="ProductSDto" Title="پیشنهاد ویژه است"> <TemplateColumn T="ProductSDto" Title="پیشنهاد ویژه است">
<CellTemplate> <CellTemplate>
@if (@context.Item.IsSpecial) @if (@context.Item.IsSpecial)
@ -165,7 +164,15 @@
<TemplateColumn T="ProductSDto" Title="قیمتــ"> <TemplateColumn T="ProductSDto" Title="قیمتــ">
<CellTemplate> <CellTemplate>
<p>@context.Item.Cost.ToString("N0") ریالــ</p> <MudTextField class="-mt-2"
Format="N0"
T="double"
ValueChanged="async(cost) => await ViewModel.ChangeProductCostAsync(context.Item,cost)"
AdornmentText="ریالــ"
Immediate="false"
AdornmentIcon="@Icons.Material.Filled.Check"
Adornment="Adornment.End"
Value="context.Item.Cost"></MudTextField>
</CellTemplate> </CellTemplate>
</TemplateColumn> </TemplateColumn>
<TemplateColumn CellClass="d-flex justify-end"> <TemplateColumn CellClass="d-flex justify-end">

View File

@ -1,4 +1,5 @@
using MudBlazor.Services; using MudBlazor.Services;
using Netina.Domain.Entities.Products;
namespace Netina.AdminPanel.PWA.Pages; namespace Netina.AdminPanel.PWA.Pages;
@ -232,4 +233,28 @@ public class ProductsPageViewModel(
CurrentPage = 0; CurrentPage = 0;
await GetEntitiesAsync(); await GetEntitiesAsync();
} }
public async Task ChangeProductCostAsync(ProductSDto product,double cost)
{
try
{
var token = await _userUtility.GetBearerTokenAsync();
if (token == null)
throw new Exception("Token is null");
await restWrapper.ProductRestApi.ChangeCostAsync(product.Id, cost, token);
product.Cost = cost;
}
catch (ApiException ex)
{
var exe = await ex.GetContentAsAsync<ApiResult>();
snackbar.Add(exe != null ? exe.Message : ex.Content, Severity.Error);
}
catch (Exception e)
{
snackbar.Add(e.Message, Severity.Error);
}
}
} }

View File

@ -2,9 +2,13 @@
public interface IProductRestApi public interface IProductRestApi
{ {
[Put("/{productId}")] [Put("/{productId}/displayed")]
Task<bool> ChangeDisplayedAsync(Guid productId, [Query]bool beDisplayed, [Header("Authorization")]string authorization); Task<bool> ChangeDisplayedAsync(Guid productId, [Query]bool beDisplayed, [Header("Authorization")]string authorization);
[Put("/{productId}/cost")]
Task<bool> ChangeCostAsync(Guid productId, [Query] double cost, [Header("Authorization")] string authorization);
[Get("/{productId}")] [Get("/{productId}")]
Task<GetProductResponseDto> ReadOne(Guid productId); Task<GetProductResponseDto> ReadOne(Guid productId);

View File

@ -1,27 +1,5 @@
{ {
"dependencies": { "dependencies": {
"@ckeditor/ckeditor5-alignment": "41.0.0",
"@ckeditor/ckeditor5-autoformat": "41.0.0",
"@ckeditor/ckeditor5-basic-styles": "41.0.0",
"@ckeditor/ckeditor5-block-quote": "41.0.0",
"@ckeditor/ckeditor5-editor-classic": "41.0.0",
"@ckeditor/ckeditor5-essentials": "41.0.0",
"@ckeditor/ckeditor5-font": "41.0.0",
"@ckeditor/ckeditor5-heading": "41.0.0",
"@ckeditor/ckeditor5-horizontal-line": "41.0.0",
"@ckeditor/ckeditor5-html-support": "^41.0.0",
"@ckeditor/ckeditor5-image": "41.0.0",
"@ckeditor/ckeditor5-indent": "41.0.0",
"@ckeditor/ckeditor5-link": "41.0.0",
"@ckeditor/ckeditor5-list": "41.0.0",
"@ckeditor/ckeditor5-media-embed": "41.0.0",
"@ckeditor/ckeditor5-paragraph": "41.0.0",
"@ckeditor/ckeditor5-paste-from-office": "41.0.0",
"@ckeditor/ckeditor5-table": "41.0.0",
"@ckeditor/ckeditor5-typing": "41.0.0",
"@ckeditor/ckeditor5-undo": "41.0.0",
"@ckeditor/ckeditor5-upload": "41.0.0",
"@ckeditor/ckeditor5-word-count": "41.0.0",
"autoprefixer": "^10.4.17", "autoprefixer": "^10.4.17",
"flowbite": "^2.2.1", "flowbite": "^2.2.1",
"postcss": "^8.4.33", "postcss": "^8.4.33",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,322 @@
import {
ClassicEditor,
AccessibilityHelp,
Alignment,
Autoformat,
AutoImage,
AutoLink,
Autosave,
BalloonToolbar,
BlockQuote,
Bold,
CodeBlock,
Essentials,
FindAndReplace,
FontBackgroundColor,
FontColor,
FontFamily,
FontSize,
Heading,
Highlight,
HorizontalLine,
HtmlEmbed,
ImageBlock,
ImageCaption,
ImageInline,
ImageInsert,
ImageInsertViaUrl,
ImageResize,
ImageStyle,
ImageTextAlternative,
ImageToolbar,
ImageUpload,
Indent,
IndentBlock,
Italic,
Link,
LinkImage,
List,
ListProperties,
MediaEmbed,
Paragraph,
PasteFromOffice,
SelectAll,
ShowBlocks,
SimpleUploadAdapter,
SourceEditing,
SpecialCharacters,
SpecialCharactersArrows,
SpecialCharactersCurrency,
SpecialCharactersEssentials,
SpecialCharactersLatin,
SpecialCharactersMathematical,
SpecialCharactersText,
Strikethrough,
Table,
TableCaption,
TableCellProperties,
TableColumnResize,
TableProperties,
TableToolbar,
TextTransformation,
TodoList,
Underline,
Undo
} from '/assets/vendor/ckeditor5.js';
const editorConfig = {
toolbar: {
items: [
'undo',
'redo',
'|',
'sourceEditing',
'showBlocks',
'findAndReplace',
'selectAll',
'|',
'heading',
'|',
'fontSize',
'fontFamily',
'fontColor',
'fontBackgroundColor',
'|',
'bold',
'italic',
'underline',
'strikethrough',
'|',
'specialCharacters',
'horizontalLine',
'link',
'insertImage',
'mediaEmbed',
'insertTable',
'highlight',
'blockQuote',
'codeBlock',
'htmlEmbed',
'|',
'alignment',
'|',
'bulletedList',
'numberedList',
'todoList',
'outdent',
'indent',
'|',
'accessibilityHelp'
],
shouldNotGroupWhenFull: true
},
plugins: [
AccessibilityHelp,
Alignment,
Autoformat,
AutoImage,
AutoLink,
Autosave,
BalloonToolbar,
BlockQuote,
Bold,
CodeBlock,
Essentials,
FindAndReplace,
FontBackgroundColor,
FontColor,
FontFamily,
FontSize,
Heading,
Highlight,
HorizontalLine,
HtmlEmbed,
ImageBlock,
ImageCaption,
ImageInline,
ImageInsert,
ImageInsertViaUrl,
ImageResize,
ImageStyle,
ImageTextAlternative,
ImageToolbar,
ImageUpload,
Indent,
IndentBlock,
Italic,
Link,
LinkImage,
List,
ListProperties,
MediaEmbed,
Paragraph,
PasteFromOffice,
SelectAll,
ShowBlocks,
SimpleUploadAdapter,
SourceEditing,
SpecialCharacters,
SpecialCharactersArrows,
SpecialCharactersCurrency,
SpecialCharactersEssentials,
SpecialCharactersLatin,
SpecialCharactersMathematical,
SpecialCharactersText,
Strikethrough,
Table,
TableCaption,
TableCellProperties,
TableColumnResize,
TableProperties,
TableToolbar,
TextTransformation,
TodoList,
Underline,
Undo
],
simpleUpload: {
uploadUrl: 'https://api.vesmeh.com/api/file/ckeditor',
withCredentials: true,
headers: {
Authorization: 'xuwp4KzU1/YBoevpzgH0cz8+zLKQ+EOaYXeo4JtRxmVIuN7Hqxz97oQ398tNX68+'
}
},
balloonToolbar: ['bold', 'italic', '|', 'link', 'insertImage', '|', 'bulletedList', 'numberedList'],
fontFamily: {
supportAllValues: true
},
fontSize: {
options: [10, 12, 14, 'default', 18, 20, 22],
supportAllValues: true
},
heading: {
options: [
{
model: 'paragraph',
title: 'Paragraph',
class: 'ck-heading_paragraph'
},
{
model: 'heading1',
view: 'h1',
title: 'Heading 1',
class: 'ck-heading_heading1'
},
{
model: 'heading2',
view: 'h2',
title: 'Heading 2',
class: 'ck-heading_heading2'
},
{
model: 'heading3',
view: 'h3',
title: 'Heading 3',
class: 'ck-heading_heading3'
},
{
model: 'heading4',
view: 'h4',
title: 'Heading 4',
class: 'ck-heading_heading4'
},
{
model: 'heading5',
view: 'h5',
title: 'Heading 5',
class: 'ck-heading_heading5'
},
{
model: 'heading6',
view: 'h6',
title: 'Heading 6',
class: 'ck-heading_heading6'
}
]
},
image: {
toolbar: [
'toggleImageCaption',
'imageTextAlternative',
'|',
'imageStyle:inline',
'imageStyle:wrapText',
'imageStyle:breakText',
'|',
'resizeImage'
]
},
link: {
addTargetToExternalLinks: true,
defaultProtocol: 'https://',
decorators: {
toggleDownloadable: {
mode: 'manual',
label: 'Downloadable',
attributes: {
download: 'file'
}
}
}
},
list: {
properties: {
styles: true,
startIndex: true,
reversed: true
}
},
placeholder: 'متن خود را بنویسید یا کپی کنید',
table: {
contentToolbar: ['tableColumn', 'tableRow', 'mergeTableCells', 'tableProperties', 'tableCellProperties']
},
language: {
ui: 'en',
content: 'ar'
}
};
export function initializeCKEditor(data) {
if (!document.querySelector('.editor')) return;
if (window.editor) return;
ClassicEditor.create(document.querySelector('.editor'), editorConfig)
.then(editor => {
window.editor = editor;
window.editor.setData(data);
editor.editing.view.document.on('blur', () => {
if (GLOBAL.DotNetReference) {
GLOBAL.DotNetReference.invokeMethodAsync('MyMethod', window.editor.getData());
}
});
})
.catch(handleSampleError);
}
export function destroyEditor() {
if (window.editor) {
window.editor.destroy();
window.editor = null;
}
}
export function setData(data) {
if (window.editor) {
window.editor.setData(data);
}
}
function handleSampleError(error) {
const issueUrl = 'https://github.com/ckeditor/ckeditor5/issues';
const message = [
'Oops, something went wrong!',
`Please, report the following error on ${issueUrl} with the build id "pws0dnpd0jqj-zi42lsl7aqxa" and the error stack trace:`
].join('\n');
console.error(message);
console.error(error);
}
export var GLOBAL = {
DotNetReference: null,
SetDotnetReference: function (pDotNetReference) {
this.DotNetReference = pDotNetReference;
}
};

View File

@ -11,6 +11,7 @@
<script src="https://unpkg.com/@dotlottie/player-component@latest/dist/dotlottie-player.mjs" type="module"></script> <script src="https://unpkg.com/@dotlottie/player-component@latest/dist/dotlottie-player.mjs" type="module"></script>
<link rel="icon" type="image/png" href="favicon.png" /> <link rel="icon" type="image/png" href="favicon.png" />
<link rel="stylesheet" href="css/CKEditor.css" /> <link rel="stylesheet" href="css/CKEditor.css" />
<link rel="stylesheet" href="assets/vendor/ckeditor5.css">
<link href="manifest.webmanifest" rel="manifest" /> <link href="manifest.webmanifest" rel="manifest" />
<link rel="apple-touch-icon" sizes="512x512" href="icon-512.png" /> <link rel="apple-touch-icon" sizes="512x512" href="icon-512.png" />
<link rel="apple-touch-icon" sizes="192x192" href="icon-192.png" /> <link rel="apple-touch-icon" sizes="192x192" href="icon-192.png" />
@ -48,6 +49,15 @@
<a href="" class="reload">بارگزاری مجدد</a> <a href="" class="reload">بارگزاری مجدد</a>
<a class="dismiss">بستن</a> <a class="dismiss">بستن</a>
</div> </div>
<script type="module">
import { initializeCKEditor, destroyEditor, setData, GLOBAL } from './ckeditor5New.js';
window.initializeCKEditor = initializeCKEditor;
window.destroyEditor = destroyEditor;
window.setData = setData;
window.GLOBAL = GLOBAL;
</script>
<script src="_framework/blazor.webassembly.js"></script> <script src="_framework/blazor.webassembly.js"></script>
<script src="aes-js-3.1.2.js"></script> <script src="aes-js-3.1.2.js"></script>
@ -104,7 +114,6 @@
<script src="_content/Radzen.Blazor/Radzen.Blazor.js"></script> <script src="_content/Radzen.Blazor/Radzen.Blazor.js"></script>
<script src="_content/MudBlazor/MudBlazor.min.js"></script> <script src="_content/MudBlazor/MudBlazor.min.js"></script>
<script src="_content/Toolbelt.Blazor.PWA.Updater.Service/script.min.js"></script> <script src="_content/Toolbelt.Blazor.PWA.Updater.Service/script.min.js"></script>
<script src="ckeditor.js"></script>
</body> </body>