Программная реализация надстройки над системой управления проектами "YouTrack"

Изучение возможностей системы YouTrack. Аналитический обзор ее аналогов и их функциональности. Анализ требований к системе управления проектами и надстройке. Визуализация данных. Проектирование интерфейса надстройки. Определение технологий реализации.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 13.09.2017
Размер файла 2,3 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

line (см. рис. 3.1);

spline;

area;

areaspline;

column;

bar;

pie;

scatter;

другие.

Рисунок 3.1. График типа line

Они могут быть комбинированы между друг другом при выводе конечному пользователю, и обладают возможностью скрытия любого элемента в режиме реального времени непосредственно пользователем для удобства разборки информации.

3.2 Результат разработки

При первоначальном входе в систему пользователю высвечивается страница с формой авторизации (рис. 3.2).

Рисунок 3.2. Окно авторизации приложения

Пользователь вводит свои данные и нажимает кнопку Log In. Происходит запрос к API системы YouTrack и при её успешном выполнении сохраняется cookie аутентификации. Код метода получения и сохранения cookie:

public YouTrackAuthCookie GetAuthenticationCookieFromYouTrack(string login, string password)

var request = new RestRequest("/rest/user/login", Method.POST);

request.AddParameter("login", login);

request.AddParameter("password", password);

var response = this._client.Execute(request);

this.EnsureOkResponseStatus(response, "Cannot authenticate user on YouTrack instance '{0}', login '{1}', status code {2}",

this._client.BaseUrl,

login,

response.StatusCode);

var authCookie = response.Cookies

.FirstOrDefault(cookie => cookie.Name == YOUTRACK_AUTH_COOKIE);

if (authCookie == null)

{

var message = string.Format("Cannot found YouTrack authentication cookie ({0}) in response to {1} for user {2}",

YOUTRACK_AUTH_COOKIE, this._client.BaseUrl,

login);

throw new ApplicationException(message);

}

var authCookieInfo = new YouTrackAuthCookie

{

Name = authCookie.Name,

Value = authCookie.Value,

Domain = authCookie.Domain,

Path = authCookie.Path,

HttpOnly = authCookie.HttpOnly,

Secure = authCookie.Secure,

Expires = authCookie.Expires

return authCookieInfo;

}

При успешном входе пользователь перенаправляется на главную страницу приложения (см. рис. 3.3). Если возникает ошибка авторизации, пользователю высвечивается уведомление об ошибке. Главная страница приложения содержит список поисковых запросов пользователя из YouTrack в боковой панели и список задач выбранного запроса.

В верхней панели добавлены кнопки создания новой задачи, переключения между списками задач и отчётов, выхода из приложения и поле поиска задачи, с префиксом проекта (сокращённое название проекта из YouTrack).

Рисунок 3.3. Интерфейс приложения, вкладка Issues (задачи)

Для перехода к списку отчётов используется кнопка Reports (рис. 3.4). При её нажатии список задач меняется на список отчётов. После выбора любого отчёта из списка появляются его превью. Для перехода к отчёту используется кнопка Go to report.

Рисунок 3.4. Превью отчёта Delivery

Чтобы создать новую задачу необходимо нажать кнопку Submit New Request, после чего появляется форма как на рисунке 3.5. Пользователь заполняет необходимые поля и нажимает кнопку Submit New Request. Происходит запрос на создание новой задачи к API YouTrack:

static createIssue(title, description, callback, context) {

Youtrack._req("CreateIssue",

"/rest/issue",

Youtrack._paramsToUrl({ y_project: encodeURIComponent(Settings.ProjectId), y_summary: encodeURIComponent(title), y_description: encodeURIComponent(description) }),

callback, context);

}

Рисунок 3.5. Создание новой задачи

Ест возможность выбрать задачу из списка и просмотреть её детали (см. рис. 3.6). Задачу можно отредактировать, нажав кнопку редактирования в правом верхнем углу деталей задачи. Запрос обновления задачи к API YouTrack:

static updateIssue(data: { issueId: string; title: string; description: string; }, callback, context) {

Youtrack._req("POST", "/rest/issue/" + data.issueId,

Youtrack._paramsToUrl({ y_summary: encodeURIComponent(data.title), y_description: encodeURIComponent(data.description) }),

callback, context, );

}

Боковая панель группирует запросы по сохранённым поисковым запросам пользователя из YouTrack:

static getSavedSearches(callback, context) {

const login = Youtrack._getCurrentLogin();

Youtrack._req("GET",

"/rest/user/" + login + "/filter", null,

callback, context);

}

Рисунок 3.6. Просмотр деталей задачи

Данные о задачах могут быть отредактированы определенной группой пользователей, другие пользователи имеют доступ только для чтения.

Заключение

В результате проведённой работы был сделан обзор наиболее популярных программ управления задач программных проектов, среди которых используемый в работе YouTrack и популярная на сегодняшний день JIRA. Проведено сравнение этих систем по выделенным критериям.

С участием заказчика определены требования к функциям, интерфейсу и средствам создания надстройки. С их учётом разработан проект надстройки, который включает в себя описание работы с данными о проекте, способы их извлечения из системы YouTrack, устройство и взаимодействие компонентов системы, обоснованы средства реализации системы и инструменты, применённые в ходе работ.

Также представлена начальная версия интерфейса системы. Архитектура системы спроектирована с учётом возможных расширений в будущем. Разработана первая версия надстройки с необходимой функциональностью, выбраны технологии реализации и проект согласован с заказчиком. Вычисления из файла Excel перенесены в систему, созданы необходимые отчёты в виде графиков. Функционал реализован с использованием заявленных заказчиком технологий. Планируется поддержка проекта и обновление, возможно его расширение. В систему могут быть добавлены новые отчёты, содержащие информацию не только о трудозатратах, но и о самом проекте.

На данный момент система внедрена на предприятии и используется по назначению более чем двадцатью людьми.

Библиографический список

1. A brief look into using the scrum framework for software development. [Электронный ресурс] URL: https://www.atlassian.com/agile/scrum (дата обращения: 28.04.2017).

2. Agile Boards. [Электронный ресурс] URL: https://www.jetbrains.com/youtrack/features/agile_project_management.html (дата обращения: 28.04.2017).

3. Definition of visualization. [Электронный ресурс] URL: http://whatis.techtarget.com/definition/visualization (дата обращения: 28.04.2017).

4. Highcharts Demos. [Электронный ресурс] URL: http://www.highcharts.com/demo (дата обращения: 28.04.2017).

5. Scrum and Bugzilla. [Электронный ресурс] URL: https://blog.mozilla.org/webdev/2012/03/27/scrum-and-bugzilla/ (дата обращения: 28.04.2017).

6. The 20 Most Popular Project Management Software Products [Infographic]. [Электронный ресурс] URL: http://www.capterra.com/project-management-software/#infographic (дата обращения: 28.04.2017).

7. YouTrack Standalone 2017.2 Help. Custom Field Types. [Электронный ресурс] URL: https://www.jetbrains.com/help/youtrack/standalone/2017.2/Supported-Custom-Field-Types.html (дата обращения: 28.04.2017).

8. YouTrack Standalone 2017.2 Help. Custom Fields. [Электронный ресурс] URL: https://www.jetbrains.com/help/youtrack/standalone/2017.2/Custom-Fields.html (дата обращения: 28.04.2017).

Приложения

Приложение A. Диаграммы описания системы

Рисунок A.1. Использование надстройки. Работа в надстройке с задачами из YouTrack

Рисунок А.2. Диаграмма классов надстройки

Приложение B. Код приложения

Запросы к Youtrack (youtrack.ts):

import * as $ from "jquery";

import { JsonCache } from "../helpers/jsonCache";

import { hashHistory } from 'react-router';

import { spaPatternUrls } from "../helpers/urlHelper";

import { Settings } from "../settings";

export class Youtrack {

private static _server: string;

constructor() {

}

private static _req(method, api_path, parametrs: string, callback, context, body?) {

const c = JsonCache.getItem<string>("authCookie");

let url = "/Proxy/" + method + Youtrack._paramsToUrl({ c: encodeURIComponent(c), p: encodeURIComponent(api_path) }) + (parametrs ? parametrs.replace("?", "&") : "");

var req = new XMLHttpRequest();

context = context || this;

req.onreadystatechange = function () {

if (req.readyState == 4) {

if (req.status == 200) {

let res = JSON.parse(req.responseText || "{}");

if (res && res.value && (res.value == "You are not logged in." || res.value == "User not found or you have no permission to read user.")) {

hashHistory.push(spaPatternUrls.auth());

}

else {

callback.call(context, res);

}

}

else {

callback.call(context, JSON.parse(req.responseText || "{}"));

}

}

};

method = method == "GET" || method == "POST" ? method : "GET";

req.open(method, url, true);

req.timeout = 40000;

if (req.setRequestHeader) {

req.setRequestHeader("Accept", "application/json");

}

req.send(body || "");

}

private static _getCurrentLogin() {

return JsonCache.getItem<string>("userLogin");

}

private static _paramsToUrl(dict) {

dict = dict ? dict : [];

const result = [];

for (let prop in dict) {

result.push("{0}={1}".replace("{0}", prop)

.replace("{1}", dict[prop]));

}

return result.length == 0 ? "" : `?${result.join("&")}`;

}

static search(query, callback, offset, context, limit) {

limit = limit || 1000;

Youtrack._req("GET",

"/rest/issue/search",

Youtrack._paramsToUrl({ y_filter: encodeURIComponent(query), y_after: encodeURIComponent(offset), y_max: encodeURIComponent(limit) }),

callback, context);

}

static getCurrentUser(callback, context) {

return this.getUserInfo("current", callback, context);

}

static getSavedSearches(callback, context) {

const login = Youtrack._getCurrentLogin();

Youtrack._req("GET",

"/rest/user/" + login + "/filter", null,

callback, context);

}

static getUserInfo(login, callback, context) {

login = login || Youtrack._getCurrentLogin() || "current";

Youtrack._req("GET",

"/rest/user/" + login, null,

callback, context);

}

static getIssues(query, callback, context) {

Youtrack._req("GET", "/rest/issue", Youtrack._paramsToUrl({ y_filter: encodeURIComponent(query) }),

callback, context);

}

static getIssue(id, callback, context) {

Youtrack._req("GET",

"/rest/issue/" + id, Youtrack._paramsToUrl({ y_wikifyDescription: true }),

callback, context);

}

static getIssuesCount(query, callback, context) {

Youtrack._req("GET", "rest/issue/count", Youtrack._paramsToUrl({ y_filter: encodeURIComponent(query) }),

callback, context);

}

static downloadAttach(link: string, callback, context) {

link = link.replace(Settings.YoutrackServer + "/_persistent/", "");

let y_file = link.split("?")[1].split("&")[0].split("=")[1];

let y_c = link.split("?")[1].split("&")[1].split("=")[1];

link = link.split("?")[0];

window.open("Attach/Get" + Youtrack._paramsToUrl({

c: encodeURIComponent(JsonCache.getItem<string>("authCookie")),

f: encodeURIComponent(link.split("?")[0]),

y_file: encodeURIComponent(y_file),

y_c: encodeURIComponent(y_c)

}), "_black");

}

static updateIssue(data: { issueId: string; title: string; description: string; }, callback, context) {

Youtrack._req("POST", "/rest/issue/" + data.issueId,

Youtrack._paramsToUrl({ y_summary: encodeURIComponent(data.title), y_description: encodeURIComponent(data.description) }),

callback, context, );

}

static executeCommand(issueId, dict, callback, context) {

let command = "";

for (let item in dict) {

command += item + " " + dict[item] + " ";

}

Youtrack._req("POST", "/rest/issue/" + issueId + "/execute", null,

callback, context, "command=" + encodeURIComponent(command));

}

static createIssue(title, description, callback, context) {

Youtrack._req("CreateIssue",

"/rest/issue",

Youtrack._paramsToUrl({ y_project: encodeURIComponent(Settings.ProjectId), y_summary: encodeURIComponent(title), y_description: encodeURIComponent(description) }),

callback, context);

}

static getIssueChanges(id, callback, context) {

Youtrack._req("GET",

"/rest/issue/" + id + "/changes", null,

callback, context);

}

static getIssueLinks(id, callback, context) {

Youtrack._req("GET",

"/rest/issue/" + id + "/link", null,

callback, context);

}

}

Кэширование данных (jsonCache.ts):

interface CacheItem<TEntity> {

value: TEntity;

userKey: number;

}

export class JsonCache {

private static _getKey(key?) {

if (!key)

key = "JsonCache";

return `JsonCache.${key}`;

}

private static _getStorage() {

return window.localStorage;

}

static removeItem(key) {

const sessionKey = this._getKey(key);

const storage = this._getStorage();

const result = storage[sessionKey] ? true : false;

storage.removeItem(sessionKey);

return result;

}

private static _getUserKey() {

return -1;

}

static getItem<TEntity>(key) {

const sessionKey = this._getKey(key);

const storage = this._getStorage();

const storageItemValue = storage.getItem(sessionKey);

const storageItemValueObject: CacheItem<TEntity> = storageItemValue && JSON.parse(storageItemValue);

let result = storageItemValueObject && storageItemValueObject.value;

if (storageItemValueObject) {

if (storageItemValueObject.userKey !== this._getUserKey()) {

this.removeItem(key);

result = null;

}

}

return result;

}

static setItem<TEntity>(key: string, value: TEntity) {

const sessionKey = this._getKey(key);

const storage = this._getStorage();

const result: CacheItem<TEntity> = { value: value, userKey: this._getUserKey() };

storage.setItem(sessionKey, JSON.stringify(result));

}

}

Работа с задачами (IssueHelper.ts):

import { Issue } from "../base";

import { Settings } from "../settings";

export class issueHelper {

static _parseDateTime(dateTime) {

let createdDate = new Date(parseInt(dateTime)).toUTCString();

return createdDate = createdDate.substring(createdDate.indexOf(",") + 2, createdDate.lastIndexOf(":"));

}

static _getDefaultValueIfEmpty(name: string, nullIfEmpty?: boolean) {

if (nullIfEmpty) return "";

return "No " + name.toLowerCase();

}

static getIssueFieldValueByName(issue: Issue, name: string, nullIfEmpty?: boolean): any {

let result;

if (!issue) return this._getDefaultValueIfEmpty(name, nullIfEmpty);

if (name == RequiredFields.id) {

return issue && issue.id || this._getDefaultValueIfEmpty(name);

}

var field = issue.field.filter(function (item) {

return item.name == name;

})[0];

if (!field) return this._getDefaultValueIfEmpty(name, nullIfEmpty);

if (name == RequiredFields.updated || name == RequiredFields.created) {

result = this._parseDateTime(field.value)

}

if (name == "Assignee") {

result = JSON.parse(JSON.stringify(field.value[0])).fullName;

}

if (name == "Estimation" || name == "Estimation DB" || name == "Estimation Web" || name == "Estimation Testing") {

result = JSON.parse(JSON.stringify(field)).valueId[0];

}

return result || field && field.value || "";

}

static getValuesForRequiredFields(issue: Issue): {

id: string;

summary: string;

description: string;

created: string;

updated: string;

reporterFullName: string;

updaterFullName: string;

attachments: string;

return {

id: this.getIssueFieldValueByName(issue, RequiredFields.id, true),

summary: this.getIssueFieldValueByName(issue, RequiredFields.summary, true),

description: this.getIssueFieldValueByName(issue, RequiredFields.description, true),

created: this.getIssueFieldValueByName(issue, RequiredFields.created, true),

updated: this.getIssueFieldValueByName(issue, RequiredFields.updated, true),

reporterFullName: this.getIssueFieldValueByName(issue, RequiredFields.reporterFullName),

updaterFullName: this.getIssueFieldValueByName(issue, RequiredFields.updaterFullName),

attachments: this.getIssueFieldValueByName(issue, RequiredFields.attachments)

}

}

static getSettingsField(fieldName: string) {

return Settings.IssueFields.filter((item) => { return item.youtrackId == fieldName })[0];

}

static isNeedToShowField(fieldName: string): boolean {

let field = this.getSettingsField(fieldName);

return !!(field && field.show);

}

static isCanBeEditField(fieldName: string): boolean {

let field = this.getSettingsField(fieldName);

return !!(field && field.edit);

}

static getFileldDisplayName(fieldName: string): string {

let field = this.getSettingsField(fieldName);

return (field && field.displayName) || fieldName;

}

static getFileldWorkflow(fieldName: string): string {

let field = this.getSettingsField(fieldName);

return (field && field.workflow) || null;

}

static getFileldDafaultValue(fieldName: string): string {

let field = this.getSettingsField(fieldName);

return (field && field.default) || this._getDefaultValueIfEmpty(fieldName);

}

}

export var RequiredFields = {

id: "id",

summary: "summary",

description: "description",

created: "created",

updated: "updated",

updaterFullName: "updaterFullName",

reporterFullName: "reporterFullName",

attachments: "attachments"

};

Извлечение значений полей (FieldsHelper.cs):

using System;

using System.Collections.Generic;

using System.Linq;

namespace Helpers

{

using System.Net;

using RestSharp;

public class FieldsHelper : BaseRestSharpHelper

{

private readonly RestClient _client;

private readonly string _youtrackUrl;

private string _authCookieValue;

private JsonConfigHelper _config;

private const string ENUM_TYPE = "enum[1]";

private const string USER_TYPE = "user[1]";

private const string VERSION_BUNDLE = "version[1]";

private const string STATE_BUNDLE = "state[1]";

private readonly string[] _supportedTypes = new string[] { ENUM_TYPE ,

USER_TYPE,

VERSION_BUNDLE,

STATE_BUNDLE };

public FieldsHelper(string youtrackUrl, JsonConfigHelper configHelper)

{

this._client = new RestClient(youtrackUrl);

_youtrackUrl = youtrackUrl;

this._client.CookieContainer = new CookieContainer();

this._config = configHelper;

}

public List<string> GetFieldValues(string projectId, string fieldName)

{

string fieldType;

string bundleName = GetEnumBundleName(projectId, fieldName, out fieldType);

List<string> filedValues = new List<string>();

if (fieldType == ENUM_TYPE)

{

filedValues = GetBundleValues(bundleName);

}

else if (fieldType == USER_TYPE)

{

filedValues = fieldName == "Assignee" ? GetAssignees(projectId) : GetUserBundleValues(bundleName);

}

else if (fieldType == VERSION_BUNDLE)

{

filedValues = fieldName == "Sprints"? null : GetVersionBundleValues(bundleName);

}

else if (fieldType == STATE_BUNDLE)

{

filedValues = GetStateBundleValues(bundleName);

}

return filedValues;

}

private List<string> GetStateBundleValues(string stateBundleName)

{

List<string> values = new List<string>();

var request = new RestRequest("/rest/admin/customfield/stateBundle/{bundleName}", Method.GET);

request.AddUrlSegment("bundleName", stateBundleName);

string authCookie = GetAdminAuthCookieValue();

AuthHelper.AddAuthCookie(request, authCookie);

var response = this._client.Execute<dynamic>(request);

this.EnsureOkResponseStatus(response, "Cannot get values for state bundle '{0}', status code {1}",

stateBundleName,

response.StatusCode);

foreach (dynamic v in response.Data["state"])

{

values.Add(v["value"]);

}

return values;

}

public string GetAdminAuthCookieValue()

{

if (!string.IsNullOrEmpty(this._authCookieValue))

{

return this._authCookieValue;

}

AuthHelper authHelper = new AuthHelper(_youtrackUrl);

var authCookie = authHelper.GetAuthenticationCookieFromYouTrack(

_config.SuperUserLogin,

_config.SuperUserPassword);

this._authCookieValue = authCookie.Value;

return this._authCookieValue;

}

private List<string> GetSprints(string versionBundleName)

{

List<string> values = new List<string>();

var request = new RestRequest("/rest/admin/customfield/versionBundle/{bundleName}", Method.GET);

request.AddUrlSegment("bundleName", versionBundleName);

string authCookie = GetAdminAuthCookieValue();

AuthHelper.AddAuthCookie(request, authCookie);

var response = this._client.Execute<dynamic>(request);

this.EnsureOkResponseStatus(response, "Cannot get values for version bundle '{0}', status code {1}",

versionBundleName,

response.StatusCode);

foreach (dynamic v in response.Data["version"])

{

values.Add(v["value"]);

}

return values;

}

private List<string> GetVersionBundleValues(string versionBundleName)

{

List<string> values = new List<string>();

var request = new RestRequest("/rest/admin/customfield/versionBundle/{bundleName}", Method.GET);

request.AddUrlSegment("bundleName", versionBundleName);

string authCookie = GetAdminAuthCookieValue();

AuthHelper.AddAuthCookie(request, authCookie);

var response = this._client.Execute<dynamic>(request);

this.EnsureOkResponseStatus(response, "Cannot get values for version bundle '{0}', status code {1}",

versionBundleName,

response.StatusCode);

foreach (dynamic v in response.Data["version"])

{

values.Add(v["value"]);

}

return values;

}

private List<string> GetAssignees(string projectName)

{

List<string> values = new List<string>();

var request = new RestRequest("/rest/admin/project/{projectName}/assignee", Method.GET);

request.AddUrlSegment("projectName", projectName);

string authCookie = GetAdminAuthCookieValue();

AuthHelper.AddAuthCookie(request, authCookie);

var response = this._client.Execute<dynamic>(request);

this.EnsureOkResponseStatus(response, "Cannot get values for user bundle '{0}', status code {1}",

projectName,

response.StatusCode);

foreach (dynamic v in response.Data["assignees"])

{

values.Add(v["login"]);

}

return values;

}

private List<string> GetUserBundleValues(string userBundleName)

{

List<string> values = new List<string>();

var request = new RestRequest("/rest/admin/customfield/userBundle/{bundleName}", Method.GET);

request.AddUrlSegment("bundleName", userBundleName);

string authCookie = GetAdminAuthCookieValue();

AuthHelper.AddAuthCookie(request, authCookie);

var response = this._client.Execute<dynamic>(request);

this.EnsureOkResponseStatus(response, "Cannot get values for user bundle '{0}', status code {1}",

userBundleName,

response.StatusCode);

foreach (dynamic v in response.Data["user"])

{

values.Add(v["login"]);

}

return values;

}

private List<string> GetBundleValues(string bundleName)

{

List<string> values = new List<string>();

var request = new RestRequest("/rest/admin/customfield/bundle/{bundleName}", Method.GET);

request.AddUrlSegment("bundleName", bundleName);

string authCookie = GetAdminAuthCookieValue();

AuthHelper.AddAuthCookie(request, authCookie);

var response = this._client.Execute<dynamic>(request);

this.EnsureOkResponseStatus(response, "Cannot get values for bundle '{0}', status code {1}",

bundleName,

response.StatusCode);

foreach (dynamic v in response.Data["value"])

{

values.Add(v["value"]);

}

return values;

}

private string GetEnumBundleName(string projectId, string fieldName, out string fieldType)

{

var request = new RestRequest("/rest/admin/project/{projectId}/customfield/{customFieldName}", Method.GET);

request.AddUrlSegment("projectId", projectId);

request.AddUrlSegment("customFieldName", fieldName);

string authCookie = GetAdminAuthCookieValue();

AuthHelper.AddAuthCookie(request, authCookie);

var response = this._client.Execute<dynamic>(request);

this.EnsureOkResponseStatus(response, "Cannot get values for field '{0}', status code {1}",

fieldName,

response.StatusCode);

fieldType = response.Data["type"];

if (!_supportedTypes.Contains(fieldType))

{

string message = string.Format("Only fields with type {0} can be returned, but {1} was returned",

string.Join(", ", _supportedTypes),

response.Data["type"]);

throw new InvalidOperationException(message);

}

return response.Data["param"][0]["value"];

}

}

}

Размещено на Allbest.ru


Подобные документы

  • Сущность управления проектами, этапы его реализации и необходимые для этого знания, порядок составления и назначение Плана управления проектом. Концепция тройственной ограниченности. Использование программы MS Oficce Project в управлении проектами.

    реферат [24,9 K], добавлен 16.11.2009

  • Обзор рынка Информационных технологий. Современные автоматизированные системы управления проектами и их классификация. Open Plan (Welcom Software) - система, предлагающая решение по управлению проектами масштаба корпорации. Основные модули Open Plan.

    курсовая работа [630,9 K], добавлен 24.02.2010

  • Методы и алгоритмы построения инструментариев для разработки систем управления проектами посредством Web интерфейса. Составление модели обработки информации "как должно быть". Годовой экономический эффект и прочие показатели экономической эффективности.

    дипломная работа [1,1 M], добавлен 28.09.2015

  • Аналитический обзор целевой аудитории сайта. Анализ требований к сайту. Проектирование функций и архитектуры системы при помощи CMS WordPress. Разработка интерфейса и структуры данных. Реализация интерфейса (экранные формы и руководство по эксплуатации).

    дипломная работа [2,0 M], добавлен 19.01.2017

  • Разработка системы управления проектами для компании ЗАО "Диакон". Экономические параметры разработки и внедрения электронной информационной системы. Технология разработки программного обеспечения. Выбор типа графического интерфейса, его составляющие.

    дипломная работа [1,4 M], добавлен 10.06.2014

  • Характеристика основных методик управления проектами, их отличительные особенности, критерии и обоснование выбора, анализ информационных технологий. Анализ возможностей, предоставляемых программой Microsoft Project, ее экономическая эффективность.

    дипломная работа [4,6 M], добавлен 28.06.2010

  • Внедрение системы управления проектами Microsoft Project 2003 в Московский институт экономики, менеджмента и права для автоматизации учета выполнения дипломных проектов. Сравнительная характеристика систем управления проектами в России и за рубежом.

    дипломная работа [1,4 M], добавлен 25.10.2013

  • Формирование требований к системе. Описание входной и выходной информации. Концептуальное и логическое проектирование структуры и пользовательского интерфейса. Выбор средств реализации подсистемы. Реализация функциональности программного средства.

    курсовая работа [1,3 M], добавлен 28.08.2012

  • Проектирование корпоративных информационных систем. Автоматизация процесса выполнения лабораторных работ по дисциплине "Управление программными проектами". Построение модели ИС учебного процесса: архитектура, формализация пользовательских требований.

    дипломная работа [1,1 M], добавлен 20.08.2017

  • Проектирование базы данных "Менеджер". Выбор системы проектирования и реализации. Задачи, выполняемые приложением. Технические требования, предъявляемые к базе данных. Ее информационно-логическая структура. Основные принципы работы с приложением.

    дипломная работа [2,5 M], добавлен 20.05.2013

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.