Merge branch 'develop' of https://bitbucket.org/ncarminati/cms_step into develop

This commit is contained in:
Alessandro Francia
2018-09-21 12:07:23 +02:00
28 changed files with 198 additions and 68 deletions
+18 -18
View File
@@ -589,8 +589,8 @@ namespace CMS_Client.Browser_Tools
using (ZipArchive archive = ZipFile.OpenRead(jobOpenFileDialog.FileName))
{
// Setup main Fields
job.Name = Path.GetFileName(jobOpenFileDialog.FileName);
job.LastEditTimestamp = new FileInfo(jobOpenFileDialog.FileName).LastAccessTime;
job.name = Path.GetFileName(jobOpenFileDialog.FileName);
job.lastEditTimestamp = new FileInfo(jobOpenFileDialog.FileName).LastAccessTime;
foreach (ZipArchiveEntry entry in archive.Entries)
{
@@ -599,7 +599,7 @@ namespace CMS_Client.Browser_Tools
{
using (var reader = new StreamReader(entry.Open()))
{
job.IsoMainProgram = (reader.ReadToEnd());
job.isoMainProgram = (reader.ReadToEnd());
}
}
// Add all images
@@ -611,10 +611,10 @@ namespace CMS_Client.Browser_Tools
{
entry.Open().CopyTo(memstream);
bytes = memstream.ToArray();
job.Metadata.Generics.Images.Add(new ImageParam()
job.metadata.generics.images.Add(new ImageParam()
{
Name = Path.GetFileNameWithoutExtension(entry.Name),
Base64 = "data:image/" + Path.GetExtension(entry.Name).ToLower().TrimStart('.') + ";base64," + Convert.ToBase64String(bytes)
name = Path.GetFileNameWithoutExtension(entry.Name),
base64 = "data:image/" + Path.GetExtension(entry.Name).ToLower().TrimStart('.') + ";base64," + Convert.ToBase64String(bytes)
});
}
}
@@ -633,10 +633,10 @@ namespace CMS_Client.Browser_Tools
}
else
{
job.Metadata.Generics.Description = metasFromFile.Description;
job.Metadata.Generics.ExecutionTime = metasFromFile.ExecutionTime;
job.Metadata.Tools = metasFromFile.Tools;
job.Metadata.Customs = metasFromFile.Customs;
job.metadata.generics.Description = metasFromFile.Description;
job.metadata.generics.ExecutionTime = metasFromFile.ExecutionTime;
job.metadata.tools = metasFromFile.Tools;
job.metadata.customs = metasFromFile.Customs;
}
}
}
@@ -680,10 +680,10 @@ namespace CMS_Client.Browser_Tools
}
//Metadata
metafile.Description = job.Metadata.Generics.Description;
metafile.ExecutionTime = job.Metadata.Generics.ExecutionTime;
metafile.Tools = job.Metadata.Tools;
metafile.Customs = job.Metadata.Customs;
metafile.Description = job.metadata.generics.Description;
metafile.ExecutionTime = job.metadata.generics.ExecutionTime;
metafile.Tools = job.metadata.tools;
metafile.Customs = job.metadata.customs;
using (StreamWriter file = System.IO.File.CreateText(JOB_OPENING_PATH + JOB_METADATA_FILENAME))
{
JsonSerializer serializer = new JsonSerializer
@@ -694,7 +694,7 @@ namespace CMS_Client.Browser_Tools
}
//Main Program
System.IO.File.WriteAllText(JOB_OPENING_PATH + JOB_MAIN_FILENAME, job.IsoMainProgram);
System.IO.File.WriteAllText(JOB_OPENING_PATH + JOB_MAIN_FILENAME, job.isoMainProgram);
//delete Zip File if exists
if (System.IO.File.Exists(jobSaveFileDialog.FileName))
@@ -730,8 +730,8 @@ namespace CMS_Client.Browser_Tools
//Send to Step
e.SetReturnValue(JsonConvert.SerializeObject(new ImageParam()
{
Name = Path.GetFileNameWithoutExtension(imageOpenFileDialog.FileName),
Base64 = "data:image/" + Path.GetExtension(newImagePath).ToLower().TrimStart('.') + ";base64," + Convert.ToBase64String(System.IO.File.ReadAllBytes(newImagePath))
name = Path.GetFileNameWithoutExtension(imageOpenFileDialog.FileName),
base64 = "data:image/" + Path.GetExtension(newImagePath).ToLower().TrimStart('.') + ";base64," + Convert.ToBase64String(System.IO.File.ReadAllBytes(newImagePath))
}));
return;
}
@@ -790,7 +790,7 @@ namespace CMS_Client.Browser_Tools
System.IO.File.Copy(PPOpenFileDialog.FileName, newPPPath);
//Send to Step
e.SetReturnValue(null);
e.SetReturnValue(JsonConvert.SerializeObject(new PPContainer(Path.GetFileName(PPOpenFileDialog.FileName))));
return;
}
e.SetReturnValue(null);
@@ -8,11 +8,11 @@ namespace CMS_Client.Browser_Tools.Models.Errors
{
public class ErrorContainer
{
public String Error;
public String error;
public ErrorContainer(String Err)
{
this.Error = Err;
this.error = Err;
}
}
}
+5 -5
View File
@@ -9,14 +9,14 @@ namespace CMS_Client.Browser_Tools.Models
{
public class JobToStep
{
public string Name;
public DateTime LastEditTimestamp;
public string IsoMainProgram;
public Metas Metadata;
public string name;
public DateTime lastEditTimestamp;
public string isoMainProgram;
public Metas metadata;
public JobToStep()
{
Metadata = new Metas();
metadata = new Metas();
}
}
}
@@ -10,12 +10,12 @@ namespace CMS_Client.Browser_Tools.Models.Metadata
{
public string Name;
public string Type;
public List<string> SelectionList;
public List<string> selectionList;
public int Value;
public CustomParam()
{
SelectionList = new List<string>();
selectionList = new List<string>();
}
}
}
@@ -8,13 +8,13 @@ namespace CMS_Client.Browser_Tools.Models.Metadata
{
public class GenericsParam
{
public List<ImageParam> Images;
public List<ImageParam> images;
public string Description;
public TimeSpan ExecutionTime;
public GenericsParam()
{
Images = new List<ImageParam>();
images = new List<ImageParam>();
}
}
}
@@ -8,7 +8,7 @@ namespace CMS_Client.Browser_Tools.Models.Metadata
{
public class ImageParam
{
public string Name;
public string Base64;
public string name;
public string base64;
}
}
@@ -8,15 +8,15 @@ namespace CMS_Client.Browser_Tools.Models.Metadata
{
public class Metas
{
public GenericsParam Generics;
public List<int> Tools;
public List<CustomParam> Customs;
public GenericsParam generics;
public List<int> tools;
public List<CustomParam> customs;
public Metas()
{
Generics = new GenericsParam();
Tools = new List<int>();
Customs = new List<CustomParam>();
generics = new GenericsParam();
tools = new List<int>();
customs = new List<CustomParam>();
}
}
}
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CMS_Client.Browser_Tools.Models.Metadata
{
public class PPContainer
{
public String name;
public PPContainer(String name)
{
this.name = name;
}
}
}
+1
View File
@@ -162,6 +162,7 @@
<Compile Include="Browser_Tools\Models\Metadata\GenericsParam.cs" />
<Compile Include="Browser_Tools\Models\Metadata\ImageParam.cs" />
<Compile Include="Browser_Tools\Models\Metadata\Metas.cs" />
<Compile Include="Browser_Tools\Models\Metadata\PPContainer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="View\LoadingForm.cs">
<SubType>Form</SubType>
+7 -2
View File
@@ -11,7 +11,7 @@
<ncNeeded>true</ncNeeded>
</tooling>
<report>
<enabled>true</enabled>
<enabled>false</enabled>
<allowExternalBrowser>true</allowExternalBrowser>
<ncNeeded>true</ncNeeded>
</report>
@@ -31,8 +31,13 @@
<ncNeeded>false</ncNeeded>
</utilities>
<scada>
<enabled>true</enabled>
<enabled>false</enabled>
<allowExternalBrowser>true</allowExternalBrowser>
<ncNeeded>true</ncNeeded>
</scada>
<jobeditor>
<enabled>true</enabled>
<allowExternalBrowser>true</allowExternalBrowser>
<ncNeeded>false</ncNeeded>
</jobeditor>
</areasConfig>
@@ -72,6 +72,15 @@
</xs:all>
</xs:complexType>
</xs:element>
<xs:element name="jobeditor">
<xs:complexType>
<xs:all>
<xs:element name="enabled" type="xs:boolean" />
<xs:element name="allowExternalBrowser" type="xs:boolean" />
<xs:element name="ncNeeded" type="xs:boolean" />
</xs:all>
</xs:complexType>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
+2 -2
View File
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<serverConfig>
<ncConfig>
<ncVendor>DEMO</ncVendor> <!-- NO_NC/DEMO/FANUC/SIEMENS/OSAI -->
<ncVendor>OSAI</ncVendor> <!-- NO_NC/DEMO/FANUC/SIEMENS/OSAI -->
<showNcHMI>true</showNcHMI>
<ncIpAddress>localhost</ncIpAddress>
<ncIpAddress>192.168.157.2</ncIpAddress>
<ncPort>8080</ncPort>
<machineModel>Ares 37 OF</machineModel>
<sharedPath>C:\PartPrg\</sharedPath>
+1
View File
@@ -32,6 +32,7 @@ namespace Step.Config
public static AreasConfigModel MaintenanceConfig;
public static AreasConfigModel UtilitiesConfig;
public static AreasConfigModel ScadaConfig;
public static AreasConfigModel JobEditorConfig;
public static List<string> MacrosConfig;
}
+7
View File
@@ -98,6 +98,10 @@ namespace Step.Config
case AREAS.SCADA_KEY:
SetAreaValue(ref ScadaConfig, element);
break;
case AREAS.JOBEDITOR_KEY:
SetAreaValue(ref JobEditorConfig, element);
break;
}
}
@@ -150,6 +154,9 @@ namespace Step.Config
case AREAS.SCADA_KEY:
return ScadaConfig.Enabled;
case AREAS.JOBEDITOR_KEY:
return ScadaConfig.Enabled;
case AREAS.GENERAL_KEY:
case AREAS.UNDER_HOOD:
return true;
+1
View File
@@ -115,6 +115,7 @@ namespace Step.Model
public const string SCADA_KEY = "scada";
public const string GENERAL_KEY = "general";
public const string UNDER_HOOD = "underHood";
public const string JOBEDITOR_KEY = "jobeditor";
}
// Config File Names
@@ -16,5 +16,6 @@ namespace Step.Model.DTOModels
public AreasConfigModel MaintenanceConfig;
public AreasConfigModel UtilitiesConfig;
public AreasConfigModel ScadaConfig;
public AreasConfigModel JobEditorConfig;
}
}
+3 -1
View File
@@ -383,7 +383,7 @@ namespace Step.NC
// Update queue running index after move an item
if (itemId < QueueRunningIndexes[processId] && newIndex >= QueueRunningIndexes[processId])
QueueRunningIndexes[processId] -= 1;
if (newIndex < QueueRunningIndexes[processId] && itemId > QueueRunningIndexes[processId])
if (newIndex <= QueueRunningIndexes[processId] && itemId > QueueRunningIndexes[processId])
QueueRunningIndexes[processId] += 1;
queue = new List<DTOQueueModel>();
@@ -1263,6 +1263,8 @@ namespace Step.NC
{
config = new ToolTableConfiguration();
CmsError cmsError = numericalControl.TOOLS_RConfiguration(ref config);
if (cmsError.IsError())
return cmsError;
if (NcConfig.NcVendor != NC_VENDOR.SIEMENS)
{
@@ -24,7 +24,8 @@ namespace Step.Controllers.WebApi
MaintenanceConfig = MaintenanceConfig,
ReportConfig = ReportConfig,
ToolingConfig = ToolingConfig,
UtilitiesConfig = UtilitiesConfig
UtilitiesConfig = UtilitiesConfig,
JobEditorConfig = JobEditorConfig
};
return Ok(startupConfiguration);
@@ -10,12 +10,15 @@ using Step.Model.DatabaseModels;
using Step.Model.DTOModels;
using Step.Model.DTOModels.ToolModels;
using Step.NC;
using Step.Utils;
using TeamDev.SDK.MVVM;
namespace Step.Listeners.Database
{
public static class SignalRDatabaseHandler
{
private static List<DTOQueueModel> LastPartProgramQueue = new List<DTOQueueModel>();
public static void UpdateToolsData(object newData)
{
using (NcToolManagerController controller = new NcToolManagerController())
@@ -73,5 +76,29 @@ namespace Step.Listeners.Database
}
}
}
public static void UpdateQueue(object queue)
{
List<DTOQueueModel> newQueue = queue as List<DTOQueueModel>;
if (!LastPartProgramQueue.SequenceEqual(newQueue))
{
// Copy to static object
LastPartProgramQueue = new List<DTOQueueModel>();
foreach (var queueItem in newQueue)
{
DTOQueueModel tmp = new DTOQueueModel();
SupportFunctions.CopyProperties(queueItem, tmp);
LastPartProgramQueue.Add(tmp);
}
using (QueueController controller = new QueueController())
{
controller.UpdateQueue();
}
}
}
}
}
+1
View File
@@ -83,6 +83,7 @@ namespace Step.Listeners
infos.Add(MessageServices.Current.Subscribe(SEND_QUEUE_DATA, (a, b) =>
{
SignalRListener.SendPartProgramQueue(a);
SignalRDatabaseHandler.UpdateQueue(a);
}));

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

@@ -126,6 +126,11 @@ footer {
background-size: cover;
}
button.jobeditor{
background-image: url(../icons/png/editor-BIG.png);
background-size: cover;
}
button:active{
box-shadow: 0px 0px 1px 1px #FFF;
}
+4
View File
@@ -2845,6 +2845,10 @@ footer .container button.scada {
background-image: url(../icons/png/SCADA-big.png);
background-size: cover;
}
footer .container button.jobeditor {
background-image: url(../icons/png/editor-BIG.png);
background-size: cover;
}
footer .container button:active {
box-shadow: 0px 0px 1px 1px #FFF;
}
@@ -9,6 +9,10 @@ import "./job-editor-lang-definition"
import { Container, Draggable } from "vue-smooth-dnd";
import { objectsJob } from "src/modules/base-components/cards";
import * as pf from "sprintf-js";
import { jobService } from "../services/jobService";
import * as iziToast from "izitoast";
declare var cmsClient: any;
@Component({ components: { ace, Container, Draggable, objectsJob } })
export default class JobEditorDetail extends Vue {
@@ -22,6 +26,8 @@ export default class JobEditorDetail extends Vue {
commands = new Array<commandInstance>();
interactive: boolean = false;
macros: Array<string> = [];
get sortedCommands() {
return Array.from(this.activeCommandSet).sort((a, b) => {
if (a.order > b.order) return 1;
@@ -55,9 +61,9 @@ export default class JobEditorDetail extends Vue {
commandsChanged(n, o) {
if (n && this.interactive) {
var result = "";
debugger
this.commands.forEach(c => {
result += pf.vsprintf(c.definition.command, c.value || "", c.value2 || "") + "\n";
result += pf.vsprintf(c.definition.command, [c.value || "", c.value2 || ""]) + "\n";
});
this.isoProgram = result;
@@ -108,6 +114,32 @@ export default class JobEditorDetail extends Vue {
vScrollBarAlwaysVisible: true
})
}
selectProgram(command) {
var result = JSON.parse(cmsClient.addPPToJob());
if (!result)
this.showError("internal_error");
if (result.error)
this.showError(result.error);
else
command.value = result.name;
}
async mounted() {
this.macros = await jobService.GetMacroList();
}
private showError(error){
(iziToast as any).error({
title: "Error",
message: error,
theme: "dark",
timeout: 10000,
class: "t-error",
transitionOut: "fadeOut",
})
}
}
interface commandDefinition {
@@ -18,7 +18,7 @@
<button class="btn" @click="removeCommand(p)"><i class="fa fa-trash"></i></button>
</div>
<div class="details" slot v-if="p.title=='job_item_part_program'">
<input type="text" v-model="p.value">
<input type="text" v-model="p.value"><button class="btn" @click="selectProgram(p)"><i class="fa fa-folder"></i></button>
</div>
<div class="details" slot v-if="p.title=='job_item_delay'">
<input type="number" v-model="p.value">
@@ -31,7 +31,7 @@
</div>
<div class="details" slot v-if="p.title=='job_item_macro_cms'">
<select v-model="p.value">
<option v-for="(m, index) in macros" :key="index" :value="m">{{m}}</option>
</select>
</div>
</objects-job>
+22 -21
View File
@@ -13,6 +13,7 @@ export default class JobEditor extends Vue {
editing: boolean = false;
currentJob = "";
// occorre uno switch per la scelta del linguaggio in base al CN
jobitems = siemensJobItems;
public selectedTab: string = "ParBase";
@@ -30,34 +31,34 @@ export default class JobEditor extends Vue {
const siemensJobItems = [
{ title: 'job_item_part_program', layout: "big", command: 'CALL "%s"', rx: /CALL "(.+)";?|CALL "(.+)";([.]*)"/, order: 0 },
{ title: 'job_item_macro_cms', layout: "big", command: 'PCALL /_N_CMA_DIR/%s', rx: /PCALL \/_N_CMA_DIR\/(.+);?|PCALL \/_N_CMA_DIR\/(.+);?([.]*)/, order: 0 },
{ title: 'job_item_text', layout: "big", command: "%s", rx: /(.+);?|(.+);([.]*)/, order: 100 },
{ title: 'job_item_pause', layout: "small", command: "M0;%s", rx: /^M0;?|^M0;([.]*)/, order: 0 },
{ title: 'job_item_delay', layout: "small", command: "G04 F%s;", rx: /G04 F(\d*);?|G04 F(\d*);([.]*)/, order: 0 },
{ title: 'job_item_origin', layout: "small", command: "G%s", rx: /G(.+);?|G(.+);([.]*)/, order: 0 },
{ title: 'job_item_end_program', layout: "small", command: "M30", rx: /M30;?|M30;([.]*)/, order: 0 },
{ title: 'job_item_part_program', layout: "big", command: 'CALL "%s";%s', rx: /CALL "(.+)";(.*)|CALL "(.+)";?/, order: 0 },
{ title: 'job_item_macro_cms', layout: "big", command: 'PCALL /_N_CMA_DIR/%s;%s', rx: /PCALL \/_N_CMA_DIR\/(.+);(.*)|PCALL \/_N_CMA_DIR\/(.+);?/, order: 0 },
{ title: 'job_item_text', layout: "big", command: "%s;%s", rx: /(.+);(.*)|(.+);?/, order: 100 },
{ title: 'job_item_pause', layout: "small", command: "M0;%s", rx: /^M0;(.*)|^M0;?/, order: 0 },
{ title: 'job_item_delay', layout: "small", command: "G04 F%s;%s", rx: /G04 F(\d*);(.*)|G04 F(\d*);?/, order: 0 },
{ title: 'job_item_origin', layout: "small", command: "G%s;%s", rx: /G(.+);(.*)|G(.+);?/, order: 0 },
{ title: 'job_item_end_program', layout: "small", command: "M30;%s", rx: /M30;(.*)|M30;?/, order: 0 },
];
// Da controllare comandi e regex
const osaiJobItems = [
{ title: 'job_item_part_program', layout: "big", command: 'M198 %s', rx: /M198 (.+);?[.]*/, order: 0 },
{ title: 'job_item_macro_cms', layout: "big", command: 'M98 P%s', rx: /M98 P(.+);?[.]*/, order: 0 },
{ title: 'job_item_text', layout: "big", command: "%s", rx: /(.+);?[.]*/, order: 100 },
{ title: 'job_item_pause', layout: "small", command: "M0", rx: /^M0;?[.]*/, order: 0 },
{ title: 'job_item_delay', layout: "small", command: "G04 X%s;", rx: /G04 X(.+);?[.]*/, order: 0 },
{ title: 'job_item_origin', layout: "small", command: "G54 P%s", rx: /G54 P(.+);?[.]*/, order: 0 },
{ title: 'job_item_end_program', layout: "small", command: "M30;", rx: /M30;?[.]*/, order: 0 },
{ title: 'job_item_part_program', layout: "big", command: 'M198 %s;%s', rx: /M198 (.+);(.*)|M198 (.+);?/, order: 0 },
{ title: 'job_item_macro_cms', layout: "big", command: 'M98 P%s;%s', rx: /M98 P(.+);(.*)|M98 P(.+);?/, order: 0 },
{ title: 'job_item_text', layout: "big", command: "%s;%s", rx: /(.+);(.*)|(.+);?/, order: 100 },
{ title: 'job_item_pause', layout: "small", command: "M0;%s", rx: /^M0;(.*)|^M0;?/, order: 0 },
{ title: 'job_item_delay', layout: "small", command: "G04 X%s;%s", rx: /G04 X(.+);(.*)|G04 X(.+);?/, order: 0 },
{ title: 'job_item_origin', layout: "small", command: "G54 P%s;%s", rx: /G54 P(.+);(.*)|G54 P(.+);?/, order: 0 },
{ title: 'job_item_end_program', layout: "small", command: "M30;%s", rx: /M30;(.*)|M30;?/, order: 0 },
];
// Da controllare comandi e regex
const fanucJobItems = [
{ title: 'job_item_part_program', layout: "big", command: 'CALL "%s"', rx: /M198 (.+);?[.]*/, order: 0 },
{ title: 'job_item_macro_cms', layout: "big", command: 'PCALL /_N_CMA_DIR/%s', rx: /M98 P(.+);?[.]*/, order: 0 },
{ title: 'job_item_text', layout: "big", command: "%s", rx: /(.+);?[.]*/, order: 100 },
{ title: 'job_item_pause', layout: "small", command: "M0", rx: /^M0;?[.]*/, order: 0 },
{ title: 'job_item_delay', layout: "small", command: "G04 F%s;", rx: /G04 X(.+);?[.]*/, order: 0 },
{ title: 'job_item_origin', layout: "small", command: "G%s", rx: /G54 P(.+);?[.]*/, order: 0 },
{ title: 'job_item_end_program', layout: "small", command: "M30", rx: /M30;?[.]*/, order: 0 },
{ title: 'job_item_part_program', layout: "big", command: '(CLT,%s);%s', rx: /\(CLT,(.+)\);(.*)|\(CLT,(.+)\);?/, order: 0 },
{ title: 'job_item_macro_cms', layout: "big", command: '(CLD,%s);%s', rx: /\(CLD,(.+)\);(.*)|\(CLD,(.+)\);?/, order: 0 },
{ title: 'job_item_text', layout: "big", command: "%s", rx: /(.+);(.*)|(.+);?/, order: 100 },
{ title: 'job_item_pause', layout: "small", command: "M0;%s", rx: /^M0;(.*)|^M0;?/, order: 0 },
{ title: 'job_item_delay', layout: "small", command: "(DLY,%s);%s", rx: /\(DLY,(.+)\);(.*)|\(DLY,(.+)\);?/, order: 0 },
{ title: 'job_item_origin', layout: "small", command: "(UAO,%s);%s", rx: /\(UAO,(.+)\);(.*)|\(UAO,(.+)\);?/, order: 0 },
{ title: 'job_item_end_program', layout: "small", command: "M30;%s", rx: /M30;(.*)|M30;?/, order: 0 },
];
+3
View File
@@ -17,6 +17,9 @@
<button @click="openProgram('/test/header')" :title="'footer_tooltip_scada' | localize('Scada')"
:disabled="!isAreaEnabled('scada')" v-if="isAreaVisible('scada')" class="oval scada" :class="{ big:isInPath('/test/header') && !state.isMainViewLiftedUp}"></button>
<button @click="openProgram('/job-editor')" :title="'footer_tooltip_job_editor' | localize('Job-Editor')"
:disabled="!isAreaEnabled('jobeditor')" v-if="isAreaVisible('jobeditor')" class="oval jobeditor" :class="{ big:isInPath('job-editor') && !state.isMainViewLiftedUp}"></button>
<div v-if="isAreaVisible('utilities') && getUtilities().length > 0" class="divider"><i class="fa fa-circle"></i></div>
<button @click="startUtility(software.id)" :title="software.longName" v-for="software in getUtilities()" :key="software.id"
:disabled="!isAreaEnabled('utilities')" v-if="isAreaVisible('utilities')" class="oval externUtility">
+11
View File
@@ -0,0 +1,11 @@
import { baseRestService } from "src/_base/baseRestService";
export class JobService extends baseRestService {
async GetMacroList(): Promise<Array<string>> {
return await this.Get<string[]>("api/file_manager/macros");
}
}
export const jobService = new JobService();